From 24480ea0c188ca03522eacd011002cfa8cefb79e Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Mon, 29 Sep 2014 19:12:37 -0400 Subject: [PATCH 001/112] First attempt at caching tangents meshes --- src/graphics/mesh_tools.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/graphics/mesh_tools.cpp b/src/graphics/mesh_tools.cpp index a0c05242e..a5fc3db63 100644 --- a/src/graphics/mesh_tools.cpp +++ b/src/graphics/mesh_tools.cpp @@ -22,6 +22,8 @@ #include #include "utils/log.hpp" #include "graphics/irr_driver.hpp" +#include "modes/world.hpp" +#include "tracks/track.hpp" void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) { @@ -325,7 +327,8 @@ bool MeshTools::isNormalMap(scene::IMeshBuffer* mb) { if (!irr_driver->isGLSL()) return false; - return (mb->getMaterial().MaterialType == irr_driver->getShader(ES_NORMAL_MAP)); + return (mb->getMaterial().MaterialType == irr_driver->getShader(ES_NORMAL_MAP) && + mb->getVertexType() != video::EVT_TANGENTS); } // Copied from irrlicht @@ -435,8 +438,29 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh, bool(*predic if (calculateTangents) recalculateTangents(clone, recalculateNormals, smooth, angleWeighted); + int mbcount = clone->getMeshBufferCount(); + for (int i = 0; i < mbcount; i++) + { + scene::IMeshBuffer* mb = clone->getMeshBuffer(i); + + for (int t = 0; t < video::MATERIAL_MAX_TEXTURES; t++) + { + video::ITexture* texture = mb->getMaterial().TextureLayer[t].Texture; + if (texture != NULL) + texture->grab(); + } + } + + scene::IMeshCache* meshCache = irr_driver->getSceneManager()->getMeshCache(); + io::SNamedPath path = meshCache->getMeshName(mesh); irr_driver->removeMeshFromCache(mesh); + scene::SAnimatedMesh* amesh = new scene::SAnimatedMesh(clone); + meshCache->addMesh(path, amesh); + amesh->drop(); + + World::getWorld()->getTrack()->addCachedMesh(amesh); + return clone; } From 3fc0d3be0930f3e11f7845f352cf38c65fecb43a Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Fri, 3 Oct 2014 16:25:19 +0200 Subject: [PATCH 002/112] Second try of my previous pull request, which was partially reverted due to caused crashes and memory leaks --- src/guiengine/widgets/icon_button_widget.cpp | 45 ++++++++++++++++++++ src/guiengine/widgets/icon_button_widget.hpp | 4 +- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index 4255895a0..f384bd83e 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -42,6 +42,7 @@ IconButtonWidget::IconButtonWidget(ScaleMode scale_mode, const bool tab_stop, m_label = NULL; m_font = NULL; m_texture = NULL; + m_deactivated_texture = NULL; m_highlight_texture = NULL; m_custom_aspect_ratio = 1.0f; @@ -270,6 +271,49 @@ void IconButtonWidget::unfocused(const int playerID, Widget* new_focus) m_label->setVisible(false); } } +// ----------------------------------------------------------------------------- +const video::ITexture* IconButtonWidget::getTexture() +{ + if (Widget::isActivated()) + { + return m_texture; + } + else + { + if (m_deactivated_texture == NULL) + m_deactivated_texture = getDeactivatedTexture(m_texture); + return m_deactivated_texture; + } +} + +// ----------------------------------------------------------------------------- +video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* texture) +{ + SColor c; + u32 g; + + video::IVideoDriver* driver = irr_driver->getVideoDriver(); + video::IImage* image = driver->createImageFromData (texture->getColorFormat(), + texture->getSize(), texture->lock(), false); + texture->unlock(); + + //Turn the image into grayscale + for (u32 x = 0; x < image->getDimension().Width; x++) + { + for (u32 y = 0; y < image->getDimension().Height; y++) + { + c = image->getPixel(x, y); + g = ((c.getRed() + c.getGreen() + c.getBlue()) / 3); + c.set(std::max (0, (int)c.getAlpha() - 120), g, g, g); + image->setPixel(x, y, c); + } + } + + texture = driver->addTexture(texture->getName().getPath() + "_disabled", image); + image->drop(); + + return texture; +} // ----------------------------------------------------------------------------- void IconButtonWidget::setTexture(video::ITexture* texture) @@ -277,6 +321,7 @@ void IconButtonWidget::setTexture(video::ITexture* texture) m_texture = texture; if (texture == NULL) { + m_deactivated_texture = NULL; m_texture_w = 0; m_texture_h = 0; } diff --git a/src/guiengine/widgets/icon_button_widget.hpp b/src/guiengine/widgets/icon_button_widget.hpp index e4126ab91..9c8221a87 100644 --- a/src/guiengine/widgets/icon_button_widget.hpp +++ b/src/guiengine/widgets/icon_button_widget.hpp @@ -43,9 +43,11 @@ namespace GUIEngine { private: irr::video::ITexture* m_texture; + irr::video::ITexture* m_deactivated_texture; irr::video::ITexture* m_highlight_texture; int m_texture_w, m_texture_h; + video::ITexture* getDeactivatedTexture(video::ITexture* texture); void setLabelFont(); public: @@ -158,7 +160,7 @@ namespace GUIEngine virtual void unfocused(const int playerID, Widget* new_focus); // -------------------------------------------------------------------- /** Returns the texture of this button. */ - const video::ITexture* getTexture() const { return m_texture; } + const video::ITexture* getTexture(); }; } From f520e38cd5df1d8ad71e6128e61db258622f6f3d Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Fri, 3 Oct 2014 22:11:21 +0200 Subject: [PATCH 003/112] This will (hopefully) solve the memory leaks in dynamic ribbons and image button widgets --- src/guiengine/widgets/dynamic_ribbon_widget.cpp | 4 ++-- src/guiengine/widgets/icon_button_widget.cpp | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index 34fdf011a..f3b013873 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -23,7 +23,6 @@ #include "utils/vs.hpp" #include -#include #include #include @@ -45,6 +44,7 @@ DynamicRibbonWidget::DynamicRibbonWidget(const bool combo, const bool multi_row) m_check_inside_me = true; m_supports_multiplayer = true; m_scrolling_enabled = true; + m_animated_contents = false; // by default, set all players to have no selection in this ribbon for (unsigned int n=0; ndrop(); + delete m_font; if (m_animated_contents) { GUIEngine::needsUpdate.remove(this); diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index f384bd83e..393858ed9 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -293,8 +293,8 @@ video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* textur u32 g; video::IVideoDriver* driver = irr_driver->getVideoDriver(); - video::IImage* image = driver->createImageFromData (texture->getColorFormat(), - texture->getSize(), texture->lock(), false); + std::auto_ptr image (driver->createImageFromData (texture->getColorFormat(), + texture->getSize(), texture->lock(), false)); texture->unlock(); //Turn the image into grayscale @@ -309,10 +309,7 @@ video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* textur } } - texture = driver->addTexture(texture->getName().getPath() + "_disabled", image); - image->drop(); - - return texture; + return driver->addTexture(texture->getName().getPath() + "_disabled", image.get ()); } // ----------------------------------------------------------------------------- From ee49604856fcc601a547f36d579e554443ec6895 Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Sat, 4 Oct 2014 12:15:11 +0200 Subject: [PATCH 004/112] Issue #1588 Fixed crashes in track info screen --- src/states_screens/track_info_screen.cpp | 48 +++++++++++------------- src/states_screens/track_info_screen.hpp | 9 +++-- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/states_screens/track_info_screen.cpp b/src/states_screens/track_info_screen.cpp index fd089f376..b54c100ba 100644 --- a/src/states_screens/track_info_screen.cpp +++ b/src/states_screens/track_info_screen.cpp @@ -70,6 +70,16 @@ void TrackInfoScreen::loadedFromFile() m_ai_kart_spinner = getWidget("ai-spinner"); m_reverse = getWidget("reverse"); m_reverse->setState(false); + + m_highscore_label = getWidget("highscores"); + + m_kart_icons[0] = getWidget("iconscore1"); + m_kart_icons[1] = getWidget("iconscore2"); + m_kart_icons[2] = getWidget("iconscore3"); + + m_highscore_entries[0] = getWidget("highscore1"); + m_highscore_entries[1] = getWidget("highscore2"); + m_highscore_entries[2] = getWidget("highscore3"); } // loadedFromFile // ---------------------------------------------------------------------------- @@ -181,30 +191,16 @@ void TrackInfoScreen::init() m_reverse->setState(false); // ---- High Scores - if (has_highscores) - { - m_kart_icons[0] = getWidget("iconscore1"); - m_kart_icons[1] = getWidget("iconscore2"); - m_kart_icons[2] = getWidget("iconscore3"); + m_highscore_label->setVisible(has_highscores); - m_highscore_entries[0] = getWidget("highscore1"); - m_highscore_entries[1] = getWidget("highscore2"); - m_highscore_entries[2] = getWidget("highscore3"); + m_kart_icons[0]->setVisible(has_highscores); + m_kart_icons[1]->setVisible(has_highscores); + m_kart_icons[2]->setVisible(has_highscores); - updateHighScores(); - } - else - { - getWidget("iconscore1")->setVisible(false); - getWidget("iconscore2")->setVisible(false); - getWidget("iconscore3")->setVisible(false); + m_highscore_entries[0]->setVisible(has_highscores); + m_highscore_entries[1]->setVisible(has_highscores); + m_highscore_entries[2]->setVisible(has_highscores); - getWidget("highscores")->setVisible(false); - getWidget("highscore1")->setVisible(false); - getWidget("highscore2")->setVisible(false); - getWidget("highscore3")->setVisible(false); - } - RibbonWidget* bt_start = getWidget("buttons"); bt_start->setFocusForPlayer(PLAYER_ID_GAME_MASTER); @@ -220,6 +216,9 @@ TrackInfoScreen::~TrackInfoScreen() void TrackInfoScreen::updateHighScores() { + if (!race_manager->modeHasHighscores()) + return; + std::string game_mode_ident = RaceManager::getIdentOf( race_manager->getMinorMode() ); const Highscores::HighscoreType type = "HST_" + game_mode_ident; @@ -281,7 +280,7 @@ void TrackInfoScreen::onEnterPressedInternal() // Create a copy of member variables we still need, since they will // not be accessible after dismiss: - const int num_laps = race_manager->modeHasLaps() ? m_lap_spinner->getValue() + const int num_laps = race_manager->modeHasLaps() ? m_lap_spinner->getValue() : -1; const bool reverse_track = m_reverse == NULL ? false : m_reverse->getState(); @@ -318,10 +317,7 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name, race_manager->setReverseTrack(m_reverse->getState()); // Makes sure the highscores get swapped when clicking the 'reverse' // checkbox. - if (race_manager->modeHasHighscores()) - { - updateHighScores(); - } + updateHighScores(); } else if (name == "lap-spinner") { diff --git a/src/states_screens/track_info_screen.hpp b/src/states_screens/track_info_screen.hpp index 4034bd5de..e84173d6a 100644 --- a/src/states_screens/track_info_screen.hpp +++ b/src/states_screens/track_info_screen.hpp @@ -58,18 +58,21 @@ class TrackInfoScreen : public GUIEngine::Screen, /** Check box for reverse mode. */ GUIEngine::CheckBoxWidget* m_reverse; + /** The label of the highscore list. */ + GUIEngine::LabelWidget* m_highscore_label; + /** The icons for the highscore list. */ GUIEngine::IconButtonWidget* m_kart_icons[HIGHSCORE_COUNT]; /** The actual highscore text values shown. */ GUIEngine::LabelWidget* m_highscore_entries[HIGHSCORE_COUNT]; - + void updateHighScores(); - + public: TrackInfoScreen(); virtual ~TrackInfoScreen(); - + virtual void init(); virtual void loadedFromFile(); virtual void eventCallback(GUIEngine::Widget *,const std::string &name , From 0121ae8db6b2ebb3fea026204f4932fe7c6b5800 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 02:30:01 +0200 Subject: [PATCH 005/112] Use specmap value --- data/shaders/instanced_object_pass2.frag | 6 +++++- data/shaders/instanced_objectref_pass2.frag | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/data/shaders/instanced_object_pass2.frag b/data/shaders/instanced_object_pass2.frag index feebe72f2..8068bf40c 100644 --- a/data/shaders/instanced_object_pass2.frag +++ b/data/shaders/instanced_object_pass2.frag @@ -1,9 +1,11 @@ #ifndef GL_ARB_bindless_texture uniform sampler2D Albedo; +uniform sampler2D SpecMap; #endif #ifdef GL_ARB_bindless_texture flat in sampler2D handle; +flat in sampler2D secondhandle; #endif in vec2 uv; in vec4 color; @@ -15,12 +17,14 @@ void main(void) { #ifdef GL_ARB_bindless_texture vec4 col = texture(handle, uv); + float specmap = texture(secondhandle, uv).g; #ifdef SRGBBindlessFix col.xyz = pow(col.xyz, vec3(2.2)); #endif #else vec4 col = texture(Albedo, uv); + float specmap = texture(SpecMap, uv).g; #endif col.xyz *= pow(color.xyz, vec3(2.2)); - FragColor = vec4(getLightFactor(col.xyz, vec3(1.), 1.), 1.); + FragColor = vec4(getLightFactor(col.xyz, vec3(specmap), 1.), 1.); } diff --git a/data/shaders/instanced_objectref_pass2.frag b/data/shaders/instanced_objectref_pass2.frag index 045706254..41f3dc34f 100644 --- a/data/shaders/instanced_objectref_pass2.frag +++ b/data/shaders/instanced_objectref_pass2.frag @@ -1,9 +1,11 @@ #ifndef GL_ARB_bindless_texture uniform sampler2D Albedo; +uniform sampler2D SpecMap; #endif #ifdef GL_ARB_bindless_texture flat in sampler2D handle; +flat in sampler2D secondhandle; #endif in vec2 uv; in vec4 color; @@ -15,13 +17,15 @@ void main(void) { #ifdef GL_ARB_bindless_texture vec4 col = texture(handle, uv); + float specmap = texture(secondhandle, uv).g; #ifdef SRGBBindlessFix col.xyz = pow(col.xyz, vec3(2.2)); #endif #else vec4 col = texture(Albedo, uv); + float specmap = texture(SpecMap, uv).g; #endif col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a * color.a < 0.5) discard; - FragColor = vec4(getLightFactor(col.xyz, vec3(1.), 1.), 1.); + FragColor = vec4(getLightFactor(col.xyz, vec3(1.), specmap), 1.); } From df62c8921e9e04fc07459dbca13cd3f7ab24a4a8 Mon Sep 17 00:00:00 2001 From: hiker Date: Sun, 5 Oct 2014 21:35:14 +1100 Subject: [PATCH 006/112] Added limited lazy-load flag to avoid loading of all font textures (most of which might not be needed). Fixes #1592. --- data/fonts/materials.xml | 34 +++++++++---------- src/graphics/material.cpp | 11 ++++--- src/graphics/material.hpp | 69 +++++++++++++++++++++++++-------------- src/main.cpp | 7 ++-- 4 files changed, 71 insertions(+), 50 deletions(-) diff --git a/data/fonts/materials.xml b/data/fonts/materials.xml index 105ab3111..b33a66186 100644 --- a/data/fonts/materials.xml +++ b/data/fonts/materials.xml @@ -1,22 +1,22 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index d633a8a3c..b9244c1a6 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -57,8 +57,7 @@ Material::Material(const XMLNode *node, bool deprecated) m_shader_type = SHADERTYPE_SOLID; m_deprecated = deprecated; - node->get("name", &m_texname); - + node->get("name", &m_texname); if (m_texname=="") { throw std::runtime_error("[Material] No texture name specified " @@ -66,6 +65,7 @@ Material::Material(const XMLNode *node, bool deprecated) } init(); + node->get("lazy-load", &m_lazy_load); bool b = false; node->get("clampu", &b); if (b) m_clamp_tex |= UCLAMP; //blender 2.4 style @@ -412,10 +412,10 @@ Material::Material(const std::string& fname, bool is_full_path, */ void Material::init() { + m_lazy_load = false; + m_texture = NULL; m_clamp_tex = 0; m_shader_type = SHADERTYPE_SOLID; - //m_lightmap = false; - //m_adjust_image = ADJ_NONE; m_backface_culling = true; m_high_tire_adhesion = false; m_below_surface = false; @@ -455,6 +455,9 @@ void Material::init() //----------------------------------------------------------------------------- void Material::install(bool is_full_path, bool complain_if_not_found) { + // Don't load a texture that is lazily loaded. + if(m_lazy_load) return; + const std::string &full_path = is_full_path ? m_texname : file_manager->searchTexture(m_texname); diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index 4e95e648b..934c3c433 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -22,13 +22,11 @@ #include "utils/no_copy.hpp" +#include #include #include #include -#include - - namespace irr { namespace video { class ITexture; class SMaterial; } @@ -81,9 +79,18 @@ public: private: + /** Pointer to the texture. */ video::ITexture *m_texture; - //unsigned int m_index; + + /** Name of the texture. */ std::string m_texname; + + /** If true, the texture will not automatically be loaded and bound + * at load time, it must be loaded elsewhere. This is used to store + * material settings for font textures, without loading fonts for + * languages that might not be needed at all. */ + bool m_lazy_load; + /** Name of a special sfx to play when a kart is on this terrain, or * "" if no special sfx exists. */ std::string m_sfx_name; @@ -114,7 +121,7 @@ private: /** If a kart is rescued when driving on this surface. */ bool m_drive_reset; - /** True if this is a texture that will start the jump animatoin when + /** True if this is a texture that will start the jump animation when * leaving it and being in the air. */ bool m_is_jump_texture; @@ -244,27 +251,45 @@ public: void setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const; void setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb); - void adjustForFog(scene::ISceneNode* parent, video::SMaterial *m, bool use_fog) const; + void adjustForFog(scene::ISceneNode* parent, video::SMaterial *m, + bool use_fog) const; + void onMadeVisible(scene::IMeshBuffer* who); + void onHidden(scene::IMeshBuffer* who); + void isInitiallyHidden(scene::IMeshBuffer* who); /** Returns the ITexture associated with this material. */ - video::ITexture *getTexture() const { return m_texture; } + video::ITexture *getTexture() const + { + // Note that atm lazy load means that the textures are not loaded + // via the material. So getTexture should only get called for non + // lazily loaded textures (used atm for font textures. + assert(!m_lazy_load); + return m_texture; + } // getTexture + // ------------------------------------------------------------------------ bool isIgnore () const { return m_ignore; } + // ------------------------------------------------------------------------ /** Returns true if this material is a zipper. */ bool isZipper () const { return m_zipper; } + // ------------------------------------------------------------------------ /** Returns if this material should trigger a rescue if a kart * is driving on it. */ bool isDriveReset () const { return m_drive_reset; } + // ------------------------------------------------------------------------ /** Returns if this material should trigger a rescue if a kart * crashes against it. */ CollisionReaction getCollisionReaction() const { return m_collision_reaction; } + // ------------------------------------------------------------------------ std::string getCrashResetParticles() const { return m_collision_particles; } + // ------------------------------------------------------------------------ bool highTireAdhesion () const { return m_high_tire_adhesion; } + // ------------------------------------------------------------------------ const std::string& getTexFname () const { return m_texname; } - //int getIndex () const { return m_index; } + // ------------------------------------------------------------------------ bool isTransparent () const { return m_shader_type == SHADERTYPE_ADDITIVE || @@ -272,12 +297,6 @@ public: m_shader_type == SHADERTYPE_ALPHA_TEST; } - // ------------------------------------------------------------------------ - /** Returns true if this materials need pre-multiply of alpha. */ - //bool isPreMul() const {return m_adjust_image==ADJ_PREMUL; } - // ------------------------------------------------------------------------ - /** Returns true if this materials need pre-division of alpha. */ - //bool isPreDiv() const {return m_adjust_image==ADJ_DIV; } // ------------------------------------------------------------------------ /** Returns the fraction of maximum speed on this material. */ float getMaxSpeedFraction() const { return m_max_speed_fraction; } @@ -300,17 +319,20 @@ public: // ------------------------------------------------------------------------ /** Returns the name of a special sfx to play while a kart is on this * terrain. The string will be "" if no special sfx exists. */ - const std::string & - getSFXName () const { return m_sfx_name; } + const std::string &getSFXName() const { return m_sfx_name; } + // ------------------------------------------------------------------------ + /** Returns if fog is enabled. */ bool isFogEnabled() const { return m_fog; } - /** - * \brief Get the kind of particles that are to be used on this material, in the given conditions - * \return The particles to use, or NULL if none - */ - const ParticleKind* getParticlesWhen(ParticleConditions cond) const { return m_particles_effects[cond]; } - + // ------------------------------------------------------------------------ + /** \brief Get the kind of particles that are to be used on this material, + * in the given conditions. + * \return The particles to use, or NULL if none. */ + const ParticleKind* getParticlesWhen(ParticleConditions cond) const + { + return m_particles_effects[cond]; + } // getParticlesWhen // ------------------------------------------------------------------------ /** Returns true if a kart falling over this kind of material triggers * the special falling camera. */ @@ -346,9 +368,6 @@ public: // ------------------------------------------------------------------------ ShaderType getShaderType() const { return m_shader_type; } // ------------------------------------------------------------------------ - void onMadeVisible(scene::IMeshBuffer* who); - void onHidden(scene::IMeshBuffer* who); - void isInitiallyHidden(scene::IMeshBuffer* who); } ; diff --git a/src/main.cpp b/src/main.cpp index 546757998..54bd8b79e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1208,12 +1208,11 @@ int main(int argc, char *argv[] ) main_loop = new MainLoop(); material_manager->loadMaterial(); - // Load the font textures - file_manager->pushTextureSearchPath( - file_manager->getAsset(FileManager::FONT,"")); + // Load the font textures - they are all lazily loaded + // so no need to push a texture search path. They will actually + // be loaded from ScalableFont. material_manager->addSharedMaterial( file_manager->getAsset(FileManager::FONT,"materials.xml")); - file_manager->popTextureSearchPath(); GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI, "options_video.png")); From f95eeb7f56764f4e126d397e07d54523e492efe0 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Sun, 5 Oct 2014 15:11:45 +0200 Subject: [PATCH 007/112] Fix #1602 --- src/states_screens/user_screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp index 5029a90ad..787d6726a 100644 --- a/src/states_screens/user_screen.cpp +++ b/src/states_screens/user_screen.cpp @@ -282,7 +282,7 @@ void BaseUserScreen::eventCallback(Widget* widget, else if (button == "cancel") { StateManager::get()->popMenu(); - onEscapePressed(); + StateManager::get()->escapePressed(); } else if (button == "recover") { From 9f2b66d195bfcdb827a8306f1f9c0ddf7bfd79d5 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 20:37:49 +0200 Subject: [PATCH 008/112] Use specmap on others mats --- .../instanced_detailledobject_pass2.frag | 6 +++++- data/shaders/instanced_grass_pass2.frag | 6 +++++- src/graphics/render_geometry.cpp | 18 +++++++++--------- src/graphics/shaders.cpp | 8 ++++---- src/graphics/shaders.hpp | 8 ++++---- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/data/shaders/instanced_detailledobject_pass2.frag b/data/shaders/instanced_detailledobject_pass2.frag index 44790f61c..927a6a845 100644 --- a/data/shaders/instanced_detailledobject_pass2.frag +++ b/data/shaders/instanced_detailledobject_pass2.frag @@ -1,10 +1,12 @@ #ifndef GL_ARB_bindless_texture uniform sampler2D Albedo; uniform sampler2D Detail; +uniform sampler2D SpecMap; #endif #ifdef GL_ARB_bindless_texture flat in sampler2D handle; +flat in sampler2D secondhandle; flat in sampler2D thirdhandle; #endif in vec2 uv; @@ -17,6 +19,7 @@ void main(void) { #ifdef GL_ARB_bindless_texture vec4 color = texture(handle, uv); + float specmap = texture(secondhandle, uv).g; #ifdef SRGBBindlessFix color.xyz = pow(color.xyz, vec3(2.2)); #endif @@ -24,7 +27,8 @@ void main(void) #else vec4 color = texture(Albedo, uv); vec4 detail = texture(Detail, uv_bis); + float specmap = texture(SpecMap, uv).g; #endif color *= detail; - FragColor = vec4(getLightFactor(color.xyz, vec3(1.), 1.), 1.); + FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap), 1.); } diff --git a/data/shaders/instanced_grass_pass2.frag b/data/shaders/instanced_grass_pass2.frag index fd48f1012..0bd7f0dbe 100644 --- a/data/shaders/instanced_grass_pass2.frag +++ b/data/shaders/instanced_grass_pass2.frag @@ -2,6 +2,7 @@ layout(bindless_sampler) uniform sampler2D dtex; #else uniform sampler2D Albedo; +uniform sampler2D SpecMap; uniform sampler2D dtex; #endif @@ -9,6 +10,7 @@ uniform vec3 SunDir; #ifdef GL_ARB_bindless_texture flat in sampler2D handle; +flat in sampler2D secondhandle; #endif in vec3 nor; in vec2 uv; @@ -20,11 +22,13 @@ void main(void) { #ifdef GL_ARB_bindless_texture vec4 color = texture(handle, uv); + float specmap = texture(secondhandle, uv).g; #ifdef SRGBBindlessFix color.xyz = pow(color.xyz, vec3(2.2)); #endif #else vec4 color = texture(Albedo, uv); + float specmap = texture(SpecMap, uv).g; #endif if (color.a < 0.5) discard; @@ -44,6 +48,6 @@ void main(void) float scattering = mix(fPowEdotL, fLdotNBack, .5); - vec3 LightFactor = color.xyz * (scattering * 0.3) + getLightFactor(color.xyz, vec3(1.), 1.); + vec3 LightFactor = color.xyz * (scattering * 0.3) + getLightFactor(color.xyz, vec3(1.), specmap); FragColor = vec4(LightFactor, 1.); } diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index b0421af7c..2bc9426ce 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -75,7 +75,7 @@ struct DefaultMaterial }; const std::vector DefaultMaterial::FirstPassTextures = { 1 }; -const std::vector DefaultMaterial::SecondPassTextures = { 0 }; +const std::vector DefaultMaterial::SecondPassTextures = { 0, 1 }; struct AlphaRef { @@ -93,7 +93,7 @@ struct AlphaRef }; const std::vector AlphaRef::FirstPassTextures = { 0, 1 }; -const std::vector AlphaRef::SecondPassTextures = { 0 }; +const std::vector AlphaRef::SecondPassTextures = { 0, 1 }; struct SphereMap { @@ -165,7 +165,7 @@ struct NormalMat }; const std::vector NormalMat::FirstPassTextures = { 2, 1 }; -const std::vector NormalMat::SecondPassTextures = { 0 }; +const std::vector NormalMat::SecondPassTextures = { 0, 1 }; struct DetailMat { @@ -183,7 +183,7 @@ struct DetailMat }; const std::vector DetailMat::FirstPassTextures = { 1 }; -const std::vector DetailMat::SecondPassTextures = { 0, 2 }; +const std::vector DetailMat::SecondPassTextures = { 0, 2, 1 }; struct SplattingMat { @@ -531,15 +531,15 @@ void IrrDriver::renderSolidSecondPass() if (UserConfigParams::m_azdo) { - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); + multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); + multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle, 0), windDir, cb->getPosition()); + multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle, 0, 0), windDir, cb->getPosition()); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0)); - multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); + multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0)); + multidraw2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0, 0)); } else if (irr_driver->hasARB_draw_indirect()) { diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index d18c1900a..61148e2ac 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -865,7 +865,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_object_pass2.frag").c_str()); AssignUniforms(); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "SpecMap"); } InstancedObjectRefPass2Shader::InstancedObjectRefPass2Shader() @@ -876,7 +876,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_objectref_pass2.frag").c_str()); AssignUniforms(); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "SpecMap"); } DetailledObjectPass2Shader::DetailledObjectPass2Shader() @@ -897,7 +897,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_detailledobject_pass2.frag").c_str()); AssignUniforms(); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Detail"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Detail", 5, "SpecMap"); } ObjectUnlitShader::ObjectUnlitShader() @@ -947,7 +947,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_grass_pass2.frag").c_str()); AssignUniforms("windDir", "SunDir"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "dtex", 4, "Albedo"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "dtex", 4, "Albedo", 4, "SpecMap"); } SphereMapShader::SphereMapShader() diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 9a0214731..719bf63b0 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -107,13 +107,13 @@ public: ObjectPass2Shader(); }; -class InstancedObjectPass2Shader : public ShaderHelperSingleton, public TextureRead +class InstancedObjectPass2Shader : public ShaderHelperSingleton, public TextureRead { public: InstancedObjectPass2Shader(); }; -class InstancedObjectRefPass2Shader : public ShaderHelperSingleton, public TextureRead +class InstancedObjectRefPass2Shader : public ShaderHelperSingleton, public TextureRead { public: InstancedObjectRefPass2Shader(); @@ -125,7 +125,7 @@ public: DetailledObjectPass2Shader(); }; -class InstancedDetailledObjectPass2Shader : public ShaderHelperSingleton, public TextureRead +class InstancedDetailledObjectPass2Shader : public ShaderHelperSingleton, public TextureRead { public: InstancedDetailledObjectPass2Shader(); @@ -155,7 +155,7 @@ public: GrassPass2Shader(); }; -class InstancedGrassPass2Shader : public ShaderHelperSingleton, public TextureRead +class InstancedGrassPass2Shader : public ShaderHelperSingleton, public TextureRead { public: InstancedGrassPass2Shader(); From a8161288a9e5d4b856afce3297df386cbbe56bab Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 20:47:13 +0200 Subject: [PATCH 009/112] Convert remaining shaders --- data/shaders/detailledobject_pass2.frag | 5 ++++- data/shaders/grass_pass2.frag | 5 ++++- data/shaders/object_pass2.frag | 5 ++++- data/shaders/objectref_pass2.frag | 5 ++++- src/graphics/shaders.cpp | 10 +++++----- src/graphics/shaders.hpp | 8 ++++---- 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/data/shaders/detailledobject_pass2.frag b/data/shaders/detailledobject_pass2.frag index 832a68f70..5b19966cc 100644 --- a/data/shaders/detailledobject_pass2.frag +++ b/data/shaders/detailledobject_pass2.frag @@ -1,9 +1,11 @@ #ifdef GL_ARB_bindless_texture layout(bindless_sampler) uniform sampler2D Albedo; layout(bindless_sampler) uniform sampler2D Detail; +layout(bindless_sampler) uniform sampler2D SpecMap; #else uniform sampler2D Albedo; uniform sampler2D Detail; +uniform sampler2D SpecMap; #endif #if __VERSION__ >= 130 @@ -28,5 +30,6 @@ void main(void) #endif vec4 detail = texture(Detail, uv_bis); color *= detail; - FragColor = vec4(getLightFactor(color.xyz, vec3(1.), 1.), 1.); + float specmap = texture(SpecMap, uv).g; + FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap), 1.); } diff --git a/data/shaders/grass_pass2.frag b/data/shaders/grass_pass2.frag index 10d747e1b..6b677ceea 100644 --- a/data/shaders/grass_pass2.frag +++ b/data/shaders/grass_pass2.frag @@ -1,9 +1,11 @@ #ifdef GL_ARB_bindless_texture layout(bindless_sampler) uniform sampler2D Albedo; layout(bindless_sampler) uniform sampler2D dtex; +layout(bindless_sampler) uniform sampler2D SpecMap; #else uniform sampler2D Albedo; uniform sampler2D dtex; +uniform sampler2D SpecMap; #endif uniform vec3 SunDir; @@ -38,7 +40,8 @@ void main(void) float fLdotNBack = max(0., - dot(nor, SunDir) * 0.6 + 0.4); float scattering = mix(fPowEdotL, fLdotNBack, .5); + float specmap = texture(SpecMap, uv).g; - vec3 LightFactor = color.xyz * (scattering * 0.3) + getLightFactor(color.xyz, vec3(1.), 1.); + vec3 LightFactor = color.xyz * (scattering * 0.3) + getLightFactor(color.xyz, vec3(1.), specmap); FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index 53341f689..dc2fca7f1 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -1,7 +1,9 @@ #ifdef GL_ARB_bindless_texture layout(bindless_sampler) uniform sampler2D Albedo; +layout(bindless_sampler) uniform sampler2D SpecMap; #else uniform sampler2D Albedo; +uniform sampler2D SpecMap; #endif in vec2 uv; @@ -21,5 +23,6 @@ void main(void) vec4 col = texture(Albedo, uv); #endif col.xyz *= pow(color.xyz, vec3(2.2)); - FragColor = vec4(getLightFactor(color.xyz, vec3(1.), 1.), 1.); + float specmap = texture(SpecMap, uv).g; + FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap), 1.); } diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index d6b2d1f1c..ae1531a98 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -1,7 +1,9 @@ #ifdef GL_ARB_bindless_texture layout(bindless_sampler) uniform sampler2D Albedo; +layout(bindless_sampler) uniform sampler2D SpecMap; #else uniform sampler2D Albedo; +uniform sampler2D SpecMap; #endif in vec2 uv; @@ -20,5 +22,6 @@ void main(void) #endif col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a * color.a < 0.5) discard; - FragColor = vec4(getLightFactor(color.xyz, vec3(1.), 1.), 1.); + float specmap = texture(SpecMap, uv).g; + FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap), 1.); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 61148e2ac..289d81660 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -854,7 +854,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str()); AssignUniforms("ModelMatrix", "TextureMatrix"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Specmap"); } InstancedObjectPass2Shader::InstancedObjectPass2Shader() @@ -886,7 +886,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/detailledobject_pass2.frag").c_str()); AssignUniforms("ModelMatrix"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Detail"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Detail", 5, "Specmap"); } InstancedDetailledObjectPass2Shader::InstancedDetailledObjectPass2Shader() @@ -926,7 +926,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str()); AssignUniforms("ModelMatrix", "TextureMatrix"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Specmap"); } GrassPass2Shader::GrassPass2Shader() @@ -936,7 +936,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str()); AssignUniforms("ModelMatrix", "windDir"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Specmap"); } InstancedGrassPass2Shader::InstancedGrassPass2Shader() @@ -947,7 +947,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_grass_pass2.frag").c_str()); AssignUniforms("windDir", "SunDir"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "dtex", 4, "Albedo", 4, "SpecMap"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "dtex", 4, "Albedo", 5, "SpecMap"); } SphereMapShader::SphereMapShader() diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 719bf63b0..3113ce75c 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -101,7 +101,7 @@ public: InstancedNormalMapShader(); }; -class ObjectPass2Shader : public ShaderHelperSingleton, public TextureRead +class ObjectPass2Shader : public ShaderHelperSingleton, public TextureRead { public: ObjectPass2Shader(); @@ -119,7 +119,7 @@ public: InstancedObjectRefPass2Shader(); }; -class DetailledObjectPass2Shader : public ShaderHelperSingleton, public TextureRead +class DetailledObjectPass2Shader : public ShaderHelperSingleton, public TextureRead { public: DetailledObjectPass2Shader(); @@ -143,13 +143,13 @@ public: InstancedObjectUnlitShader(); }; -class ObjectRefPass2Shader : public ShaderHelperSingleton, public TextureRead +class ObjectRefPass2Shader : public ShaderHelperSingleton, public TextureRead { public: ObjectRefPass2Shader(); }; -class GrassPass2Shader : public ShaderHelperSingleton, public TextureRead +class GrassPass2Shader : public ShaderHelperSingleton, public TextureRead { public: GrassPass2Shader(); From 297221ca3d13505fdfbb7e702f7ecb2bd10a9a0a Mon Sep 17 00:00:00 2001 From: Flakebi Date: Sun, 5 Oct 2014 21:32:14 +0200 Subject: [PATCH 010/112] Fix #1438 --- src/guiengine/widgets/ribbon_widget.cpp | 26 ++++--------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/src/guiengine/widgets/ribbon_widget.cpp b/src/guiengine/widgets/ribbon_widget.cpp index 2300dbf91..78e2b95d1 100644 --- a/src/guiengine/widgets/ribbon_widget.cpp +++ b/src/guiengine/widgets/ribbon_widget.cpp @@ -141,14 +141,8 @@ void RibbonWidget::add() total_needed_space += m_active_children[i].m_w; } - int free_w_space = m_w - total_needed_space; - //int biggest_y = 0; const int button_y = 10; - float global_zoom = 1; - - const int min_free_space = 50; - global_zoom = (float)m_w / (float)( m_w - free_w_space + min_free_space ); const int one_button_space = int(roundf((float)m_w / (float)subbuttons_amount)); @@ -320,22 +314,10 @@ void RibbonWidget::add() float image_h = (float)image->getSize().Height; float image_w = image_h*imageRatio; - - // scale to fit (FIXME: calculate the right value directly...) - float zoom = global_zoom; - - if (button_y + image_h*zoom + needed_space_under_button > m_h) - { - // scale down - while (button_y + image_h*zoom + - needed_space_under_button > m_h) zoom -= 0.01f; - } - else - { - // scale up - while (button_y + image_h*zoom + - needed_space_under_button < m_h) zoom += 0.01f; - } + float zoom = (float) (m_h - button_y - needed_space_under_button) / image_h; + float zoom_x = (float) one_button_space / image_w; + if(zoom_x < zoom) + zoom = zoom_x; // ---- add bitmap button part // backup and restore position in case the same object is added From 4c4aba2ad8c1c97c25d72694c4c6f00a43c0145a Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 21:33:11 +0200 Subject: [PATCH 011/112] Some fixes --- src/graphics/render_geometry.cpp | 2 +- src/graphics/shaders.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index 2bc9426ce..613c9c1e5 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -147,7 +147,7 @@ struct GrassMat }; const std::vector GrassMat::FirstPassTextures = { 0 }; -const std::vector GrassMat::SecondPassTextures = { 0 }; +const std::vector GrassMat::SecondPassTextures = { 0, 1 }; struct NormalMat { diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 289d81660..d445f96a9 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -854,7 +854,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass2.frag").c_str()); AssignUniforms("ModelMatrix", "TextureMatrix"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Specmap"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "SpecMap"); } InstancedObjectPass2Shader::InstancedObjectPass2Shader() @@ -886,7 +886,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/detailledobject_pass2.frag").c_str()); AssignUniforms("ModelMatrix"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Detail", 5, "Specmap"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Detail", 5, "SpecMap"); } InstancedDetailledObjectPass2Shader::InstancedDetailledObjectPass2Shader() @@ -926,7 +926,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str()); AssignUniforms("ModelMatrix", "TextureMatrix"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Specmap"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "SpecMap"); } GrassPass2Shader::GrassPass2Shader() @@ -936,7 +936,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str()); AssignUniforms("ModelMatrix", "windDir"); - AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "Specmap"); + AssignSamplerNames(Program, 0, "DiffuseMap", 1, "SpecularMap", 2, "SSAO", 3, "Albedo", 4, "SpecMap"); } InstancedGrassPass2Shader::InstancedGrassPass2Shader() From 300a09746fafd44a7b46f661009cd5eeda03376d Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 21:45:56 +0200 Subject: [PATCH 012/112] Additionnal fixes --- data/shaders/object_pass2.frag | 2 +- data/shaders/objectref_pass2.frag | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index dc2fca7f1..ba984f87d 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -24,5 +24,5 @@ void main(void) #endif col.xyz *= pow(color.xyz, vec3(2.2)); float specmap = texture(SpecMap, uv).g; - FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap), 1.); + FragColor = vec4(getLightFactor(col.xyz, vec3(1.), specmap), 1.); } diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index ae1531a98..a7fd08dca 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -23,5 +23,5 @@ void main(void) col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a * color.a < 0.5) discard; float specmap = texture(SpecMap, uv).g; - FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap), 1.); + FragColor = vec4(getLightFactor(col.xyz, vec3(1.), specmap), 1.); } From 0db951f3741227568374771a8d72d0deba509ba6 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 21:53:06 +0200 Subject: [PATCH 013/112] Try to emulate enery conservation --- data/shaders/instanced_object_pass2.frag | 2 +- data/shaders/instanced_objectpass_spheremap.frag | 2 +- data/shaders/objectpass_spheremap.frag | 2 +- data/shaders/utils/getLightFactor.frag | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/shaders/instanced_object_pass2.frag b/data/shaders/instanced_object_pass2.frag index 8068bf40c..c260d7aab 100644 --- a/data/shaders/instanced_object_pass2.frag +++ b/data/shaders/instanced_object_pass2.frag @@ -26,5 +26,5 @@ void main(void) float specmap = texture(SpecMap, uv).g; #endif col.xyz *= pow(color.xyz, vec3(2.2)); - FragColor = vec4(getLightFactor(col.xyz, vec3(specmap), 1.), 1.); + FragColor = vec4(getLightFactor(col.xyz, vec3(1.), specmap), 1.); } diff --git a/data/shaders/instanced_objectpass_spheremap.frag b/data/shaders/instanced_objectpass_spheremap.frag index 50ce74fb6..21414ee31 100644 --- a/data/shaders/instanced_objectpass_spheremap.frag +++ b/data/shaders/instanced_objectpass_spheremap.frag @@ -30,5 +30,5 @@ void main() { vec4 detail0 = texture(tex, r.xy / m + .5); #endif - FragColor = vec4(getLightFactor(detail0.xyz, vec3(1.), 1.), 1.); + FragColor = vec4(getLightFactor(detail0.xyz, vec3(1.), 0.), 1.); } diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 5e1400a3d..e5ed033d1 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -31,5 +31,5 @@ void main() { #endif #endif - FragColor = vec4(getLightFactor(detail0.xyz, vec3(1.), 1.), 1.); + FragColor = vec4(getLightFactor(detail0.xyz, vec3(1.), 0.), 1.); } diff --git a/data/shaders/utils/getLightFactor.frag b/data/shaders/utils/getLightFactor.frag index 8c04c7694..7d974d56d 100644 --- a/data/shaders/utils/getLightFactor.frag +++ b/data/shaders/utils/getLightFactor.frag @@ -14,6 +14,6 @@ vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapVa vec3 DiffuseComponent = texture(DiffuseMap, tc).xyz; vec3 SpecularComponent = texture(SpecularMap, tc).xyz; float ao = texture(SSAO, tc).x; - vec3 tmp = diffuseMatColor * DiffuseComponent + specularMatColor * SpecularComponent * specMapValue; + vec3 tmp = diffuseMatColor * DiffuseComponent * (1. - specMapValue) + specularMatColor * SpecularComponent * specMapValue; return tmp * ao; } \ No newline at end of file From 019db1a11d3ff19e1d931475c35387a58c74c459 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 21:56:04 +0200 Subject: [PATCH 014/112] Revert "Revert "Prepare shader for specmap value"" This reverts commit 780482edba2b0de3358f7e2139db3de3318f729e. --- data/shaders/detailledobject_pass2.frag | 5 ++-- data/shaders/grass_pass2.frag | 19 +++++++------- .../instanced_detailledobject_pass2.frag | 5 ++-- data/shaders/instanced_grass_pass2.frag | 26 ++++++++++--------- data/shaders/instanced_object_pass2.frag | 5 ++-- .../instanced_objectpass_spheremap.frag | 5 ++-- data/shaders/instanced_objectref_pass2.frag | 5 ++-- data/shaders/object_pass2.frag | 5 ++-- data/shaders/objectpass_spheremap.frag | 5 ++-- data/shaders/objectref_pass2.frag | 5 ++-- data/shaders/splatting.frag | 5 ++-- data/shaders/utils/getLightFactor.frag | 4 +-- 12 files changed, 44 insertions(+), 50 deletions(-) diff --git a/data/shaders/detailledobject_pass2.frag b/data/shaders/detailledobject_pass2.frag index a426b6935..832a68f70 100644 --- a/data/shaders/detailledobject_pass2.frag +++ b/data/shaders/detailledobject_pass2.frag @@ -16,7 +16,7 @@ varying vec2 uv_bis; #define FragColor gl_FragColor #endif -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main(void) { @@ -28,6 +28,5 @@ void main(void) #endif vec4 detail = texture(Detail, uv_bis); color *= detail; - vec3 LightFactor = getLightFactor(1. - color.a); - FragColor = vec4(color.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(color.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/grass_pass2.frag b/data/shaders/grass_pass2.frag index 408e78365..10d747e1b 100644 --- a/data/shaders/grass_pass2.frag +++ b/data/shaders/grass_pass2.frag @@ -12,10 +12,18 @@ in vec3 nor; in vec2 uv; out vec4 FragColor; -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main(void) { + vec4 color = texture(Albedo, uv); +#ifdef GL_ARB_bindless_texture +#ifdef SRGBBindlessFix + color.xyz = pow(color.xyz, vec3(2.2)); +#endif +#endif + if (color.a < 0.5) discard; + vec2 texc = gl_FragCoord.xy / screen; float z = texture(dtex, texc).x; @@ -31,13 +39,6 @@ void main(void) float fLdotNBack = max(0., - dot(nor, SunDir) * 0.6 + 0.4); float scattering = mix(fPowEdotL, fLdotNBack, .5); - vec4 color = texture(Albedo, uv); -#ifdef GL_ARB_bindless_texture -#ifdef SRGBBindlessFix - color.xyz = pow(color.xyz, vec3(2.2)); -#endif -#endif - if (color.a < 0.5) discard; - vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.); + vec3 LightFactor = color.xyz * (scattering * 0.3) + getLightFactor(color.xyz, vec3(1.), 1.); FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/data/shaders/instanced_detailledobject_pass2.frag b/data/shaders/instanced_detailledobject_pass2.frag index c631fe3ef..44790f61c 100644 --- a/data/shaders/instanced_detailledobject_pass2.frag +++ b/data/shaders/instanced_detailledobject_pass2.frag @@ -11,7 +11,7 @@ in vec2 uv; in vec2 uv_bis; out vec4 FragColor; -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main(void) { @@ -26,6 +26,5 @@ void main(void) vec4 detail = texture(Detail, uv_bis); #endif color *= detail; - vec3 LightFactor = getLightFactor(1. - color.a); - FragColor = vec4(color.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(color.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/instanced_grass_pass2.frag b/data/shaders/instanced_grass_pass2.frag index b297a4c88..fd48f1012 100644 --- a/data/shaders/instanced_grass_pass2.frag +++ b/data/shaders/instanced_grass_pass2.frag @@ -14,10 +14,20 @@ in vec3 nor; in vec2 uv; out vec4 FragColor; -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main(void) { +#ifdef GL_ARB_bindless_texture + vec4 color = texture(handle, uv); +#ifdef SRGBBindlessFix + color.xyz = pow(color.xyz, vec3(2.2)); +#endif +#else + vec4 color = texture(Albedo, uv); +#endif + if (color.a < 0.5) discard; + vec2 texc = gl_FragCoord.xy / screen; float z = texture(dtex, texc).x; @@ -33,15 +43,7 @@ void main(void) float fLdotNBack = max(0., - dot(nor, SunDir) * 0.6 + 0.4); float scattering = mix(fPowEdotL, fLdotNBack, .5); -#ifdef GL_ARB_bindless_texture - vec4 color = texture(handle, uv); -#ifdef SRGBBindlessFix - color.xyz = pow(color.xyz, vec3(2.2)); -#endif -#else - vec4 color = texture(Albedo, uv); -#endif - if (color.a < 0.5) discard; - vec3 LightFactor = (scattering * 0.3) + getLightFactor(1.); - FragColor = vec4(color.xyz * LightFactor, 1.); + + vec3 LightFactor = color.xyz * (scattering * 0.3) + getLightFactor(color.xyz, vec3(1.), 1.); + FragColor = vec4(LightFactor, 1.); } diff --git a/data/shaders/instanced_object_pass2.frag b/data/shaders/instanced_object_pass2.frag index 76176ba37..feebe72f2 100644 --- a/data/shaders/instanced_object_pass2.frag +++ b/data/shaders/instanced_object_pass2.frag @@ -9,7 +9,7 @@ in vec2 uv; in vec4 color; out vec4 FragColor; -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main(void) { @@ -22,6 +22,5 @@ void main(void) vec4 col = texture(Albedo, uv); #endif col.xyz *= pow(color.xyz, vec3(2.2)); - vec3 LightFactor = getLightFactor(1.); - FragColor = vec4(col.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(col.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/instanced_objectpass_spheremap.frag b/data/shaders/instanced_objectpass_spheremap.frag index 5365dd7ef..50ce74fb6 100644 --- a/data/shaders/instanced_objectpass_spheremap.frag +++ b/data/shaders/instanced_objectpass_spheremap.frag @@ -12,7 +12,7 @@ out vec4 FragColor; vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main() { vec3 texc = gl_FragCoord.xyz / vec3(screen, 1.); @@ -29,7 +29,6 @@ void main() { #else vec4 detail0 = texture(tex, r.xy / m + .5); #endif - vec3 LightFactor = getLightFactor(1.); - FragColor = vec4(detail0.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(detail0.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/instanced_objectref_pass2.frag b/data/shaders/instanced_objectref_pass2.frag index 201f610a1..045706254 100644 --- a/data/shaders/instanced_objectref_pass2.frag +++ b/data/shaders/instanced_objectref_pass2.frag @@ -9,7 +9,7 @@ in vec2 uv; in vec4 color; out vec4 FragColor; -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main(void) { @@ -23,6 +23,5 @@ void main(void) #endif col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a * color.a < 0.5) discard; - vec3 LightFactor = getLightFactor(1.); - FragColor = vec4(col.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(col.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index 047f0a192..53341f689 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -8,7 +8,7 @@ in vec2 uv; in vec4 color; out vec4 FragColor; -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main(void) { @@ -21,6 +21,5 @@ void main(void) vec4 col = texture(Albedo, uv); #endif col.xyz *= pow(color.xyz, vec3(2.2)); - vec3 LightFactor = getLightFactor(1.); - FragColor = vec4(col.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(color.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 8e4e0f4fc..5e1400a3d 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -15,7 +15,7 @@ varying vec3 nor; #endif vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main() { vec3 texc = gl_FragCoord.xyz / vec3(screen, 1.); @@ -30,7 +30,6 @@ void main() { detail0.xyz = pow(detail0.xyz, vec3(2.2)); #endif #endif - vec3 LightFactor = getLightFactor(1.); - FragColor = vec4(detail0.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(detail0.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index 13ff676f8..d6b2d1f1c 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -8,7 +8,7 @@ in vec2 uv; in vec4 color; out vec4 FragColor; -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main(void) { @@ -20,6 +20,5 @@ void main(void) #endif col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a * color.a < 0.5) discard; - vec3 LightFactor = getLightFactor(1.); - FragColor = vec4(col.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(color.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index d302908d2..3641c8d40 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -22,7 +22,7 @@ varying vec2 uv_bis; #define FragColor gl_FragColor #endif -vec3 getLightFactor(float specMapValue); +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue); void main() { // Splatting part @@ -46,6 +46,5 @@ void main() { splatting.b * detail2 + max(0., (1.0 - splatting.r - splatting.g - splatting.b)) * detail3; - vec3 LightFactor = getLightFactor(1.); - FragColor = vec4(splatted.xyz * LightFactor, 1.); + FragColor = vec4(getLightFactor(splatted.xyz, vec3(1.), 1.), 1.); } diff --git a/data/shaders/utils/getLightFactor.frag b/data/shaders/utils/getLightFactor.frag index 9bf4cdf58..8c04c7694 100644 --- a/data/shaders/utils/getLightFactor.frag +++ b/data/shaders/utils/getLightFactor.frag @@ -8,12 +8,12 @@ uniform sampler2D SpecularMap; uniform sampler2D SSAO; #endif -vec3 getLightFactor(float specMapValue) +vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue) { vec2 tc = gl_FragCoord.xy / screen; vec3 DiffuseComponent = texture(DiffuseMap, tc).xyz; vec3 SpecularComponent = texture(SpecularMap, tc).xyz; float ao = texture(SSAO, tc).x; - vec3 tmp = DiffuseComponent + SpecularComponent * specMapValue; + vec3 tmp = diffuseMatColor * DiffuseComponent + specularMatColor * SpecularComponent * specMapValue; return tmp * ao; } \ No newline at end of file From 4bb73e0573ea9bea3cf867d2e817ac765268f949 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 22:23:10 +0200 Subject: [PATCH 015/112] Fix godray opacity --- src/graphics/post_processing.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index dee6b68a4..d4370bb8b 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -662,7 +662,8 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo // Blend glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); + glBlendColor(0., 0., 0., track->getGodRaysOpacity()); + glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE); glBlendEquation(GL_FUNC_ADD); in_fbo->Bind(); From 44792a1490d529ef63d300e7237628f4e8a04b27 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 5 Oct 2014 22:46:02 +0200 Subject: [PATCH 016/112] Fix splatting --- data/shaders/splatting.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index 3641c8d40..acc6fabc3 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -46,5 +46,5 @@ void main() { splatting.b * detail2 + max(0., (1.0 - splatting.r - splatting.g - splatting.b)) * detail3; - FragColor = vec4(getLightFactor(splatted.xyz, vec3(1.), 1.), 1.); + FragColor = vec4(getLightFactor(splatted.xyz, vec3(1.), 0.), 1.); } From 6f5b7aa4ae0e9e55b418f0aaf0c01b73944a17b8 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 6 Oct 2014 07:48:15 +1100 Subject: [PATCH 017/112] Tried a different layout for the checkboxes (sorry, but I didn't like the previous approach at all). Only disadvantage now (I can think of) is that the width of the lables is now hard coded to 40% of the screen. --- data/gui/user_screen.stkgui | 16 ++++++---------- data/gui/user_screen_tab.stkgui | 16 +++++++--------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/data/gui/user_screen.stkgui b/data/gui/user_screen.stkgui index 0a7d83e31..a9c54f543 100644 --- a/data/gui/user_screen.stkgui +++ b/data/gui/user_screen.stkgui @@ -15,25 +15,23 @@
- - -
- - -
-
@@ -56,8 +54,6 @@ I18N="Login dialog" text="Add user" label_location="bottom"/> -
-
- - -
diff --git a/src/config/device_config.cpp b/src/config/device_config.cpp index 488550389..96a671899 100644 --- a/src/config/device_config.cpp +++ b/src/config/device_config.cpp @@ -83,6 +83,10 @@ irr::core::stringw DeviceConfig::getMappingIdString (const PlayerAction action) returnString += id; break; + case Input::IT_NONE: + returnString += "none"; + break; + default: assert(false); returnString += type; diff --git a/src/states_screens/dialogs/press_a_key_dialog.cpp b/src/states_screens/dialogs/press_a_key_dialog.cpp index 5070067c6..464b09fa5 100644 --- a/src/states_screens/dialogs/press_a_key_dialog.cpp +++ b/src/states_screens/dialogs/press_a_key_dialog.cpp @@ -44,6 +44,12 @@ GUIEngine::EventPropagation PressAKeyDialog::processEvent(const std::string& eve dismiss(); return GUIEngine::EVENT_BLOCK; } + else if (eventSource == "assignNone") + { + Input simulatedInput; + OptionsScreenInput2::getInstance()->gotSensedInput(simulatedInput); + return GUIEngine::EVENT_BLOCK; + } else if (eventSource == "assignEsc") { Input simulatedInput(Input::IT_KEYBOARD, 0 /* deviceID */, KEY_ESCAPE); diff --git a/src/states_screens/options_screen_input2.cpp b/src/states_screens/options_screen_input2.cpp index 2f72ce1ed..2b1fad3cc 100644 --- a/src/states_screens/options_screen_input2.cpp +++ b/src/states_screens/options_screen_input2.cpp @@ -447,6 +447,23 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input) updateInputButtons(); } } + else if (sensed_input.m_type == Input::IT_NONE) + { + if (UserConfigParams::logMisc()) + { + std::cout << "% Binding " << KartActionStrings[binding_to_set] + << " : setting to keyboard key NONE\n\n"; + } + + KeyboardConfig* keyboard = (KeyboardConfig*)m_config; + keyboard->setBinding(binding_to_set, Input::IT_NONE, + sensed_input.m_button_id, Input::AD_NEUTRAL, + Input::AR_HALF, + sensed_input.m_character); + + // refresh display + updateInputButtons(); + } else { return; From 6a47c157d2a0ab1b1c71e6c20abc570b19b39a1a Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 7 Oct 2014 15:42:22 +1100 Subject: [PATCH 027/112] Removed "" around linux version number in hardware report, compiler warning and windows line endings. --- src/config/hardware_stats.cpp | 63 ++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/config/hardware_stats.cpp b/src/config/hardware_stats.cpp index dd784e10c..1a459e531 100644 --- a/src/config/hardware_stats.cpp +++ b/src/config/hardware_stats.cpp @@ -124,7 +124,6 @@ bool readEtcReleaseFile(const std::string &filename) { std::ifstream in(filename); std::string s, distro, version; - int bits = 0; while( (distro.empty() || version.empty()) && std::getline(in, s) ) { @@ -135,6 +134,8 @@ bool readEtcReleaseFile(const std::string &filename) } if(!distro.empty() && !version.empty()) { + distro = StringUtils::replace(distro, "\"", ""); + version = StringUtils::replace(version, "\"", ""); m_os_version = distro + " " + version; return true; } @@ -167,36 +168,36 @@ void determineOSVersion() #endif #ifdef WIN32 // (C) 2014 by Wildfire Games (0 A.D.), ported by Joerg Henrichs. - - HKEY hKey; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, - KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) - { - m_os_version = "windows-unknown"; - return; - } - char windows_version_string[20]; - DWORD size = sizeof(windows_version_string); - RegQueryValueEx(hKey, "CurrentVersion", 0, 0, (LPBYTE)windows_version_string, &size); - unsigned major = 0, minor = 0; - const int ret = sscanf_s(windows_version_string, "%u.%u", &major, &minor); - int windows_version = (major << 8) | minor; - RegCloseKey(hKey); - - switch(windows_version) - { - case 0x0500: m_os_version="Windows 2000"; break; - case 0x0501: m_os_version="Windows XP"; break; - case 0x0502: m_os_version="Windows XP64"; break; - case 0x0600: m_os_version="Windows Vista"; break; - case 0x0601: m_os_version="Windows 7"; break; - case 0x0602: m_os_version="Windows 8"; break; - default: { - m_os_version = StringUtils::insertValues("Windows %d", - windows_version); - break; - } + + HKEY hKey; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, + KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) + { + m_os_version = "windows-unknown"; + return; + } + char windows_version_string[20]; + DWORD size = sizeof(windows_version_string); + RegQueryValueEx(hKey, "CurrentVersion", 0, 0, (LPBYTE)windows_version_string, &size); + unsigned major = 0, minor = 0; + const int ret = sscanf_s(windows_version_string, "%u.%u", &major, &minor); + int windows_version = (major << 8) | minor; + RegCloseKey(hKey); + + switch(windows_version) + { + case 0x0500: m_os_version="Windows 2000"; break; + case 0x0501: m_os_version="Windows XP"; break; + case 0x0502: m_os_version="Windows XP64"; break; + case 0x0600: m_os_version="Windows Vista"; break; + case 0x0601: m_os_version="Windows 7"; break; + case 0x0602: m_os_version="Windows 8"; break; + default: { + m_os_version = StringUtils::insertValues("Windows %d", + windows_version); + break; + } } // switch #endif From 6b43e2dd6fce6610e2ec6864f3bdf18061f10890 Mon Sep 17 00:00:00 2001 From: deve Date: Tue, 7 Oct 2014 06:54:02 +0200 Subject: [PATCH 028/112] Don't allow too long GP names. --- .../dialogs/enter_gp_name_dialog.cpp | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/states_screens/dialogs/enter_gp_name_dialog.cpp b/src/states_screens/dialogs/enter_gp_name_dialog.cpp index b7e24ce20..37f9c28da 100644 --- a/src/states_screens/dialogs/enter_gp_name_dialog.cpp +++ b/src/states_screens/dialogs/enter_gp_name_dialog.cpp @@ -80,29 +80,31 @@ void EnterGPNameDialog::onEnterPressedInternal() //Otherwise, see if we can accept the new name TextBoxWidget* textCtrl = getWidget("textfield"); assert(textCtrl != NULL); + LabelWidget* label = getWidget("title"); + assert(label != NULL); + stringw name = textCtrl->getText().trim(); - if (name.size() > 0 && name != "Random Grand Prix") + if (name.size() == 0) + { + label->setText(_("Name is empty."), false); + SFXManager::get()->quickSound("anvil"); + } + else if (grand_prix_manager->existsName(name) || name == "Random Grand Prix") { // check for duplicate names - if (grand_prix_manager->existsName(name)) - { - LabelWidget* label = getWidget("title"); - assert(label != NULL); - label->setText(_("Another grand prix with this name already exists."), false); - SFXManager::get()->quickSound("anvil"); - return; - } - - // It's unsafe to delete from inside the event handler so we do it - // in onUpdate (which checks for m_self_destroy) - m_self_destroy = true; + label->setText(_("Another grand prix with this name already exists."), false); + SFXManager::get()->quickSound("anvil"); + } + else if (name.size() > 30) + { + label->setText(_("Name is too long."), false); + SFXManager::get()->quickSound("anvil"); } else { - LabelWidget* label = getWidget("title"); - assert(label != NULL); - label->setText(_("Cannot add a grand prix with this name"), false); - SFXManager::get()->quickSound("anvil"); + // It's unsafe to delete from inside the event handler so we do it + // in onUpdate (which checks for m_self_destroy) + m_self_destroy = true; } } From ed7a114f5f4477d7f4f7d8e3434c2ce395c96e93 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 7 Oct 2014 16:52:18 +1100 Subject: [PATCH 029/112] Fix #1583: flushing entries from the online profile cache would make friend lists of other progiles incomplete. Also increased cache size to 100. --- src/online/online_profile.hpp | 4 ++++ src/online/profile_manager.cpp | 41 +++++++++++++++++++++++++++++++++- src/online/profile_manager.hpp | 8 ++++--- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/online/online_profile.hpp b/src/online/online_profile.hpp index 0ad3b86e4..271b331e7 100644 --- a/src/online/online_profile.hpp +++ b/src/online/online_profile.hpp @@ -125,6 +125,10 @@ public: /** Returns true if the achievements for this profile have been fetched. */ bool hasFetchedAchievements() const { return m_has_fetched_achievements; } + // ------------------------------------------------------------------------ + /** Unsets the flag that all friends of this profile are in cache. Used + * when a profile is pushed out of cache. */ + void unsetHasFetchedFriends() { m_has_fetched_friends = false; } // ------------------------------------------------------------------------ /** Returns true if the friend list for this profile has been fetched. */ bool hasFetchedFriends() const { return m_has_fetched_friends; } diff --git a/src/online/profile_manager.cpp b/src/online/profile_manager.cpp index 06d71a413..b349bd36f 100644 --- a/src/online/profile_manager.cpp +++ b/src/online/profile_manager.cpp @@ -38,7 +38,7 @@ ProfileManager* ProfileManager::m_profile_manager = NULL; */ ProfileManager::ProfileManager() { - m_max_cache_size = 2; + m_max_cache_size = 100; m_currently_visiting = NULL; } // ProfileManager @@ -131,6 +131,7 @@ void ProfileManager::addDirectToCache(OnlineProfile* profile) { if (!iter->second->getCacheBit()) { + updateAllFriendFlags(iter->second); delete iter->second; iter = m_profiles_cache.erase(iter); // Keep on deleting till enough space is available. @@ -163,6 +164,44 @@ bool ProfileManager::isInCache(const uint32_t id) return false; } // isInCache +// ------------------------------------------------------------------------ +/** This function is called when the specified profile id is removed from + * cache. It will search all currently cached profiles that have the + * 'friends fetched' flag set, and reset that flag if the profile id is + * one of their friends. This fixes the problem that friend lists can + * get shortened if some of their friends are being pushed out of + * cache. + */ +void ProfileManager::updateFriendFlagsInCache(const ProfilesMap &cache, + uint32_t profile_id) +{ + ProfilesMap::const_iterator i; + for(i=cache.begin(); i!=cache.end(); i++) + { + // Profile has no friends fetched, no need to test + if(!(*i).second->hasFetchedFriends()) continue; + const OnlineProfile::IDList &friend_list = (*i).second->getFriends(); + OnlineProfile::IDList::const_iterator frnd; + frnd = std::find(friend_list.begin(), friend_list.end(), profile_id); + if(frnd!=friend_list.end()) + (*i).second->unsetHasFetchedFriends(); + } +} // updateFriendFlagsInCache + +// ------------------------------------------------------------------------ +/** This function is called when the specified profile is removed from + * cache. It searches through all caches for profiles X, that have the + * given profile as friend, and then reset the 'friends fetched' flag + * in profile X. Otherwise if a profile is pushed out of the cache, + * all friends of this profile in cache will have an incomplete list + * of friends. + */ +void ProfileManager::updateAllFriendFlags(const OnlineProfile *profile) +{ + updateFriendFlagsInCache(m_profiles_persistent, profile->getID()); + updateFriendFlagsInCache(m_profiles_cache, profile->getID()); +} // updateAllFriendFlags + // ------------------------------------------------------------------------ /** This function updates the cache bits of all cached entries. It will * set the cache bit of the given profile. Then, if the cachen is full diff --git a/src/online/profile_manager.hpp b/src/online/profile_manager.hpp index 4798488f7..512f5755e 100644 --- a/src/online/profile_manager.hpp +++ b/src/online/profile_manager.hpp @@ -70,9 +70,11 @@ private: * loaded, to make sure they can be all stored). */ unsigned int m_max_cache_size; - void updateCacheBits(OnlineProfile * profile); - void addDirectToCache(OnlineProfile * profile); - + void updateCacheBits(OnlineProfile *profile); + void addDirectToCache(OnlineProfile *profile); + void updateFriendFlagsInCache(const ProfilesMap &cache, + uint32_t profile_id); + void updateAllFriendFlags(const OnlineProfile *profile); public: /** Create the singleton instance. */ static void create() From b2e6a4387ae91a84c2c2f8606e8186aab299bb96 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 7 Oct 2014 23:15:27 +1100 Subject: [PATCH 030/112] Fixed linux compilation. --- src/online/profile_manager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/online/profile_manager.cpp b/src/online/profile_manager.cpp index b349bd36f..2f160e70f 100644 --- a/src/online/profile_manager.cpp +++ b/src/online/profile_manager.cpp @@ -22,9 +22,10 @@ #include "utils/log.hpp" #include "utils/translation.hpp" +#include +#include #include #include -#include using namespace Online; From 9b57d76a796df8b2dded733329f0bd3e125a514b Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Tue, 7 Oct 2014 18:27:08 +0200 Subject: [PATCH 031/112] Check texture cache before adding an icon button's disabled texture --- src/guiengine/widgets/icon_button_widget.cpp | 40 ++++++++++++-------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index 393858ed9..d194c3630 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -289,27 +289,37 @@ const video::ITexture* IconButtonWidget::getTexture() // ----------------------------------------------------------------------------- video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* texture) { - SColor c; - u32 g; + video::ITexture* t; - video::IVideoDriver* driver = irr_driver->getVideoDriver(); - std::auto_ptr image (driver->createImageFromData (texture->getColorFormat(), - texture->getSize(), texture->lock(), false)); - texture->unlock(); - - //Turn the image into grayscale - for (u32 x = 0; x < image->getDimension().Width; x++) + std::string name = texture->getName().getPath().c_str(); + name += "_disabled"; + t = irr_driver->getTexture(name); + if (t == NULL) { - for (u32 y = 0; y < image->getDimension().Height; y++) + SColor c; + u32 g; + + video::IVideoDriver* driver = irr_driver->getVideoDriver(); + std::auto_ptr image (driver->createImageFromData (texture->getColorFormat(), + texture->getSize(), texture->lock(), false)); + texture->unlock(); + + //Turn the image into grayscale + for (u32 x = 0; x < image->getDimension().Width; x++) { - c = image->getPixel(x, y); - g = ((c.getRed() + c.getGreen() + c.getBlue()) / 3); - c.set(std::max (0, (int)c.getAlpha() - 120), g, g, g); - image->setPixel(x, y, c); + for (u32 y = 0; y < image->getDimension().Height; y++) + { + c = image->getPixel(x, y); + g = ((c.getRed() + c.getGreen() + c.getBlue()) / 3); + c.set(std::max (0, (int)c.getAlpha() - 120), g, g, g); + image->setPixel(x, y, c); + } } + + t = driver->addTexture(name.c_str(), image.get ()); } - return driver->addTexture(texture->getName().getPath() + "_disabled", image.get ()); + return t; } // ----------------------------------------------------------------------------- From 8818892bd29108a96b7720562f6b4b67d2495751 Mon Sep 17 00:00:00 2001 From: Deve Date: Tue, 7 Oct 2014 19:16:18 +0200 Subject: [PATCH 032/112] Restore saved GPs is working again. --- src/config/saved_grand_prix.cpp | 5 +++-- src/config/saved_grand_prix.hpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/config/saved_grand_prix.cpp b/src/config/saved_grand_prix.cpp index 3805457da..8f01643a6 100644 --- a/src/config/saved_grand_prix.cpp +++ b/src/config/saved_grand_prix.cpp @@ -71,7 +71,7 @@ SavedGrandPrix::SavedGrandPrix(unsigned int player_id, const std::vector &kart_list) : m_savedgp_group("SavedGP", "Represents the saved state of a GP"), - m_player_id(player_id), + m_player_id(player_id, "player_id", &m_savedgp_group), m_gp_id(gp_id.c_str(), "gp_id", &m_savedgp_group), m_difficulty((int)difficulty,"difficulty", &m_savedgp_group), m_player_karts(player_karts,"player_karts", &m_savedgp_group), @@ -94,13 +94,14 @@ SavedGrandPrix::SavedGrandPrix(unsigned int player_id, SavedGrandPrix::SavedGrandPrix(const XMLNode* node) : m_savedgp_group("SavedGP", "Represents the saved state of a GP"), - m_player_id(0), + m_player_id(0, "player_id", &m_savedgp_group), m_gp_id("-", "gp_id", &m_savedgp_group), m_difficulty(0,"difficulty", &m_savedgp_group), m_player_karts(0,"player_karts", &m_savedgp_group), m_next_track(0,"last_track", &m_savedgp_group) { //m_player_group.findYourDataInAChildOf(node); + m_player_id.findYourDataInAnAttributeOf(node); m_gp_id.findYourDataInAnAttributeOf(node); m_difficulty.findYourDataInAnAttributeOf(node); m_player_karts.findYourDataInAnAttributeOf(node); diff --git a/src/config/saved_grand_prix.hpp b/src/config/saved_grand_prix.hpp index e8aa32217..840da10c7 100644 --- a/src/config/saved_grand_prix.hpp +++ b/src/config/saved_grand_prix.hpp @@ -60,7 +60,7 @@ protected: * WARNING : m_savedgp_group has to be declared before the other userconfigparams! */ GroupUserConfigParam m_savedgp_group; - unsigned int m_player_id; + IntUserConfigParam m_player_id; /** Identifier of this GP. */ StringUserConfigParam m_gp_id; @@ -145,6 +145,7 @@ public: for (unsigned int n=0; ngetGPID() == gpid) && (gp->getPlayerID() == player) && (gp->getDifficulty() == difficulty) && From 069853b11f8e33a975888f3fba4f8c579ca11b1a Mon Sep 17 00:00:00 2001 From: Flakebi Date: Tue, 7 Oct 2014 20:54:54 +0200 Subject: [PATCH 033/112] Fix #1153 Cleanup logging code --- src/audio/sfx_openal.cpp | 6 +-- src/config/user_config.cpp | 24 +++++------- src/graphics/irr_driver.cpp | 2 +- src/guiengine/abstract_state_manager.cpp | 22 +++++------ .../abstract_top_level_container.cpp | 20 ++++------ src/guiengine/engine.cpp | 20 ++++------ src/guiengine/event_handler.cpp | 10 ++--- src/guiengine/layout_manager.cpp | 39 +++++++++---------- src/guiengine/scalable_font.cpp | 29 +++++++------- src/guiengine/screen.cpp | 4 +- src/guiengine/screen_loader.cpp | 3 +- .../widgets/dynamic_ribbon_widget.cpp | 29 +++++++------- src/guiengine/widgets/model_view_widget.cpp | 7 ++-- src/guiengine/widgets/ribbon_widget.cpp | 3 +- src/guiengine/widgets/spinner_widget.cpp | 8 ++-- src/input/device_manager.cpp | 14 +++---- src/input/input_manager.cpp | 29 +++++++------- src/network/client_network_manager.cpp | 1 + src/race/race_manager.cpp | 11 +++--- src/states_screens/addons_screen.cpp | 3 +- src/states_screens/arenas_screen.cpp | 2 +- .../dialogs/confirm_resolution_dialog.cpp | 2 +- src/states_screens/easter_egg_screen.cpp | 3 +- src/states_screens/feature_unlocked.cpp | 19 ++++----- src/states_screens/options_screen_audio.cpp | 2 +- src/states_screens/options_screen_input.cpp | 8 ++-- src/states_screens/options_screen_input2.cpp | 33 +++++++--------- src/states_screens/options_screen_video.cpp | 12 ++---- src/states_screens/race_gui_overworld.cpp | 4 +- src/utils/translation.cpp | 20 +++++----- 30 files changed, 177 insertions(+), 212 deletions(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 83c503ca6..c80002b14 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -85,10 +85,8 @@ bool SFXOpenAL::init() assert( alIsBuffer(m_soundBuffer->getBufferID()) ); assert( alIsSource(m_soundSource) ); - //std::cout << "Setting a source with buffer " << m_soundBuffer - // << ", rolloff " << rolloff - // << ", gain=" << m_defaultGain << ", positional=" - // << (positional ? "true" : "false") << std::endl; + //Log::info("SFXOpenAL", "Setting a source with buffer, %p, rolloff %f, gain = %f, position = %s", + // m_soundBuffer, rolloff, m_defaultGain, positional ? "true" : "false"); alSourcei (m_soundSource, AL_BUFFER, m_soundBuffer->getBufferID()); diff --git a/src/config/user_config.cpp b/src/config/user_config.cpp index fb5c742aa..a6c8b1988 100644 --- a/src/config/user_config.cpp +++ b/src/config/user_config.cpp @@ -140,8 +140,7 @@ void GroupUserConfigParam::findYourDataInAChildOf(const XMLNode* node) const XMLNode* child = node->getNode( m_param_name ); if (child == NULL) { - //std::cerr << "/!\\ User Config : Couldn't find parameter group " - // << paramName << std::endl; + //Log::error("User Config", "Couldn't find parameter group %s", m_param_name.c_str()); return; } @@ -271,8 +270,7 @@ void ListUserConfigParam::findYourDataInAChildOf(const XMLNode* node) const XMLNode* child = node->getNode( m_param_name ); if (child == NULL) { - //std::cerr << "/!\\ User Config : Couldn't find parameter group " - // << paramName << std::endl; + //Log::error("User Config", "Couldn't find parameter group %s", m_param_name.c_str()); return; } @@ -374,12 +372,12 @@ void IntUserConfigParam::findYourDataInAChildOf(const XMLNode* node) const XMLNode* child = node->getNode( m_param_name ); if(child == NULL) { - //std::cout << "Couldn't find int parameter " << paramName << std::endl; + //Log::error("UserConfigParam", "Couldn't find int parameter %s", m_param_name.c_str()); return; } child->get( "value", &m_value ); - //std::cout << "read int " << paramName << ", value=" << value << std::endl; + //Log::info("UserConfigParam", "Read int %s ,value = %d", m_param_name.c_str(), value); } // findYourDataInAChildOf // ---------------------------------------------------------------------------- @@ -442,7 +440,7 @@ void TimeUserConfigParam::findYourDataInAChildOf(const XMLNode* node) const XMLNode* child = node->getNode( m_param_name ); if(child == NULL) { - //std::cout << "Couldn't find int parameter " << paramName <& mesh, node->setAnimationSpeed(0); node->updateAbsolutePosition(); node->setScale( mesh_scale[n].toIrrVector() ); - //std::cout << "(((( set frame " << model_frames[n] << " ))))\n"; + //Log::info("RTTProvider::setupRTTScene", "Set frame %d", model_frames[n]); } } diff --git a/src/guiengine/abstract_state_manager.cpp b/src/guiengine/abstract_state_manager.cpp index bafed2a3a..ae9f1a2ed 100644 --- a/src/guiengine/abstract_state_manager.cpp +++ b/src/guiengine/abstract_state_manager.cpp @@ -93,8 +93,8 @@ void AbstractStateManager::pushMenu(std::string name) if (UserConfigParams::logGUI()) { - std::cout << "[AbstractStateManager::pushMenu] switching to screen " - << name.c_str() << std::endl; + Log::info("AbstractStateManager::pushMenu", "Switching to screen %s", + name.c_str()); } // Send tear-down event to previous menu @@ -125,8 +125,8 @@ void AbstractStateManager::pushScreen(Screen* screen) if (UserConfigParams::logGUI()) { - std::cout << "[AbstractStateManager::pushScreen] switching to screen " - << screen->getName().c_str() << std::endl; + Log::info("AbstractStateManager::pushScreen", "Switching to screen %s", + screen->getName().c_str()); } if (!screen->isLoaded()) screen->loadFromFile(); @@ -152,8 +152,8 @@ void AbstractStateManager::replaceTopMostScreen(Screen* screen, GUIEngine::GameS if (UserConfigParams::logGUI()) { - std::cout << "[AbstractStateManager::replaceTopmostScreen] " - "switching to screen " << name.c_str() << std::endl; + Log::info("AbstractStateManager::replaceTopMostScreen", "Switching to screen %s", + name.c_str()); } assert(m_menu_stack.size() > 0); @@ -215,8 +215,8 @@ void AbstractStateManager::popMenu() if (UserConfigParams::logGUI()) { - std::cout << "[AbstractStateManager::popMenu] switching to screen " - << m_menu_stack[m_menu_stack.size()-1].c_str() << std::endl; + Log::info("AbstractStateManager::popMenu", "Switching to screen %s", + m_menu_stack[m_menu_stack.size()-1].c_str()); } if (m_menu_stack[m_menu_stack.size()-1] == RACE_STATE_NAME) @@ -247,10 +247,8 @@ void AbstractStateManager::resetAndGoToScreen(Screen* screen) std::string name = screen->getName(); if (UserConfigParams::logGUI()) - { - std::cout << "[AbstractStateManager::resetAndGoToScreen] " - "switching to screen " << name.c_str() << std::endl; - } + Log::info("AbstractStateManager::resetAndGoToScreen", "Switching to screen %s", + name.c_str()); if (m_game_mode != GAME) getCurrentScreen()->tearDown(); m_menu_stack.clear(); diff --git a/src/guiengine/abstract_top_level_container.cpp b/src/guiengine/abstract_top_level_container.cpp index 7b2889b60..332a45b40 100644 --- a/src/guiengine/abstract_top_level_container.cpp +++ b/src/guiengine/abstract_top_level_container.cpp @@ -72,18 +72,16 @@ void AbstractTopLevelContainer::addWidgetsRecursively( widgets[n].getType() != WTYPE_ICON_BUTTON && widgets[n].getType() != WTYPE_SPACER) { - std::cerr << "/!\\ Warning /!\\ : widget " - << widgets[n].m_properties[PROP_ID].c_str() - << " of type " << widgets[n].getType() - << " has no dimensions" << std::endl; + Log::warn("AbstractTopLevelContainer::addWidgetsRecursively", + "Widget %s of type %d has no dimensions", + widgets[n].m_properties[PROP_ID].c_str(), widgets[n].getType()); } if (widgets[n].m_x == -1 || widgets[n].m_y == -1) { - std::cerr << "/!\\ Warning /!\\ : widget " - << widgets[n].m_properties[PROP_ID].c_str() - << " of type " << widgets[n].getType() - << " has no position" << std::endl; + Log::warn("AbstractTopLevelContainer::addWidgetsRecursively", + "Widget %s of type %d has no position", + widgets[n].m_properties[PROP_ID].c_str(), widgets[n].getType()); } widgets[n].add(); @@ -197,10 +195,8 @@ Widget* AbstractTopLevelContainer::getWidget(const int id, if (widget.searchInsideMe() && widget.getChildren().size() > 0) { - // std::cout << "widget = <" - // << widget.m_properties[PROP_ID].c_str() - // << "> widget.m_children.size()=" - // << widget.m_children.size() << std::endl; + //Log::info("AbstractTopLevelContainer", "widget = <%s> widget.m_children.size() = ", + // widget.m_properties[PROP_ID].c_str(), widget.m_children.size()); Widget* el = getWidget(id, &(widget.m_children)); if(el != NULL) return el; } diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index f52acefc2..c31366b03 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -1019,12 +1019,10 @@ namespace GUIEngine g_skin->drop(); // GUI env grabbed it assert(g_skin->getReferenceCount() == 1); } - catch (std::runtime_error& err) + catch (std::runtime_error& /*err*/) { - (void)err; // avoid warning about unused variable - std::cerr << - "ERROR, cannot load skin specified in user config. Falling " - "back to defaults.\n"; + Log::error("Engine::init", "Cannot load skin specified in user config. " + "Falling back to defaults."); UserConfigParams::m_skin_file.revertToDefaults(); try @@ -1036,8 +1034,7 @@ namespace GUIEngine } catch (std::runtime_error& err) { - std::cerr << "FATAL, cannot load default GUI skin\n"; - throw err; + Log::fatal("Engine::init", "Canot load default GUI skin"); } } @@ -1135,10 +1132,9 @@ namespace GUIEngine // one so that the fallback skin is not dropped newSkin = new Skin(fallbackSkin); } - catch (std::runtime_error& err) + catch (std::runtime_error& /*err*/) { - (void)err; // avoid warning about unused variable - std::cerr << "ERROR, cannot load newly specified skin!\n"; + Log::error("Engine::reloadSkin", "Canot load newly specified skin"); return; } @@ -1369,8 +1365,8 @@ namespace GUIEngine } else { - std::cerr << "WARNING: GUIEngine::addLoadingIcon given " - "NULL icon\n"; + Log::warn("Engine::addLoadingIcon", "Given " + "NULL icon"); } } // addLoadingIcon diff --git a/src/guiengine/event_handler.cpp b/src/guiengine/event_handler.cpp index 3546473e5..59b174607 100644 --- a/src/guiengine/event_handler.cpp +++ b/src/guiengine/event_handler.cpp @@ -199,7 +199,7 @@ bool EventHandler::OnEvent (const SEvent &event) // mode ignore this error message, but leave it in for debugging. if(std::string(event.LogEvent.Text)=="Unsupported texture format") #ifdef DEBUG - printf("The following message will not be printed in release mode:\n"); + Log::info("EventHandler", "The following message will not be printed in release mode"); #else return true; // EVENT_BLOCK #endif @@ -414,7 +414,7 @@ void EventHandler::navigate(const int playerID, Input::InputType type, const boo if (el == NULL) { - std::cerr << "WARNING : m_tab_down/up_root is set to an ID for which I can't find the widget\n"; + Log::warn("EventHandler::navigate", "m_tab_down/up_root is set to an ID for which I can't find the widget"); return; } } @@ -448,7 +448,7 @@ void EventHandler::navigate(const int playerID, Input::InputType type, const boo if (NAVIGATION_DEBUG) { - std::cout << "Navigating " << (reverse ? "up" : "down") << " to " << closest->getID() << std::endl; + Log::info("EventHandler", "Navigating %s to %d", (reverse ? "up" : "down"), closest->getID()); } assert(closestWidget != NULL); @@ -474,7 +474,7 @@ void EventHandler::navigate(const int playerID, Input::InputType type, const boo if (!found) { if (NAVIGATION_DEBUG) - std::cout << "EventHandler::navigat : wrap around\n"; + Log::info( "EventHandler::navigate", "Wrap around"); // select the last/first widget Widget* wrapWidget = NULL; @@ -529,7 +529,7 @@ EventPropagation EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int if (w->m_event_handler == NULL) return EVENT_LET; } - //std::cout << "**** widget activated : " << w->m_properties[PROP_ID].c_str() << " ****" << std::endl; + //Log::info("EventHandler", "Widget activated: %s", w->m_properties[PROP_ID].c_str()); if (w->m_event_handler != NULL) { diff --git a/src/guiengine/layout_manager.cpp b/src/guiengine/layout_manager.cpp index 268d45605..887108c13 100644 --- a/src/guiengine/layout_manager.cpp +++ b/src/guiengine/layout_manager.cpp @@ -21,9 +21,6 @@ #include #include -using namespace irr; -using namespace gui; -using namespace video; #include "graphics/irr_driver.hpp" #include "guiengine/abstract_top_level_container.hpp" @@ -35,6 +32,9 @@ using namespace video; #include "utils/string_utils.hpp" #include "utils/vs.hpp" +using namespace irr; +using namespace gui; +using namespace video; using namespace GUIEngine; /** Like atoi, but on error prints an error message to stderr */ @@ -420,7 +420,7 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev horizontal = false; else { - std::cerr << "Unknown layout name : " << layout_name.c_str() << std::endl; + Log::error("LayoutManager::doCalculateLayout", "Unknown layout name: %s", layout_name.c_str()); break; } @@ -475,11 +475,9 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev int proportion = 1; std::istringstream myStream(prop); if (!(myStream >> proportion)) - { - std::cerr << "/!\\ Warning /!\\ : proportion '" << prop.c_str() - << "' is not a number for widget " << widgets[n].m_properties[PROP_ID].c_str() - << std::endl; - } + Log::warn("LayoutManager::doCalculateLayout", + "Proportion '%s' is not a number for widget %s", prop.c_str(), + widgets[n].m_properties[PROP_ID].c_str()); const float fraction = (float)proportion/(float)total_proportion; @@ -522,9 +520,9 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev } else { - std::cerr << "/!\\ Warning /!\\ : alignment '" << align.c_str() - << "' is unknown (widget '" << widgets[n].m_properties[PROP_ID].c_str() - << "', in a horiozntal-row layout)\n"; + Log::warn("LayoutManager::doCalculateLayout", + "Alignment '%s' is unknown (widget '%s', in a horiozntal-row layout)", + align.c_str(), widgets[n].m_properties[PROP_ID].c_str()); } widgets[n].m_w = (int)(left_space*fraction); @@ -597,9 +595,9 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev } else { - std::cerr << "/!\\ Warning /!\\ : alignment '" << align.c_str() - << "' is unknown (widget '" << widgets[n].m_properties[PROP_ID].c_str() - << "', in a vertical-row layout)\n"; + Log::warn("LayoutManager::doCalculateLayout", + "Alignment '%s' is unknown (widget '%s', in a vertical-row layout)", + align.c_str(), widgets[n].m_properties[PROP_ID].c_str()); } widgets[n].m_y = y; @@ -651,9 +649,9 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev } else { - std::cerr << "/!\\ Warning /!\\ : alignment '" << align.c_str() - << "' is unknown in widget " << widgets[n].m_properties[PROP_ID].c_str() - << std::endl; + Log::warn("LayoutManager::doCalculateLayout", + "Alignment '%s' is unknown in widget '%s'", + align.c_str(), widgets[n].m_properties[PROP_ID].c_str()); } x += widgets[n].m_w; @@ -697,8 +695,9 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev } else { - std::cerr << "/!\\ Warning /!\\ : alignment '" << align.c_str() - << "' is unknown in widget " << widgets[n].m_properties[PROP_ID].c_str() << std::endl; + Log::warn("LayoutManager::doCalculateLayout", + "Alignment '%s' is unknown in widget '%s'", + align.c_str(), widgets[n].m_properties[PROP_ID].c_str()); } widgets[n].m_y = y; diff --git a/src/guiengine/scalable_font.cpp b/src/guiengine/scalable_font.cpp index ebbcaf82d..41484cd62 100644 --- a/src/guiengine/scalable_font.cpp +++ b/src/guiengine/scalable_font.cpp @@ -101,7 +101,7 @@ void ScalableFont::doReadXmlFile(io::IXMLReader* xml) /* const wchar_t* iflangis = xml->getAttributeValue(L"iflanguage"); - printf("langcode = %s\n", translations->getCurrentLanguageCode().c_str()); + Log::info("ScalableFont", "langcode = %s", translations->getCurrentLanguageCode().c_str()); if (iflangis != NULL && core::stringc(iflangis) != translations->getCurrentLanguageCode().c_str()) @@ -128,8 +128,10 @@ void ScalableFont::doReadXmlFile(io::IXMLReader* xml) float scale=1.0f; if(xml->getAttributeValue(L"scale")) + { scale = xml->getAttributeValueAsFloat(L"scale"); - //std::cout << "scale = " << scale << std::endl; + //Log::info("ScalableFont", "scale = %f", scale); + } bool excludeFromMaxHeightCalculation = false; if (xml->getAttributeValue(L"excludeFromMaxHeightCalculation")) @@ -137,7 +139,7 @@ void ScalableFont::doReadXmlFile(io::IXMLReader* xml) core::stringw alpha = xml->getAttributeValue(L"hasAlpha"); - //std::cout << "---- Adding font texture " << fn.c_str() << "; alpha=" << alpha.c_str() << std::endl; + //Log::info("ScalableFont", "Adding font texture %s; alpha = %s", fn.c_str(), alpha.c_str()); // make sure the sprite bank has enough textures in it @@ -227,7 +229,7 @@ void ScalableFont::doReadXmlFile(io::IXMLReader* xml) CharacterMap[ch] = Areas.size(); - //std::cout << "Inserting character '" << (int)ch << "' with area " << Areas.size() << std::endl; + //Log::info("ScalableFont", "Inserting character '%d' with area %d", (int)ch, Areas.size()); // make frame f.rectNumber = SpriteBank->getPositions().size(); @@ -366,18 +368,18 @@ s32 ScalableFont::getAreaIDFromCharacter(const wchar_t c, bool* fallback_font) c if (n != CharacterMap.end()) { if (fallback_font != NULL) *fallback_font = false; - // std::cout << "Character " << (int)c << " found in font\n"; + //Log::info("ScalableFont", "Character %d found in font", (int)c); return (*n).second; } else if (m_fallback_font != NULL && fallback_font != NULL) { - // std::cout << "Font does not have this character : <" << (int)c << ">, trying fallback font" << std::endl; + //Log::warn("ScalableFont", "Font does not have this character: <%d>, try fallback font", (int)c); *fallback_font = true; return m_fallback_font->getAreaIDFromCharacter(c, NULL); } else { - // std::cout << "The font does not have this character : <" << (int)c << ">" << std::endl; + //Log::warn("ScalableFont", "The font does not have this character: <%d>", (int)c); if (fallback_font != NULL) *fallback_font = false; return WrongCharacter; } @@ -453,12 +455,12 @@ core::dimension2d ScalableFont::getDimension(const wchar_t* text) const dim.Height += thisLine.Height; if (dim.Width < thisLine.Width) dim.Width = thisLine.Width; - // std::cout << "ScalableFont::getDimension returns : " << dim.Width << ", " << dim.Height << " --> "; + //Log::info("ScalableFont", "ScalableFont::getDimension returns: %d, %d", dim.Width, dim.Height); dim.Width = (int)(dim.Width + 0.9f); // round up dim.Height = (int)(dim.Height + 0.9f); - //std::cout << dim.Width << ", " << dim.Height << std::endl; + //Log::info("ScalableFont", "After: %d, %d", dim.Width, dim.Height); return dim; } @@ -616,10 +618,9 @@ void ScalableFont::doDraw(const core::stringw& text, /* if (fallback[n]) { - std::cout << "USING fallback font " << core::stringc(texture->getName()).c_str() - << "; source area is " << source.UpperLeftCorner.X << ", " << source.UpperLeftCorner.Y - << ", size " << source.getWidth() << ", " << source.getHeight() << "; dest = " - << offsets[n].X << ", " << offsets[n].Y << std::endl; + Log::info("ScalableFont", "Using fallback font %s; source area is %d, %d; size %d, %d; dest = %d, %d", + core::stringc(texture->getName()).c_str(), source.UpperLeftCorner.X, source.UpperLeftCorner.Y, + source.getWidth(), source.getHeight(), offsets[n].X, offsets[n].Y); } */ @@ -773,7 +774,7 @@ int ScalableFont::getCharWidth(const SFontArea& area, const bool fallback) const assert(info.m_file_name.size() > 0); const float char_scale = info.m_scale; - //std::cout << "area.spriteno=" << area.spriteno << ", char_scale=" << char_scale << std::endl; + //Log::info("ScalableFont", "area.spriteno = %d, char_scale = %f", area.spriteno, char_scale); if (fallback) return (int)(((area.width + area.overhang)*m_fallback_font_scale + m_fallback_kerning_width) * m_scale * char_scale); else return (int)((area.width + area.overhang + GlobalKerningWidth) * m_scale * char_scale); diff --git a/src/guiengine/screen.cpp b/src/guiengine/screen.cpp index 947fa8549..29706ee0e 100644 --- a/src/guiengine/screen.cpp +++ b/src/guiengine/screen.cpp @@ -187,11 +187,11 @@ void Screen::addWidgets() addWidgetsRecursively( m_widgets ); - //std::cout << "*****ScreenAddWidgets " << m_filename.c_str() << " : focusing the first widget*****\n"; + //Log::info("Screen::AddWidgets", "%s: focusing the first widget", m_filename.c_str()); // select the first widget (for first players only; if other players need some focus the Screen must provide it). Widget* w = getFirstWidget(); - //std::cout << "First widget is " << (w == NULL ? "null" : w->m_properties[PROP_ID].c_str()) << std::endl; + //Log::info("Screen::AddWidgets", "First widget is %s", (w == NULL ? "null" : w->m_properties[PROP_ID].c_str())); if (w != NULL) w->setFocusForPlayer( PLAYER_ID_GAME_MASTER ); else Log::warn("Screen::AddWidgets", "Couldn't select first widget, NULL was returned"); } // addWidgets diff --git a/src/guiengine/screen_loader.cpp b/src/guiengine/screen_loader.cpp index e6c5f0c2a..21feaa763 100644 --- a/src/guiengine/screen_loader.cpp +++ b/src/guiengine/screen_loader.cpp @@ -181,8 +181,7 @@ void Screen::parseScreenFileDiv(irr::io::IXMLReader* xml, PtrVector& app } else { - std::cerr << "/!\\ Warning /!\\ : unknown tag found in STK GUI file : '" - << xml->getNodeName() << "'" << std::endl; + Log::warn("Screen::parseScreenFileDiv", "unknown tag found in STK GUI file '%s'", xml->getNodeName()); continue; } diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index a00b2762b..9095da0eb 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -258,9 +258,9 @@ void DynamicRibbonWidget::add() const float score = log(2.0f*visible_items) * std::min(ratio, 1.0f) * std::min(taken_area/total_area, 1.0f); - //std::cout << " " << row_count << " rows : " << visible_items << " visible items; area = " - // << taken_area << "; size penalty = " << std::min((float)item_height / (float)m_child_height, 1.0f) - // << "; score = " << score << "\n"; + //Log::info("DynamicRibbonWidget", "%d rown: %d visible items; area = %f; " + // "size penalty = %f; score = %f", row_count, visible_items, taken_area, + // std::min((float)item_height / (float)m_child_height, 1.0f), score); if (score > max_score_so_far) { @@ -276,8 +276,8 @@ void DynamicRibbonWidget::add() const int max_rows = atoi(m_properties[PROP_MAX_ROWS].c_str()); if (max_rows < 1) { - std::cout << "/!\\ WARNING : the 'max_rows' property must be an integer greater than zero." - << " Ingoring current value '" << m_properties[PROP_MAX_ROWS] << "'\n"; + Log::warn("DynamicRibbonWidget", "The 'max_rows' property must be an integer greater than zero; " + "Ignoring current value '%s'", m_properties[PROP_MAX_ROWS].c_str()); } else { @@ -300,7 +300,7 @@ void DynamicRibbonWidget::add() for (int i=0; i item_count) { m_col_amount = (int)ceil((float)item_count/(float)m_row_amount); - //std::cout << "Adjusting m_col_amount to be " << m_col_amount << std::endl; + //Log::info("DynamicRibbonWidget", "Adjusting m_col_amount to be %d", m_col_amount); } assert( m_left_widget->ok() ); @@ -411,7 +411,7 @@ void DynamicRibbonWidget::buildInternalStructure() // it will assume there is no label and none will be created (FIXME: that's ugly) if (m_properties[PROP_LABELS_LOCATION] == "each") icon->m_text = " "; - // std::cout << "ribbon text = " << m_properties[PROP_TEXT].c_str() << std::endl; + //Log::info("DynamicRibbonWidget", "Ribbon text = %s", m_properties[PROP_TEXT].c_str()); ribbon->m_children.push_back( icon ); added_item_count++; @@ -612,12 +612,12 @@ EventPropagation DynamicRibbonWidget::rightPressed(const int playerID) getSelectedRibbon(playerID)->getSelectionText(playerID), playerID); } } - //std::cout << "rightpressed (dynamic ribbon) " << m_properties[PROP_ID] << "\n"; + //Log::info("DynamicRibbonWidget", "Rightpressed %s", m_properties[PROP_ID].c_str()); assert(m_rows.size() >= 1); if (m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return EVENT_BLOCK; - //std::cout << " rightpressed returning EVENT_LET\n"; + //Log::info("DynamicRibbonWidget", "Rightpressed returning EVENT_LET"); return EVENT_LET; } @@ -682,7 +682,7 @@ EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w, EventPropagation DynamicRibbonWidget::mouseHovered(Widget* child, const int playerID) { if (m_deactivated) return EVENT_LET; - //std::cout << "DynamicRibbonWidget::mouseHovered " << playerID << std::endl; + //Log::info("DynamicRibbonWidget", "mouseHovered %d", playerID); updateLabel(); propagateSelection(); @@ -1085,15 +1085,14 @@ bool DynamicRibbonWidget::setSelection(int item_id, const int playerID, if (iterations > 50) { - assert(false); - std::cerr << "DynamicRibbonWidget::setSelection cannot find item " << item_id << " (" << name.c_str() << ")\n"; + Log::fatal("DynamicRibbonWidget::setSelection", "Cannot find item %d (%s)", item_id, name.c_str()); return false; } iterations++; } - //std::cout << "Player " << playerID << " has item " << item_id << " (" << name.c_str() << ") in row " << row << std::endl; + //Log::info("DynamicRibbonWidget", "Player %d has item %d (%s) in row %d", playerID, item_id, name.c_str(), row); m_rows[row].setSelection(id, playerID); if (focusIt) { diff --git a/src/guiengine/widgets/model_view_widget.cpp b/src/guiengine/widgets/model_view_widget.cpp index 031de875e..05357c574 100644 --- a/src/guiengine/widgets/model_view_widget.cpp +++ b/src/guiengine/widgets/model_view_widget.cpp @@ -136,8 +136,9 @@ void ModelViewWidget::update(float delta) distance_with_negative_rotation = (int)(angle - m_rotation_target); } - //std::cout << "distance_with_positive_rotation=" << distance_with_positive_rotation << - //" distance_with_negative_rotation=" << distance_with_negative_rotation << " angle="<< angle <& mesh, node->setAnimationSpeed(0); node->updateAbsolutePosition(); node->setScale(mesh_scale[n].toIrrVector()); - //std::cout << "(((( set frame " << model_frames[n] << " ))))\n"; + //Log::info("ModelViewWidget", "Set frame %d", model_frames[n]); } } diff --git a/src/guiengine/widgets/ribbon_widget.cpp b/src/guiengine/widgets/ribbon_widget.cpp index 78e2b95d1..3f4557fbe 100644 --- a/src/guiengine/widgets/ribbon_widget.cpp +++ b/src/guiengine/widgets/ribbon_widget.cpp @@ -594,7 +594,7 @@ EventPropagation RibbonWidget::mouseHovered(Widget* child, if (m_ribbon_type == RIBBON_COMBO || m_ribbon_type == RIBBON_TABS) { - //std::cout << "SETTING m_mouse_focus\n"; + //Log::info("RibbonWidget", "Setting m_mouse_focus"); m_mouse_focus = child; } @@ -642,7 +642,6 @@ void RibbonWidget::updateSelection() // FIXME: m_selection, m_selected, m_mouse_focus... what a mess... - //std::cout << "----\n"; // Update selection flags for mouse player for (unsigned int p=0; p= m_min) { setValue(m_value-1); @@ -386,9 +386,7 @@ void SpinnerWidget::setValue(irr::core::stringw new_value) } } - std::cerr << "ERROR [SpinnerWidget::setValue] : cannot find element named '" - << irr::core::stringc(new_value.c_str()).c_str() << "'\n"; - assert(false); + Log::fatal("SpinnerWidget::setValue", "Cannot find element named '%s'", irr::core::stringc(new_value.c_str()).c_str()); } // ----------------------------------------------------------------------------- diff --git a/src/input/device_manager.cpp b/src/input/device_manager.cpp index c82a02068..f7893506c 100644 --- a/src/input/device_manager.cpp +++ b/src/input/device_manager.cpp @@ -145,9 +145,9 @@ void DeviceManager::setAssignMode(const PlayerAssignMode assignMode) m_assign_mode = assignMode; #if INPUT_MODE_DEBUG - if (assignMode == NO_ASSIGN) std::cout << "====== DeviceManager::setAssignMode(NO_ASSIGN) ======\n"; - if (assignMode == ASSIGN) std::cout << "====== DeviceManager::setAssignMode(ASSIGN) ======\n"; - if (assignMode == DETECT_NEW) std::cout << "====== DeviceManager::setAssignMode(DETECT_NEW) ======\n"; + if (assignMode == NO_ASSIGN) Log::info("DeviceManager::setAssignMode", "NO_ASSIGN); + if (assignMode == ASSIGN) Log::info("DeviceManager::setAssignMode", "ASSIGN); + if (assignMode == DETECT_NEW) Log::info("DeviceManager::setAssignMode", "DETECT_NEW); #endif // when going back to no-assign mode, do some cleanup @@ -289,7 +289,7 @@ InputDevice* DeviceManager::mapKeyboardInput( int btnID, InputManager::InputDriv { const int keyboard_amount = m_keyboards.size(); - //std::cout << "mapKeyboardInput " << btnID << " to " << keyboard_amount << " keyboards\n"; + //Log::info("DeviceManager::mapKeyboardInput", "Map %d to %d", btnID, keyboard_amount); for (int n=0; nprocessAndMapInput(btnID, mode, action)) { - //std::cout << " binding found in keyboard #" << (n+1) << "; action is " << KartActionStrings[*action] << "\n"; + //Log::info("DeviceManager::mapKeyboardInput", "Binding found in keyboard #%d; action is %s", n + 1, KartActionStrings[*action]); if (m_single_player != NULL) { - //printf("Single player\n"); + //Log::info("DeviceManager", "Single player"); *player = m_single_player; } else if (m_assign_mode == NO_ASSIGN) // Don't set the player in NO_ASSIGN mode @@ -423,7 +423,7 @@ InputDevice* DeviceManager::getLatestUsedDevice() if (m_latest_used_device == NULL) { - //std::cout<< "========== No latest device, returning keyboard ==========\n"; + //Log::info("DeviceManager", "No latest device, returning keyboard); return m_keyboards.get(0); // FIXME: is this right? } diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index 559bf71cd..e5c1d814a 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -298,7 +298,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int value) { #if INPUT_MODE_DEBUG - std::cout << "INPUT SENSING... "; + Log::info("InputManager::inputSensing", "Start sensing input"); #endif // don't store if we're trying to do something like bindings keyboard @@ -310,7 +310,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, return; #if INPUT_MODE_DEBUG - std::cout << (store_new ? "storing it" : "ignoring it") << "\n"; + Log::info("InputManager::inputSensing", store_new ? "storing it" : "ignoring it"); #endif @@ -350,10 +350,9 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, break; case Input::IT_STICKMOTION: { - std::cout << "%% storing new axis binding, value=" << value << - " deviceID=" << deviceID << " button=" << button << - " axisDirection=" << - (axisDirection == Input::AD_NEGATIVE ? "-" : "+") << "\n"; + Log::info("InputManager::inputSensing", "Storing new axis binding, value = %d; " + "deviceID = %d; button = %d; axisDirection = %s", value, deviceID, button, + axisDirection == Input::AD_NEGATIVE ? "-" : "+"); // We have to save the direction in which the axis was moved. // This is done by storing it as a sign (and since button can // be zero, we add one before changing the sign). @@ -573,8 +572,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID, InputDevice *device = NULL; if (type == Input::IT_KEYBOARD) { - //std::cout << "==== New Player Joining with Key " << - // button << " ====" << std::endl; + //Log::info("InputManager", "New Player Joining with Key %d", button); device = m_device_manager->getKeyboardFromBtnID(button); } else if (type == Input::IT_STICKBUTTON || @@ -609,8 +607,8 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID, if (pk == NULL) { - std::cerr << - "Error, trying to process action for an unknown player\n"; + Log::error("InputManager::dispatchInput", "Trying to process " + "action for an unknown player"); return; } @@ -700,8 +698,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID, void InputManager::setMasterPlayerOnly(bool enabled) { #if INPUT_MODE_DEBUG - std::cout << - "====== InputManager::setMasterPlayerOnly(" << enabled << ") ======\n"; + Log::info("InputManager::setMasterPlayerOnly", enabled ? "enabled" : "disabled"); #endif m_master_player_only = enabled; } @@ -955,7 +952,7 @@ void InputManager::setMode(InputDriverMode new_mode) { case MENU: #if INPUT_MODE_DEBUG - std::cout << "====== InputManager::setMode(MENU) ======\n"; + Log::info("InputManager::setMode", "MENU"); #endif switch (m_mode) { @@ -1017,7 +1014,7 @@ void InputManager::setMode(InputDriverMode new_mode) break; case INGAME: #if INPUT_MODE_DEBUG - std::cout << "====== InputManager::setMode(INGAME) ======\n"; + Log::info("InputManager::setMode", "INGAME"); #endif // We must be in menu mode now in order to switch. assert (m_mode == MENU); @@ -1036,7 +1033,7 @@ void InputManager::setMode(InputDriverMode new_mode) case INPUT_SENSE_KEYBOARD: case INPUT_SENSE_GAMEPAD: #if INPUT_MODE_DEBUG - std::cout << "====== InputManager::setMode(INPUT_SENSE_*) ======\n"; + Log::info("InputManager::setMode", "INPUT_SENSE_*"); #endif // We must be in menu mode now in order to switch. assert (m_mode == MENU); @@ -1050,7 +1047,7 @@ void InputManager::setMode(InputDriverMode new_mode) /* case LOWLEVEL: #if INPUT_MODE_DEBUG - std::cout << "====== InputManager::setMode(LOWLEVEL) ======\n"; + Log::info("InputManager::setMode", "LOWLEVEL"); #endif // We must be in menu mode now in order to switch. assert (m_mode == MENU); diff --git a/src/network/client_network_manager.cpp b/src/network/client_network_manager.cpp index 9968dd8b5..00f672484 100644 --- a/src/network/client_network_manager.cpp +++ b/src/network/client_network_manager.cpp @@ -94,6 +94,7 @@ void* waitInput(void* data) std::cin >> cnt; clrp->voteRaceCount(cnt); } + std::cout << "\n"; } // If STK shuts down, but should receive an input after the network // manager was deleted, the getInstance call will return NULL. diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index e49592125..539466de3 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -126,7 +126,7 @@ void RaceManager::setDefaultAIKartList(const std::vector& ai_list) // player (and therefore the current slot) is not defined yet. //if(unlock_manager->getCurrentSlot()->isLocked(name)) //{ - // printf("Kart '%s' is locked and therefore ignored.\n", + // Log::info("RaceManager", "Kart '%s' is locked and therefore ignored.", // name.c_str()); // continue; //} @@ -240,9 +240,8 @@ void RaceManager::computeRandomKartList() { int n = m_num_karts - (int)m_player_karts.size(); if(UserConfigParams::logMisc()) - std::cout << "AI karts count = " << n << " for m_num_karts=" - << m_num_karts << " and m_player_karts.size()=" - << m_player_karts.size() << std::endl; + Log::info("RaceManager", "AI karts count = %d for m_num_karts = %d and " + "m_player_karts.size() = %d", n, m_num_karts, m_player_karts.size()); // If less kart selected than there are player karts, adjust the number of // karts to the minimum @@ -655,8 +654,8 @@ void RaceManager::exitRace(bool delete_world) { if(UserConfigParams::logMisc()) { - std::cout << m_kart_status[i].m_ident << " has GP final rank " - << m_kart_status[i].m_gp_rank << std::endl; + Log::info("RaceManager", "%s has GP final rank %d", + m_kart_status[i].m_ident.c_str(), m_kart_status[i].m_gp_rank); } const int rank = m_kart_status[i].m_gp_rank; diff --git a/src/states_screens/addons_screen.cpp b/src/states_screens/addons_screen.cpp index 09cee199d..dd603b214 100644 --- a/src/states_screens/addons_screen.cpp +++ b/src/states_screens/addons_screen.cpp @@ -146,8 +146,7 @@ void AddonsScreen::init() getWidget("category")->setDeactivated(); if(UserConfigParams::logAddons()) - std::cout << "[addons] Using directory <" + file_manager->getAddonsDir() - << ">\n"; + Log::info("addons", "Using directory <%s>", file_manager->getAddonsDir().c_str()); GUIEngine::ListWidget* w_list = getWidget("list_addons"); diff --git a/src/states_screens/arenas_screen.cpp b/src/states_screens/arenas_screen.cpp index 113dead69..10a3dc412 100644 --- a/src/states_screens/arenas_screen.cpp +++ b/src/states_screens/arenas_screen.cpp @@ -133,7 +133,7 @@ void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const const std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER); if (UserConfigParams::logGUI()) - std::cout << "Clicked on arena " << selection.c_str() << std::endl; + Log::info("ArenasScreen", "Clicked on arena %s", selection.c_str()); if (selection == "random_track") diff --git a/src/states_screens/dialogs/confirm_resolution_dialog.cpp b/src/states_screens/dialogs/confirm_resolution_dialog.cpp index c4c1896ab..591dcd815 100644 --- a/src/states_screens/dialogs/confirm_resolution_dialog.cpp +++ b/src/states_screens/dialogs/confirm_resolution_dialog.cpp @@ -79,7 +79,7 @@ void ConfirmResolutionDialog::updateMessage() { //I18N: In the 'confirm resolution' dialog, that's shown when switching resoluton stringw msg = _("Confirm resolution within %i seconds", (int)m_remaining_time); - //std::cout << stringc(msg.c_str()).c_str() << std::endl; + //Log::info("ConfirmResolutionDialog", "stringc(msg.c_str()).c_str()); LabelWidget* countdown_message = getWidget("title"); countdown_message->setText( msg.c_str(), false ); diff --git a/src/states_screens/easter_egg_screen.cpp b/src/states_screens/easter_egg_screen.cpp index 89bdb527f..2a593d2cf 100644 --- a/src/states_screens/easter_egg_screen.cpp +++ b/src/states_screens/easter_egg_screen.cpp @@ -65,8 +65,7 @@ void EasterEggScreen::eventCallback(Widget* widget, const std::string& name, con { const std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER); if(UserConfigParams::logGUI()) - std::cout << "Clicked on track " << selection.c_str() - << std::endl; + Log::info("EasterEggScreen", "Clicked on track %s", selection.c_str()); UserConfigParams::m_last_track = selection; diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index 723dc8da3..389193060 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -250,8 +250,8 @@ void FeatureUnlockedCutScene::addUnlockedPicture(irr::video::ITexture* picture, { if (picture == NULL) { - std::cerr << "[FeatureUnlockedCutScene::addUnlockedPicture] WARNING: unlockable has no picture : " - << core::stringc(msg.c_str()).c_str() << "\n"; + Log::warn("FeatureUnlockedCutScene::addUnlockedPicture", "Unlockable has no picture: %s", + core::stringc(msg.c_str()).c_str()); picture = irr_driver->getTexture(file_manager->getAsset(FileManager::GUI,"main_help.png")); } @@ -278,7 +278,8 @@ void FeatureUnlockedCutScene::init() const int unlockedStuffCount = m_unlocked_stuff.size(); - if (unlockedStuffCount == 0) std::cerr << "There is nothing in the unlock chest!!!\n"; + if (unlockedStuffCount == 0) + Log::error("FeatureUnlockedCutScene::init", "There is nothing in the unlock chest"); m_all_kart_models.clearAndDeleteAll(); for (int n=0; n 1) pos.X += 1.0f*dt*(n - 0.3f); //else pos.X += 6.2f*dt*float( int((n + 1)/2) ); - //std::cout << "Object " << n << " moving by " << - // (n % 2 == 0 ? -4.0f : 4.0f)*float( n/2 + 1 ) << std::endl; + //Log::info("FeatureUnlockedCutScene", "Object %d moving by %f", n, + // (n % 2 == 0 ? -4.0f : 4.0f)*float( n/2 + 1 )); } else { @@ -514,7 +515,7 @@ void FeatureUnlockedCutScene::addUnlockedTrack(const Track* track) { if (track == NULL) { - std::cerr << "ERROR: Unlocked track does not exist???\n"; + Log::error("FeatureUnlockedCutScene::addUnlockedTrack", "Unlocked track does not exist"); return; } @@ -531,7 +532,7 @@ void FeatureUnlockedCutScene::addUnlockedGP(const GrandPrixData* gp) std::vector images; if (gp == NULL) { - std::cerr << "ERROR: Unlocked GP does not exist???\n"; + Log::error("FeatureUnlockedCutScene::addUnlockedGP", "Unlocked GP does not exist"); video::ITexture* WTF_image = irr_driver->getTexture( file_manager->getAsset(FileManager::GUI,"main_help.png")); images.push_back(WTF_image); } @@ -542,7 +543,7 @@ void FeatureUnlockedCutScene::addUnlockedGP(const GrandPrixData* gp) if (track_amount == 0) { - std::cerr << "ERROR: Unlocked GP is empty???\n"; + Log::error("FeatureUnlockedCutScene::addUnlockedGP", "Unlocked GP is empty"); video::ITexture* WTF_image = irr_driver->getTexture( file_manager->getAsset(FileManager::GUI,"main_help.png")); images.push_back(WTF_image); } diff --git a/src/states_screens/options_screen_audio.cpp b/src/states_screens/options_screen_audio.cpp index 940450d8d..b0ac7c419 100644 --- a/src/states_screens/options_screen_audio.cpp +++ b/src/states_screens/options_screen_audio.cpp @@ -151,7 +151,7 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name, CheckBoxWidget* w = dynamic_cast(widget); UserConfigParams::m_music = w->getState(); - std::cout << "music state is now " << (bool)UserConfigParams::m_music << std::endl; + Log::info("OptionsScreenAudio", "Music is now %s", ((bool) UserConfigParams::m_music) ? "on" : "off"); if(w->getState() == false) music_manager->stopMusic(); diff --git a/src/states_screens/options_screen_input.cpp b/src/states_screens/options_screen_input.cpp index 41b6396dc..4584f2292 100644 --- a/src/states_screens/options_screen_input.cpp +++ b/src/states_screens/options_screen_input.cpp @@ -235,7 +235,8 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name, } else { - std::cerr << "Cannot read internal gamepad input device ID : " << selection.c_str() << std::endl; + Log::error("OptionsScreenInput", "Cannot read internal gamepad input device ID: %s", + selection.c_str()); } } else if (selection.find("keyboard") != std::string::npos) @@ -250,12 +251,13 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name, } else { - std::cerr << "Cannot read internal keyboard input device ID : " << selection.c_str() << std::endl; + Log::error("OptionsScreenInput", "Cannot read internal keyboard input device ID: %s", + selection.c_str()); } } else { - std::cerr << "Cannot read internal input device ID : " << selection.c_str() << std::endl; + Log::error("OptionsScreenInput", "Cannot read internal input device ID: %s", selection.c_str()); } } diff --git a/src/states_screens/options_screen_input2.cpp b/src/states_screens/options_screen_input2.cpp index 2b1fad3cc..ab776a0a3 100644 --- a/src/states_screens/options_screen_input2.cpp +++ b/src/states_screens/options_screen_input2.cpp @@ -394,9 +394,8 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input) { if (UserConfigParams::logMisc()) { - std::cout << "% Binding " << KartActionStrings[binding_to_set] - << " : setting to keyboard key " << sensed_input.m_button_id - << " \n\n"; + Log::info("OptionsScreenInput2", "Binding %s: setting to keyboard key %d", + KartActionStrings[binding_to_set].c_str(), sensed_input.m_button_id); } KeyboardConfig* keyboard = (KeyboardConfig*)m_config; @@ -412,24 +411,21 @@ void OptionsScreenInput2::gotSensedInput(const Input& sensed_input) { if (UserConfigParams::logMisc()) { - std::cout << "% Binding " << KartActionStrings[binding_to_set] - << " : setting to gamepad #" - << sensed_input.m_device_id<< " : "; + Log::info("OptionsScreenInput2", "Binding %s: setting to gamepad #%d", + KartActionStrings[binding_to_set].c_str(), sensed_input.m_device_id); if (sensed_input.m_type == Input::IT_STICKMOTION) { - std::cout << "axis " <getName().c_str() - << std::endl; + Log::info("OptionsScreenInput2", "Entering sensing mode for %s", + m_config->getName().c_str()); } binding_to_set = (PlayerAction)n; @@ -560,8 +555,8 @@ void OptionsScreenInput2::eventCallback(Widget* widget, } else { - std::cerr << "unknown selection device in options : " - << m_config->getName().c_str() << std::endl; + Log::error("OptionsScreenInput2", "Unknown selection device in options: %s", + m_config->getName().c_str()); } break; } diff --git a/src/states_screens/options_screen_video.cpp b/src/states_screens/options_screen_video.cpp index c57d55bd0..c6c3a121c 100644 --- a/src/states_screens/options_screen_video.cpp +++ b/src/states_screens/options_screen_video.cpp @@ -318,15 +318,10 @@ void OptionsScreenVideo::init() (int)UserConfigParams::m_height); - if (res->setSelection(searching_for, PLAYER_ID_GAME_MASTER, + if (!res->setSelection(searching_for, PLAYER_ID_GAME_MASTER, false /* focus it */, true /* even if deactivated*/)) { - // ok found - } - else - { - std::cerr << "[OptionsScreenVideo] Cannot find resolution '" - << searching_for << "'\n"; + Log::error("OptionsScreenVideo", "Cannot find resolution %s", searching_for); } @@ -517,8 +512,7 @@ void OptionsScreenVideo::eventCallback(Widget* widget, const std::string& name, int w = -1, h = -1; if (sscanf(res.c_str(), "%ix%i", &w, &h) != 2 || w == -1 || h == -1) { - std::cerr << "Failed to decode resolution : " << res.c_str() - << std::endl; + Log::error("OptionsScreenVideo", "Failed to decode resolution %s", res.c_str()); return; } diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index 6301ef6e5..57aa620c0 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -187,11 +187,11 @@ void RaceGUIOverworld::renderPlayerView(const Camera *camera, float dt) const core::recti &viewport = camera->getViewport(); core::vector2df scaling = camera->getScaling(); - //std::cout << "Applied ratio : " << viewport.getWidth()/800.0f << std::endl; + //Log::info("RaceGUIOverworld", "Applied ratio: %f", viewport.getWidth()/800.0f); scaling *= viewport.getWidth()/800.0f; // scale race GUI along screen size - //std::cout << "Scale : " << scaling.X << ", " << scaling.Y << std::endl; + //Log::info("RaceGUIOverworld", "Scale: %f, %f", scaling.X, scaling.Y); drawAllMessages (kart, viewport, scaling); diff --git a/src/utils/translation.cpp b/src/utils/translation.cpp index a247bc4e3..3ded3a6e1 100644 --- a/src/utils/translation.cpp +++ b/src/utils/translation.cpp @@ -153,17 +153,16 @@ Translations::Translations() //: m_dictionary_manager("UTF-16") /* const std::set& languages = m_dictionary_manager.get_languages(); - std::cout << "Number of languages: " << languages.size() << std::endl; + Log::info("Translatings", "Number of languages: %d", languages.size()); for (std::set::const_iterator i = languages.begin(); i != languages.end(); ++i) { const Language& language = *i; - std::cout << "Env: " << language.str() << std::endl - << "Name: " << language.get_name() << std::endl - << "Language: " << language.get_language() << std::endl - << "Country: " << language.get_country() << std::endl - << "Modifier: " << language.get_modifier() << std::endl - << std::endl; + Log::info("Translatings", "Env: %s", language.str()); + Log::info("Translatings", "Name: %s", language.get_name()); + Log::info("Translatings", "Language: %s", language.get_language()); + Log::info("Translatings", "Country: %s", language.get_country()); + Log::info("Translatings", "Modifier: %s", language.get_modifier()); } */ @@ -297,8 +296,7 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr) if (n == FRIBIDI_BUFFER_SIZE-1) // prevent buffeoverflows { - std::cerr - << "WARNING : translated string too long, truncating!\n"; + Log::warn("Translations::fribidize", "translated string too long, truncating"); fribidiInput[n] = 0; break; } @@ -329,7 +327,7 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr) if (!result) { - std::cerr << "Fribidi failed in 'fribidi_log2vis' =(\n"; + Log::error("Translations::fribidize", "Fribidi failed in 'fribidi_log2vis' =("); m_converted_string = core::stringw(in_ptr); return m_converted_string.c_str(); } @@ -373,7 +371,7 @@ const wchar_t* Translations::w_gettext(const char* original, const char* context if (original[0] == '\0') return L""; #if TRANSLATE_VERBOSE - std::cout << "Translating " << original << "\n"; + Log::info("Translations", "Translating %s", original); #endif const std::string& original_t = (context == NULL ? From d5bc5ec11061bb3880e8b234aef5ee37fcc43e1a Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 8 Oct 2014 08:00:58 +1100 Subject: [PATCH 034/112] Fix #1605: crash when downloading friends and achievements at the same time. --- src/online/online_profile.cpp | 19 +++++++++++-------- src/online/online_profile.hpp | 18 ++++++++++++++---- .../online_profile_achievements.cpp | 2 +- src/states_screens/online_profile_friends.cpp | 2 +- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/online/online_profile.cpp b/src/online/online_profile.cpp index 0b1496aa1..40ac97648 100644 --- a/src/online/online_profile.cpp +++ b/src/online/online_profile.cpp @@ -60,7 +60,7 @@ OnlineProfile::OnlineProfile(const uint32_t & userid, const irr::core::stringw & username, bool is_current_user) { - m_state = S_READY; + m_state = (State)0; m_cache_bit = true; m_id = userid; m_is_current_user = is_current_user; @@ -112,7 +112,7 @@ OnlineProfile::OnlineProfile(const XMLNode * xml, ConstructorType type) xml->get("id", &m_id ); xml->get("user_name", &m_username); m_is_current_user = (m_id == PlayerManager::getCurrentOnlineId()); - m_state = S_READY; + m_state = (State)0; } // OnlineProfile(XMLNode) // ---------------------------------------------------------------------------- @@ -132,7 +132,7 @@ void OnlineProfile::fetchAchievements() if (m_has_fetched_achievements || m_is_current_user) return; - m_state = S_FETCHING; + m_state = State(m_state | S_FETCHING_ACHIEVEMENTS); // ------------------------------------------------------------------------ /** A simple class that receives the achievements, and calls the right @@ -173,7 +173,7 @@ void OnlineProfile::storeAchievements(const XMLNode * input) m_achievements = StringUtils::splitToUInt(achieved_string, ' '); } m_has_fetched_achievements = true; - m_state = S_READY; + m_state = State(m_state & ~S_FETCHING_ACHIEVEMENTS); } // storeAchievements // ---------------------------------------------------------------------------- @@ -187,7 +187,7 @@ void OnlineProfile::fetchFriends() if (m_has_fetched_friends) return; - m_state = S_FETCHING; + m_state = State(m_state | S_FETCHING_FRIENDS); // ------------------------------------------------------------------------ class FriendsListRequest : public XMLRequest @@ -239,7 +239,7 @@ void OnlineProfile::storeFriends(const XMLNode * input) } } // for i in nodes m_has_fetched_friends = true; - m_state = S_READY; + m_state = State(m_state & ~S_FETCHING_FRIENDS); } // storeFriends // ---------------------------------------------------------------------------- @@ -296,7 +296,8 @@ void OnlineProfile::deleteRelationalInfo() */ const OnlineProfile::IDList& OnlineProfile::getFriends() { - assert(m_has_fetched_friends && m_state == S_READY); + assert(m_has_fetched_friends && + (m_state & S_FETCHING_FRIENDS) != 0); return m_friends; } // getFriends @@ -305,7 +306,9 @@ const OnlineProfile::IDList& OnlineProfile::getFriends() */ const OnlineProfile::IDList& OnlineProfile::getAchievements() { - assert(m_has_fetched_achievements && m_state == S_READY && !m_is_current_user); + assert(m_has_fetched_achievements && + (m_state & S_FETCHING_ACHIEVEMENTS) == 0 && + !m_is_current_user); return m_achievements; } // getAchievements diff --git a/src/online/online_profile.hpp b/src/online/online_profile.hpp index 271b331e7..675168ca1 100644 --- a/src/online/online_profile.hpp +++ b/src/online/online_profile.hpp @@ -78,8 +78,8 @@ private: /** The profile can either be fetching data, or be ready. */ enum State { - S_FETCHING = 1, - S_READY + S_FETCHING_ACHIEVEMENTS = 0x01, + S_FETCHING_FRIENDS = 0x02, }; State m_state; @@ -134,8 +134,18 @@ public: bool hasFetchedFriends() const { return m_has_fetched_friends; } // ------------------------------------------------------------------------ - /** True if the profile is not fetching data atm. */ - bool isReady() const { return m_state == S_READY; } + /** True if the profile has fetched friends. */ + bool finishedFetchingFriends() const + { + return (m_state & S_FETCHING_FRIENDS) == 0; + } // finishedFetchingFriends + + // ------------------------------------------------------------------------ + /** True if the profile has fetched friends. */ + bool finishedFetchingAchievements() const + { + return (m_state & S_FETCHING_ACHIEVEMENTS) == 0; + } // hasFetchedAchievements // ------------------------------------------------------------------------ /** Returns true if this item is the current user. */ diff --git a/src/states_screens/online_profile_achievements.cpp b/src/states_screens/online_profile_achievements.cpp index f24c691e7..a5fe03ff8 100644 --- a/src/states_screens/online_profile_achievements.cpp +++ b/src/states_screens/online_profile_achievements.cpp @@ -157,7 +157,7 @@ void OnlineProfileAchievements::onUpdate(float delta) { if (!m_waiting_for_achievements) return; - if (!m_visiting_profile->isReady()) + if (!m_visiting_profile->hasFetchedAchievements()) { // This will display an increasing number of dots while waiting. m_achievements_list_widget->renameItem("loading", diff --git a/src/states_screens/online_profile_friends.cpp b/src/states_screens/online_profile_friends.cpp index d8f42259d..822e53ded 100644 --- a/src/states_screens/online_profile_friends.cpp +++ b/src/states_screens/online_profile_friends.cpp @@ -164,7 +164,7 @@ void OnlineProfileFriends::onUpdate(float delta) { if(m_waiting_for_friends) { - if(m_visiting_profile->isReady()) + if(m_visiting_profile->hasFetchedFriends()) { displayResults(); } From 4ff00018b4fd4fbd267b04739311ab8198b1fac9 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 8 Oct 2014 08:25:00 +1100 Subject: [PATCH 035/112] Fixed alignment of password field. --- data/gui/user_screen.stkgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/gui/user_screen.stkgui b/data/gui/user_screen.stkgui index a9c54f543..63496bfe3 100644 --- a/data/gui/user_screen.stkgui +++ b/data/gui/user_screen.stkgui @@ -38,7 +38,7 @@
-
From 17fd8df935065c7e89853ad81fda0edec86791e8 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 8 Oct 2014 08:25:42 +1100 Subject: [PATCH 036/112] Fixed assert statement. --- src/online/online_profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/online/online_profile.cpp b/src/online/online_profile.cpp index 40ac97648..00f834aa2 100644 --- a/src/online/online_profile.cpp +++ b/src/online/online_profile.cpp @@ -297,7 +297,7 @@ void OnlineProfile::deleteRelationalInfo() const OnlineProfile::IDList& OnlineProfile::getFriends() { assert(m_has_fetched_friends && - (m_state & S_FETCHING_FRIENDS) != 0); + (m_state & S_FETCHING_FRIENDS) == 0); return m_friends; } // getFriends From 5b2d334b8caf45e458f2847b5b2924d8b33dba01 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 8 Oct 2014 00:50:18 +0200 Subject: [PATCH 037/112] Grass mat should use glossmap too --- src/graphics/render_geometry.cpp | 2 +- src/graphics/shaders.cpp | 4 ++-- src/graphics/shaders.hpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index 613c9c1e5..224c0936b 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -146,7 +146,7 @@ struct GrassMat static const std::vector SecondPassTextures; }; -const std::vector GrassMat::FirstPassTextures = { 0 }; +const std::vector GrassMat::FirstPassTextures = { 0, 1 }; const std::vector GrassMat::SecondPassTextures = { 0, 1 }; struct NormalMat diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index bcc243444..1a5945c04 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -787,7 +787,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); AssignUniforms("ModelMatrix", "InverseModelMatrix", "windDir"); - AssignSamplerNames(Program, 0, "tex"); + AssignSamplerNames(Program, 0, "tex", 1, "glosstex"); } NormalMapShader::NormalMapShader() @@ -832,7 +832,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_objectref_pass1.frag").c_str()); AssignUniforms("windDir"); - AssignSamplerNames(Program, 0, "tex"); + AssignSamplerNames(Program, 0, "tex", 1, "glosstex"); } InstancedNormalMapShader::InstancedNormalMapShader() diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 6cba24ff9..1d498c930 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -65,7 +65,7 @@ public: ObjectRefPass1Shader(); }; -class GrassPass1Shader : public ShaderHelperSingleton, public TextureRead +class GrassPass1Shader : public ShaderHelperSingleton, public TextureRead { public: GrassPass1Shader(); @@ -89,7 +89,7 @@ public: InstancedObjectRefPass1Shader(); }; -class InstancedGrassPass1Shader : public ShaderHelperSingleton, public TextureRead +class InstancedGrassPass1Shader : public ShaderHelperSingleton, public TextureRead { public: InstancedGrassPass1Shader(); From ea3cc141ff8303858316abd60218f8db18ed0e42 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 8 Oct 2014 01:01:28 +0200 Subject: [PATCH 038/112] Fix grass in azdo mode --- data/shaders/instanced_grass.vert | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data/shaders/instanced_grass.vert b/data/shaders/instanced_grass.vert index 5a9d11769..5ca0a66a3 100644 --- a/data/shaders/instanced_grass.vert +++ b/data/shaders/instanced_grass.vert @@ -11,6 +11,7 @@ layout(location = 8) in vec3 Orientation; layout(location = 9) in vec3 Scale; #ifdef GL_ARB_bindless_texture layout(location = 10) in sampler2D Handle; +layout(location = 11) in sampler2D SecondHandle; #endif #else @@ -28,6 +29,7 @@ out vec3 nor; out vec2 uv; #ifdef GL_ARB_bindless_texture flat out sampler2D handle; +flat out sampler2D secondhandle; #endif mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); @@ -42,5 +44,6 @@ void main() uv = Texcoord; #ifdef GL_ARB_bindless_texture handle = Handle; + secondhandle = SecondHandle; #endif } From f11b4825764c8fb6af6f3fd277bbc6bf688c8c62 Mon Sep 17 00:00:00 2001 From: deve Date: Wed, 8 Oct 2014 07:07:27 +0200 Subject: [PATCH 039/112] Use stringstream instead of visual studio specific sscanf_s --- src/config/hardware_stats.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/config/hardware_stats.cpp b/src/config/hardware_stats.cpp index 1a459e531..01d1a1a84 100644 --- a/src/config/hardware_stats.cpp +++ b/src/config/hardware_stats.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -51,7 +52,7 @@ namespace HardwareStats int getRAM() { #ifdef __linux__ - const uint64_t memory_size = (uint64_t)sysconf(_SC_PHYS_PAGES) + const uint64_t memory_size = (uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); return int(memory_size / (1024*1024)); #endif @@ -117,14 +118,14 @@ int getNumProcessors() /** Tries opening and parsing the specified release file in /etc to find * information about the distro used. * \param filename Full path of the file to open. - * \return True if file could be read and valid information was paresed, + * \return True if file could be read and valid information was paresed, * false otherwise. */ bool readEtcReleaseFile(const std::string &filename) { std::ifstream in(filename); std::string s, distro, version; - while( (distro.empty() || version.empty()) && + while( (distro.empty() || version.empty()) && std::getline(in, s) ) { std::vector l = StringUtils::split(s, '='); @@ -158,7 +159,7 @@ void determineOSVersion() std::set file_list; file_manager->listFiles(file_list, "./", true); - for(std::set::iterator i = file_list.begin(); + for(std::set::iterator i = file_list.begin(); i != file_list.end(); i++) { // Only try reading /etc/*-release files @@ -181,7 +182,13 @@ void determineOSVersion() DWORD size = sizeof(windows_version_string); RegQueryValueEx(hKey, "CurrentVersion", 0, 0, (LPBYTE)windows_version_string, &size); unsigned major = 0, minor = 0; - const int ret = sscanf_s(windows_version_string, "%u.%u", &major, &minor); + + std::stringstream sstr(windows_version_string); + sstr >> major; + if (sstr.peek() == '.') + sstr.ignore(); + sstr >> minor; + int windows_version = (major << 8) | minor; RegCloseKey(hKey); @@ -194,7 +201,7 @@ void determineOSVersion() case 0x0601: m_os_version="Windows 7"; break; case 0x0602: m_os_version="Windows 8"; break; default: { - m_os_version = StringUtils::insertValues("Windows %d", + m_os_version = StringUtils::insertValues("Windows %d", windows_version); break; } @@ -260,7 +267,7 @@ void reportHardwareStats() unsigned int ogl_version = irr_driver->getGLSLVersion(); unsigned int major = ogl_version/100; unsigned int minor = ogl_version - 100*major; - std::string version = + std::string version = StringUtils::insertValues("%d.%d", major, minor); json.add("GL_SHADING_LANGUAGE_VERSION", version); @@ -279,7 +286,7 @@ void reportHardwareStats() else if(StringUtils::startsWith(card_name, "S3 Graphics")) card_name="S3"; json.add("gfx_card", card_name+" "+renderer); - + json.add("video_xres", UserConfigParams::m_width ); json.add("video_yres", UserConfigParams::m_height); @@ -311,11 +318,11 @@ void reportHardwareStats() , m_version(version) {} // -------------------------------------------------------------------- - /** Callback after the request has been executed. + /** Callback after the request has been executed. */ virtual void callback() { - // If the request contains incorrect data, it will not have a + // If the request contains incorrect data, it will not have a // download error, but return an error string as return value: if(hadDownloadError() || getData()=="

Bad Request (400)

") { From bc7d8f610332165d37e77d957de4782f7b3ad659 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 8 Oct 2014 22:49:32 +1100 Subject: [PATCH 040/112] Fixed compiler warning. --- src/utils/debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/debug.cpp b/src/utils/debug.cpp index 19c011e70..5dfafbcf5 100644 --- a/src/utils/debug.cpp +++ b/src/utils/debug.cpp @@ -436,7 +436,7 @@ bool onEvent(const SEvent &event) else if (cmdID == DEBUG_HIDE_KARTS) { if (!world) return false; - for (int n = 0; ngetNumKarts(); n++) + for (unsigned int n = 0; ngetNumKarts(); n++) { AbstractKart* kart = world->getKart(n); if (kart->getController()->isPlayerController()) From 029c33c2768acb37b8410a3555e27d4a04466fbb Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 8 Oct 2014 22:53:34 +1100 Subject: [PATCH 041/112] Avoid writing the players.xml file multiple time at the exit time. --- src/config/player_manager.cpp | 6 +++++- src/config/player_profile.cpp | 5 +++-- src/config/player_profile.hpp | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/config/player_manager.cpp b/src/config/player_manager.cpp index d138b8b18..09dc473ce 100644 --- a/src/config/player_manager.cpp +++ b/src/config/player_manager.cpp @@ -170,7 +170,11 @@ PlayerManager::~PlayerManager() for_var_in(PlayerProfile*, player, m_all_players) { if(!player->rememberPassword()) - player->clearSession(); + { + // Don't let the player trigger a save, since it + // will be done below anyway. + player->clearSession(/*save*/false); + } } save(); diff --git a/src/config/player_profile.cpp b/src/config/player_profile.cpp index c5fdcabe5..ac9123570 100644 --- a/src/config/player_profile.cpp +++ b/src/config/player_profile.cpp @@ -235,12 +235,13 @@ void PlayerProfile::saveSession(int user_id, const std::string &token) // ------------------------------------------------------------------------ /** Unsets any saved session data. */ -void PlayerProfile::clearSession() +void PlayerProfile::clearSession(bool save) { m_saved_session = false; m_saved_user_id = 0; m_saved_token = ""; - PlayerManager::get()->save(); + if(save) + PlayerManager::get()->save(); } // clearSession //------------------------------------------------------------------------------ diff --git a/src/config/player_profile.hpp b/src/config/player_profile.hpp index 0d8106df5..d9395fd9b 100644 --- a/src/config/player_profile.hpp +++ b/src/config/player_profile.hpp @@ -121,7 +121,7 @@ public: bool operator<(const PlayerProfile &other); void raceFinished(); void saveSession(int user_id, const std::string &token); - void clearSession(); + void clearSession(bool save=true); void addIcon(); /** Abstract virtual classes, to be implemented by the OnlinePlayer. */ From d5faa23e0c5c6f0ddb027534c5e2600a47d65e41 Mon Sep 17 00:00:00 2001 From: deve Date: Wed, 8 Oct 2014 14:03:23 +0200 Subject: [PATCH 042/112] Use CMAKE_CXX_FLAGS instead of add_definitions for additional flags --- CMakeLists.txt | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f0cb8f1eb..10f063cd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,11 +87,7 @@ if(WIN32) set(ENV{PATH} "$ENV{PATH};${PROJECT_SOURCE_DIR}/dependencies/include") set(ENV{LIB} ${PROJECT_SOURCE_DIR}/dependencies/lib) set(ENV{OPENALDIR} ${PROJECT_SOURCE_DIR}/dependencies) - if(MSVC) - add_definitions(/D_IRR_STATIC_LIB_) - elseif(MINGW) - add_definitions(-D_IRR_STATIC_LIB_) - endif() + add_definitions(-D_IRR_STATIC_LIB_) endif() @@ -149,7 +145,7 @@ endif() if(UNIX OR MINGW) # if(USE_CPP2011) - add_definitions("-std=gnu++0x") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") # endif() endif() @@ -172,7 +168,7 @@ endif() # Set some compiler options if(UNIX OR MINGW) - add_definitions(-Wall) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") endif() if(WIN32) @@ -200,7 +196,7 @@ endif() # TODO: remove this switch add_definitions(-DHAVE_OGGVORBIS) -if(WIN32 AND NOT MINGW) +if(WIN32) configure_file("${STK_SOURCE_DIR}/windows_installer/icon_rc.template" "${PROJECT_BINARY_DIR}/tmp/icon.rc") endif() @@ -291,8 +287,7 @@ if(UNIX AND NOT APPLE) target_link_libraries(supertuxkart ${IRRLICHT_XF86VM_LIBRARY}) endif() if(USE_ASAN) - add_definitions("-fsanitize=address") - add_definitions("-fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") target_link_libraries(supertuxkart "-fsanitize=address") endif() endif() @@ -318,11 +313,7 @@ if(USE_WIIUSE) find_library(BLUETOOTH_LIBRARY NAMES IOBluetooth PATHS /Developer/Library/Frameworks/IOBluetooth.framework) target_link_libraries(supertuxkart wiiuse ${BLUETOOTH_LIBRARY}) elseif(WIN32) - if(MSVC) - add_definitions("/DWIIUSE_STATIC") - else() - add_definitions("-DWIIUSE_STATIC") - endif() + add_definitions(-DWIIUSE_STATIC) if(WIIUSE_BUILD) target_link_libraries(supertuxkart wiiuse) else() From 30413b8d6dd8517e3355235ee2382f3691a5f620 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 8 Oct 2014 23:14:43 +1100 Subject: [PATCH 043/112] Fix loss of associated online user name if stk is played offline (might be a fix for #1595). --- src/states_screens/user_screen.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp index 787d6726a..737bf2c84 100644 --- a/src/states_screens/user_screen.cpp +++ b/src/states_screens/user_screen.cpp @@ -214,6 +214,14 @@ void BaseUserScreen::makeEntryFieldsVisible() { getWidget("label_password")->setVisible(online); m_password_tb->setVisible(online); + if(player && player->hasSavedSession()) + { + // Even though this field is invisible we need to set + // the name, otherwise in update a change of user name + // will be detected, causing a clearing of this player + // (which then removes the associated online user name). + m_username_tb->setText(player->getLastOnlineName()); + } } } // makeEntryFieldsVisible From f8de826888e8e714b55cf4ae1868bcf8916b55f8 Mon Sep 17 00:00:00 2001 From: deve Date: Wed, 8 Oct 2014 14:44:05 +0200 Subject: [PATCH 044/112] Fixed compiler warnings --- src/guiengine/widgets/dynamic_ribbon_widget.hpp | 4 ++-- src/network/protocols/connect_to_server.cpp | 2 +- src/network/protocols/get_public_address.cpp | 1 + src/utils/string_utils.cpp | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.hpp b/src/guiengine/widgets/dynamic_ribbon_widget.hpp index b3cdd1396..a46a28202 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.hpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.hpp @@ -187,7 +187,7 @@ namespace GUIEngine int m_max_label_width; /** Max length of a label, in characters */ - int m_max_label_length; + unsigned int m_max_label_length; public: @@ -298,7 +298,7 @@ namespace GUIEngine /** Set approximately how many items are expected to be in this ribbon; will help the layout * algorithm next time add() is called */ void setItemCountHint(int hint) { m_item_count_hint = hint; } - + /** Set max length of displayed text. */ void setMaxLabelLength(int length) { m_max_label_length = length; } }; diff --git a/src/network/protocols/connect_to_server.cpp b/src/network/protocols/connect_to_server.cpp index bc4dda7fd..1f66313fb 100644 --- a/src/network/protocols/connect_to_server.cpp +++ b/src/network/protocols/connect_to_server.cpp @@ -218,7 +218,7 @@ void ConnectToServer::asynchronousUpdate() } // while insufficient buffer for(unsigned int i=0; idwNumEntries; i++) { - int ip = ntohl(table->table[i].dwAddr); + unsigned int ip = ntohl(table->table[i].dwAddr); if(sender.ip == ip) // this interface is ours { sender.ip = 0x7f000001; // 127.0.0.1 diff --git a/src/network/protocols/get_public_address.cpp b/src/network/protocols/get_public_address.cpp index 29885bbbf..03c232323 100644 --- a/src/network/protocols/get_public_address.cpp +++ b/src/network/protocols/get_public_address.cpp @@ -30,6 +30,7 @@ #include #ifdef __MINGW32__ +# undef _WIN32_WINNT # define _WIN32_WINNT 0x501 #endif diff --git a/src/utils/string_utils.cpp b/src/utils/string_utils.cpp index e560bd2b5..fbbaba2b3 100644 --- a/src/utils/string_utils.cpp +++ b/src/utils/string_utils.cpp @@ -310,7 +310,7 @@ namespace StringUtils for(int i=(int)dirs.size()-1; i>=0; i--) { if(dirs[i].size()>1) continue; - if(i==dirs.size()-1) // last element + if(i==(int)dirs.size()-1) // last element { dirs[i]+=":"; // turn "c" back into "c:" } From 08c8de1986e5d38e56b60a3c7835083a1993f7bc Mon Sep 17 00:00:00 2001 From: deve Date: Thu, 9 Oct 2014 07:07:16 +0200 Subject: [PATCH 045/112] Fixed missing quotes --- src/input/device_manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/input/device_manager.cpp b/src/input/device_manager.cpp index f7893506c..65a85a563 100644 --- a/src/input/device_manager.cpp +++ b/src/input/device_manager.cpp @@ -145,9 +145,9 @@ void DeviceManager::setAssignMode(const PlayerAssignMode assignMode) m_assign_mode = assignMode; #if INPUT_MODE_DEBUG - if (assignMode == NO_ASSIGN) Log::info("DeviceManager::setAssignMode", "NO_ASSIGN); - if (assignMode == ASSIGN) Log::info("DeviceManager::setAssignMode", "ASSIGN); - if (assignMode == DETECT_NEW) Log::info("DeviceManager::setAssignMode", "DETECT_NEW); + if (assignMode == NO_ASSIGN) Log::info("DeviceManager::setAssignMode(NO_ASSIGN)"); + if (assignMode == ASSIGN) Log::info("DeviceManager::setAssignMode(ASSIGN)"); + if (assignMode == DETECT_NEW) Log::info("DeviceManager::setAssignMode(DETECT_NEW)"); #endif // when going back to no-assign mode, do some cleanup From 50c21cc11e003d26b5e2d404793e55e81df24d5b Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 9 Oct 2014 23:32:17 +1100 Subject: [PATCH 046/112] Added secret achievement (i.e. progress not shown in list). --- data/achievements.xml | 4 ++++ src/achievements/achievement_info.cpp | 2 ++ src/achievements/achievement_info.hpp | 6 ++++++ src/states_screens/online_profile_achievements.cpp | 2 ++ 4 files changed, 14 insertions(+) diff --git a/data/achievements.xml b/data/achievements.xml index 1cd0d9ad8..c3a965132 100644 --- a/data/achievements.xml +++ b/data/achievements.xml @@ -48,4 +48,8 @@ title="Banana Lover" description="Collect at least 5 bananas in one race."> + + + diff --git a/src/achievements/achievement_info.cpp b/src/achievements/achievement_info.cpp index 8763ba8e6..b2e28888c 100644 --- a/src/achievements/achievement_info.cpp +++ b/src/achievements/achievement_info.cpp @@ -35,6 +35,7 @@ AchievementInfo::AchievementInfo(const XMLNode * input) m_id = 0; m_title = ""; m_description = ""; + m_is_secret = false; bool all; all = input->get("id", &m_id ) && input->get("title", &m_title ) && @@ -69,6 +70,7 @@ AchievementInfo::AchievementInfo(const XMLNode * input) else Log::warn("AchievementInfo", "Achievement check type '%s' unknown.", s.c_str()); + input->get("secret", &m_is_secret); // Now load the goal nodes for (unsigned int n = 0; n < input->getNumNodes(); n++) diff --git a/src/achievements/achievement_info.hpp b/src/achievements/achievement_info.hpp index 648671794..c9b98e13d 100644 --- a/src/achievements/achievement_info.hpp +++ b/src/achievements/achievement_info.hpp @@ -94,6 +94,9 @@ private: /** Determines when the achievement needs to be reset */ ResetType m_reset_type; + /** A secret achievement has its progress not shown. */ + bool m_is_secret; + public: AchievementInfo(const XMLNode * input); virtual ~AchievementInfo() {}; @@ -119,6 +122,9 @@ public: /** Returns the check type for this achievement. */ AchievementCheckType getCheckType() const { return m_check_type; } // ------------------------------------------------------------------------ + /** Returns if this achievement is a secret achievement. */ + bool isSecret() const { return m_is_secret; } + // ------------------------------------------------------------------------ }; // class AchievementInfo diff --git a/src/states_screens/online_profile_achievements.cpp b/src/states_screens/online_profile_achievements.cpp index a5fe03ff8..7b75c54ab 100644 --- a/src/states_screens/online_profile_achievements.cpp +++ b/src/states_screens/online_profile_achievements.cpp @@ -103,6 +103,8 @@ void OnlineProfileAchievements::init() { std::vector row; const Achievement *a = it->second; + if(a->getInfo()->isSecret()) + continue; ListWidget::ListCell title(a->getInfo()->getTitle(), -1, 2); ListWidget::ListCell progress(a->getProgressAsString(), -1, 1); row.push_back(title); From f39e2d9cdfd091d13f5cc73df6d3e1b4a21142bd Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 07:49:14 +1100 Subject: [PATCH 047/112] Actually display secret achievements once they have been achieved. --- src/states_screens/online_profile_achievements.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/states_screens/online_profile_achievements.cpp b/src/states_screens/online_profile_achievements.cpp index 7b75c54ab..524ec27e5 100644 --- a/src/states_screens/online_profile_achievements.cpp +++ b/src/states_screens/online_profile_achievements.cpp @@ -103,7 +103,7 @@ void OnlineProfileAchievements::init() { std::vector row; const Achievement *a = it->second; - if(a->getInfo()->isSecret()) + if(a->getInfo()->isSecret() && !a->isAchieved()) continue; ListWidget::ListCell title(a->getInfo()->getTitle(), -1, 2); ListWidget::ListCell progress(a->getProgressAsString(), -1, 1); From 5d019e3537d50e9bc6e8e86bed987df17bd0df93 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 07:57:10 +1100 Subject: [PATCH 048/112] Don't show a password entry field for the currently logged in user. --- src/states_screens/user_screen.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp index 737bf2c84..6c21c14df 100644 --- a/src/states_screens/user_screen.cpp +++ b/src/states_screens/user_screen.cpp @@ -203,7 +203,11 @@ void BaseUserScreen::makeEntryFieldsVisible() getWidget("label_remember")->setVisible(online); getWidget("remember-user")->setVisible(online); PlayerProfile *player = getSelectedPlayer(); - if(player && player->hasSavedSession() && online) + // Don't show the password fields if the player wants to be online + // and either is the current player (no need to enter a password then) + // or has a saved session. + if(player && online && + (player->hasSavedSession() || player==PlayerManager::getCurrentPlayer())) { // If we show the online login fields, but the player has a // saved session, don't show the password field. From 3877bf1dab12c9891eb80201f2e5b9ed75ce441c Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 09:21:15 +1100 Subject: [PATCH 049/112] Added support for detecting BSD versions; added uname based fallback on linux in case /etc/*release does not find valid info. --- src/config/hardware_stats.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/config/hardware_stats.cpp b/src/config/hardware_stats.cpp index 01d1a1a84..532f98211 100644 --- a/src/config/hardware_stats.cpp +++ b/src/config/hardware_stats.cpp @@ -32,6 +32,8 @@ #include #include #include +#include // To get BSD macro +#include #include @@ -166,7 +168,27 @@ void determineOSVersion() if(StringUtils::hasSuffix(*i, "-release")) if (readEtcReleaseFile(*i)) return; } + // Fallback in case that we can't find any valid information in /etc/*release + struct utsname u; + if (uname(&u)) + { + m_os_version = "Linux unknown"; + return; + } + m_os_version = std::string(u.sysname) + " " + u.release; + #endif + +#ifdef BSD + struct utsname u; + if (uname(&u)) + { + m_os_version = "BSD unknown"; + return; + } + m_os_version = std::string(u.sysname) + " " + u.release; +#endif + #ifdef WIN32 // (C) 2014 by Wildfire Games (0 A.D.), ported by Joerg Henrichs. From a5ad78654e629f4c8e7d87bb8034ef6e4d086cf6 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 09:40:19 +1100 Subject: [PATCH 050/112] Remove data after "-" when using uname (which could theoretically be used to identify a system). --- src/config/hardware_stats.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/config/hardware_stats.cpp b/src/config/hardware_stats.cpp index 532f98211..9e69bc3e1 100644 --- a/src/config/hardware_stats.cpp +++ b/src/config/hardware_stats.cpp @@ -175,7 +175,10 @@ void determineOSVersion() m_os_version = "Linux unknown"; return; } - m_os_version = std::string(u.sysname) + " " + u.release; + // Ignore data after "-", since it could identify a system (self compiled + // kernels). + std::vector l = StringUtils::split(std::string(u.release),'-'); + m_os_version = std::string(u.sysname) + " " + l[0]; #endif @@ -186,7 +189,10 @@ void determineOSVersion() m_os_version = "BSD unknown"; return; } - m_os_version = std::string(u.sysname) + " " + u.release; + // Ignore data after "-", since it could identify a system (self compiled + // kernels). + std::vector l = StringUtils::split(std::string(u.release),'-'); + m_os_version = std::string(u.sysname) + " " + l[0]; #endif #ifdef WIN32 From 8d587ab8f1210059aafa2a747d1b80598c70d905 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 09:54:57 +1100 Subject: [PATCH 051/112] Fixed windows compilation. --- src/config/hardware_stats.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/config/hardware_stats.cpp b/src/config/hardware_stats.cpp index 9e69bc3e1..275cb71a0 100644 --- a/src/config/hardware_stats.cpp +++ b/src/config/hardware_stats.cpp @@ -32,8 +32,10 @@ #include #include #include -#include // To get BSD macro -#include +#ifndef WIN32 +# include // To get BSD macro +# include +#endif #include From 6dc18a3557f9605ea2e071fd8da60c76b2d0c56c Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 16:19:25 +1100 Subject: [PATCH 052/112] Change "Cancel" to 'Exit game' and make the back arrow invisible if the login screen is shown before the race start. --- src/guiengine/abstract_state_manager.hpp | 4 ++++ src/states_screens/user_screen.cpp | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/guiengine/abstract_state_manager.hpp b/src/guiengine/abstract_state_manager.hpp index 07f8bf8fd..ea45e4acf 100644 --- a/src/guiengine/abstract_state_manager.hpp +++ b/src/guiengine/abstract_state_manager.hpp @@ -167,6 +167,10 @@ namespace GUIEngine virtual void onTopMostScreenChanged() = 0; + // -------------------------------------------------------------------- + /** Returns the number of screens on the stack. Is used to decide + * if exiting a screen would cause STK to end or not. */ + unsigned int getMenuStackSize() const { return m_menu_stack.size(); } }; // Class AbstractStateManager } // GUIEngine diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp index 6c21c14df..148848885 100644 --- a/src/states_screens/user_screen.cpp +++ b/src/states_screens/user_screen.cpp @@ -73,6 +73,15 @@ void BaseUserScreen::init() m_info_widget = getWidget("message"); assert(m_info_widget); + // The behaviour of the screen is slightly different at startup, i.e. + // when it is the first screen: cancel will exit the game, and in + // this case no 'back' error should be shown. + bool is_first_screen = StateManager::get()->getMenuStackSize()==1; + getWidget("back")->setVisible(!is_first_screen); + getWidget("cancel")->setLabel(is_first_screen + ? _("Exit game") + : _("Cancel") ); + m_sign_out_name = ""; m_sign_in_name = ""; @@ -293,7 +302,7 @@ void BaseUserScreen::eventCallback(Widget* widget, } else if (button == "cancel") { - StateManager::get()->popMenu(); + // EscapePressed will pop this screen. StateManager::get()->escapePressed(); } else if (button == "recover") From 61068c7278279ce1b6269041396a8709cfab76d1 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 16:45:29 +1100 Subject: [PATCH 053/112] Replaces sfx->getStatus with isPlaying() functi n which is faster (for #1511). --- src/audio/dummy_sfx.hpp | 2 +- src/audio/sfx_base.hpp | 1 + src/audio/sfx_openal.cpp | 16 +++++++++++++++- src/audio/sfx_openal.hpp | 4 ++++ src/karts/kart.cpp | 4 ++-- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 9840c2233..012a75d00 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -48,7 +48,7 @@ public: virtual SFXManager::SFXStatus getStatus() { return SFXManager::SFX_STOPPED; } virtual void onSoundEnabledBack() {} virtual void setRolloff(float rolloff) {} - + virtual bool isPlaying() { return false; } virtual const SFXBuffer* getBuffer() const { return NULL; } }; // DummySFX diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index 033d57c05..65809307b 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -48,6 +48,7 @@ public: virtual bool init() = 0; virtual void position(const Vec3 &position) = 0; virtual void setLoop(bool status) = 0; + virtual bool isPlaying() = 0; virtual void play() = 0; virtual void reallyPlayNow() = 0; virtual void stop() = 0; diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index c80002b14..bb220d7c5 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -43,6 +43,7 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBu m_soundBuffer = buffer; m_soundSource = 0; m_ok = false; + m_is_playing = false; m_positional = positional; m_defaultGain = gain; m_loop = false; @@ -187,7 +188,8 @@ void SFXOpenAL::stop() { if(!m_ok) return; - m_loop = false; + m_is_playing = false; + m_loop = false; alSourcei(m_soundSource, AL_LOOPING, AL_FALSE); alSourceStop(m_soundSource); SFXManager::checkError("stoping"); @@ -228,6 +230,10 @@ void SFXOpenAL::resume() */ void SFXOpenAL::play() { + // Technically the sfx is only playing after the sfx thread starts it, + // but for STK this is correct since we don't want to start the same + // sfx twice. + m_is_playing = true; SFXManager::get()->queue(this); } // play @@ -250,6 +256,14 @@ void SFXOpenAL::reallyPlayNow() SFXManager::checkError("playing"); } // reallyPlayNow +//----------------------------------------------------------------------------- +/** Returns true if the sound effect is currently playing. + */ +bool SFXOpenAL::isPlaying() +{ + return m_is_playing; +} // isPlaying + //----------------------------------------------------------------------------- /** Sets the position where this sound effects is played. * \param position Position of the sound effect. diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 58a93eafb..807111a33 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -55,6 +55,9 @@ private: the sound source won't be created and we'll be left with no clue when enabling sounds later. */ float m_gain; + + /** True when the sfx is currently playing. */ + bool m_is_playing; /** The master gain set in user preferences */ float m_master_gain; @@ -72,6 +75,7 @@ public: virtual void play(); virtual void reallyPlayNow(); virtual void setLoop(bool status); + virtual bool isPlaying(); virtual void stop(); virtual void pause(); virtual void resume(); diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index aee0d8b7c..3e8112ced 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -2018,10 +2018,10 @@ void Kart::updatePhysics(float dt) m_skidding->getSkidState() == Skidding::SKID_ACCUMULATE_RIGHT ) && m_skidding->getGraphicalJumpOffset()==0) { - if(m_skid_sound->getStatus() != SFXManager::SFX_PLAYING &&!isWheeless()) + if(!m_skid_sound->isPlaying() && !isWheeless()) m_skid_sound->play(); } - else if(m_skid_sound->getStatus() == SFXManager::SFX_PLAYING) + else if(m_skid_sound->isPlaying()) { m_skid_sound->stop(); } From 77bd4140a803088231191925e10e4a58e44e0828 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 16:48:21 +1100 Subject: [PATCH 054/112] Replaced more getStatus() functions. --- src/karts/kart.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 3e8112ced..a5a69d2be 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1893,12 +1893,12 @@ void Kart::crashed(const Material* m, AbstractKart *k) // it's not already playing. if (isShielded() || (k != NULL && k->isShielded())) { - if (m_boing_sound->getStatus() != SFXManager::SFX_PLAYING) + if (!m_boing_sound->isPlaying()) m_boing_sound->play(); } else { - if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING) + if(!m_crash_sound->isPlaying()) m_crash_sound->play(); } } @@ -1973,7 +1973,7 @@ bool Kart::playCustomSFX(unsigned int type) // SFXManager::get()->getCustomTagName(type), // m_kart_properties->getIdent().c_str()); // If it's already playing, let it finish - if (m_custom_sounds[type]->getStatus() != SFXManager::SFX_PLAYING) + if (!m_custom_sounds[type]->isPlaying()) { m_custom_sounds[type]->play(); } From 4dc817890b1bbf7c4a27bc8eeda5a333412c9a3c Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 23:50:27 +1100 Subject: [PATCH 055/112] Reverted 77bd4140a803088231191925e10e4a58e44e0828 (which caused crash and other sfx to be played only once). --- src/karts/kart.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index a5a69d2be..3e8112ced 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1893,12 +1893,12 @@ void Kart::crashed(const Material* m, AbstractKart *k) // it's not already playing. if (isShielded() || (k != NULL && k->isShielded())) { - if (!m_boing_sound->isPlaying()) + if (m_boing_sound->getStatus() != SFXManager::SFX_PLAYING) m_boing_sound->play(); } else { - if(!m_crash_sound->isPlaying()) + if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING) m_crash_sound->play(); } } @@ -1973,7 +1973,7 @@ bool Kart::playCustomSFX(unsigned int type) // SFXManager::get()->getCustomTagName(type), // m_kart_properties->getIdent().c_str()); // If it's already playing, let it finish - if (!m_custom_sounds[type]->isPlaying()) + if (m_custom_sounds[type]->getStatus() != SFXManager::SFX_PLAYING) { m_custom_sounds[type]->play(); } From 216575a7328808bc5661633953a377798880b5a1 Mon Sep 17 00:00:00 2001 From: hiker Date: Sat, 11 Oct 2014 11:55:02 +1100 Subject: [PATCH 056/112] Started to let all sfx related command be executed from the sfx manager to avoid race condition and crashes. --- src/audio/sfx_manager.cpp | 54 ++++++++++++++++++++++++--------------- src/audio/sfx_manager.hpp | 33 ++++++++++++++++++++++-- src/audio/sfx_openal.cpp | 2 +- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 1bfd2c54e..7ebc2c061 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -106,9 +106,9 @@ SFXManager::SFXManager() if (!sfxAllowed()) return; setMasterSFXVolume( UserConfigParams::m_sfx_volume ); - m_sfx_to_play.lock(); - m_sfx_to_play.getData().clear(); - m_sfx_to_play.unlock(); + m_sfx_commands.lock(); + m_sfx_commands.getData().clear(); + m_sfx_commands.unlock(); } // SoundManager @@ -163,15 +163,17 @@ SFXManager::~SFXManager() * separate thread. * \param sfx The sound effect to be started. */ -void SFXManager::queue(SFXBase *sfx) +void SFXManager::queue(SFXCommands command, SFXBase *sfx) { // Don't add sfx that are either not working correctly (e.g. because sfx // are disabled); if(sfx && sfx->getStatus()==SFX_UNKNOWN ) return; - m_sfx_to_play.lock(); - m_sfx_to_play.getData().push_back(sfx); - m_sfx_to_play.unlock(); + SFXCommand *sfx_command = new SFXCommand(command, sfx); + + m_sfx_commands.lock(); + m_sfx_commands.getData().push_back(sfx_command); + m_sfx_commands.unlock(); // Wake up the sfx thread pthread_cond_signal(&m_cond_request); @@ -183,7 +185,7 @@ void SFXManager::queue(SFXBase *sfx) */ void SFXManager::stopThread() { - queue(NULL); + queue(SFX_EXIT, NULL); } // stopThread //---------------------------------------------------------------------------- @@ -198,35 +200,47 @@ void* SFXManager::mainLoop(void *obj) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - me->m_sfx_to_play.lock(); + me->m_sfx_commands.lock(); // Wait till we have an empty sfx in the queue - while (me->m_sfx_to_play.getData().empty() || - me->m_sfx_to_play.getData().front()!=NULL ) + while (me->m_sfx_commands.getData().empty() || + me->m_sfx_commands.getData().front()->m_command!=SFX_EXIT) { - bool empty = me->m_sfx_to_play.getData().empty(); + bool empty = me->m_sfx_commands.getData().empty(); // Wait in cond_wait for a request to arrive. The 'while' is necessary // since "spurious wakeups from the pthread_cond_wait ... may occur" // (pthread_cond_wait man page)! while (empty) { - pthread_cond_wait(&me->m_cond_request, me->m_sfx_to_play.getMutex()); - empty = me->m_sfx_to_play.getData().empty(); + pthread_cond_wait(&me->m_cond_request, me->m_sfx_commands.getMutex()); + empty = me->m_sfx_commands.getData().empty(); } - SFXBase *current = me->m_sfx_to_play.getData().front(); - me->m_sfx_to_play.getData().erase(me->m_sfx_to_play.getData().begin()); + SFXCommand *current = me->m_sfx_commands.getData().front(); + me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); - if (!current) // empty sfx indicates to abort the sfx manager + if (current->m_command == SFX_EXIT) break; - me->m_sfx_to_play.unlock(); - current->reallyPlayNow(); - me->m_sfx_to_play.lock(); + me->m_sfx_commands.unlock(); + switch(current->m_command) + { + case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; + default: assert("Not yet supported."); + } + delete current; + current = NULL; + me->m_sfx_commands.lock(); } // while + // Clean up memory to avoid leak detection + while(!me->m_sfx_commands.getData().empty()) + { + delete me->m_sfx_commands.getData().front(); + me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); + } return NULL; } // mainLoop diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 4af8f6e22..90e0ce323 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -19,6 +19,7 @@ #ifndef HEADER_SFX_MANAGER_HPP #define HEADER_SFX_MANAGER_HPP +#include "utils/leak_check.hpp" #include "utils/no_copy.hpp" #include "utils/synchronised.hpp" #include "utils/vec3.hpp" @@ -57,6 +58,18 @@ private: public: + /** The various commands to be executed by the sfx manager thread + * for each sfx. */ + enum SFXCommands + { + SFX_PLAY = 1, + SFX_STOP = 2, + SFX_PAUSE = 3, + SFX_RESUME = 4, + SFX_DELETE = 5, + SFX_EXIT = 6, + }; // SFXCommands + /** * Entries for custom SFX sounds. These are unique for each kart. * eg. kart->playCustomSFX(SFX_MANAGER::CUSTOM_HORN) @@ -85,6 +98,22 @@ public: private: + /** Data structure for the queue, which stores a sfx and the command to + * execute for it. */ + class SFXCommand : public NoCopy + { + private: + LEAK_CHECK() + public: + SFXBase *m_sfx; + SFXCommands m_command; + SFXCommand(SFXCommands command, SFXBase *base) + { + m_command = command; + m_sfx = base; + } + }; // SFXCommand + /** Listener position */ Vec3 m_position; @@ -96,7 +125,7 @@ private: std::vector m_all_sfx; /** The list of sound effects to be played in the next update. */ - Synchronised< std::vector > m_sfx_to_play; + Synchronised< std::vector > m_sfx_commands; /** To play non-positional sounds without having to create a new object for each */ std::map m_quick_sounds; @@ -124,7 +153,7 @@ private: public: static void create(); static void destroy(); - void queue(SFXBase *sfx); + void queue(SFXCommands command, SFXBase *sfx); // ------------------------------------------------------------------------ /** Static function to get the singleton sfx manager. */ static SFXManager *get() diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index bb220d7c5..029f1d9f1 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -234,7 +234,7 @@ void SFXOpenAL::play() // but for STK this is correct since we don't want to start the same // sfx twice. m_is_playing = true; - SFXManager::get()->queue(this); + SFXManager::get()->queue(SFXManager::SFX_PLAY, this); } // play //----------------------------------------------------------------------------- From f0429ce95e8439abcd6d012c867893222d5ee1ae Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Sat, 11 Oct 2014 10:50:06 +0200 Subject: [PATCH 057/112] Use length limit for dynamic ribbon labels in the GP editor --- src/states_screens/edit_track_screen.cpp | 4 ++++ src/states_screens/grand_prix_editor_screen.cpp | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/states_screens/edit_track_screen.cpp b/src/states_screens/edit_track_screen.cpp index b492ea595..c7dcd0d2a 100644 --- a/src/states_screens/edit_track_screen.cpp +++ b/src/states_screens/edit_track_screen.cpp @@ -85,7 +85,11 @@ bool EditTrackScreen::getResult() const // ----------------------------------------------------------------------------- void EditTrackScreen::loadedFromFile() { + static const int MAX_LABEL_LENGTH = 35; + DynamicRibbonWidget* tracks_widget = getWidget("tracks"); + assert(tracks_widget != NULL); + tracks_widget->setMaxLabelLength(MAX_LABEL_LENGTH); } // ----------------------------------------------------------------------------- diff --git a/src/states_screens/grand_prix_editor_screen.cpp b/src/states_screens/grand_prix_editor_screen.cpp index 372984d0d..06405e217 100644 --- a/src/states_screens/grand_prix_editor_screen.cpp +++ b/src/states_screens/grand_prix_editor_screen.cpp @@ -62,7 +62,15 @@ void GrandPrixEditorScreen::beforeAddingWidget() // ----------------------------------------------------------------------------- void GrandPrixEditorScreen::loadedFromFile() { + static const int MAX_LABEL_LENGTH = 35; + DynamicRibbonWidget* gplist_widget = getWidget("gplist"); + assert (gplist_widget != NULL); + gplist_widget->setMaxLabelLength(MAX_LABEL_LENGTH); + + DynamicRibbonWidget* tracks_widget = getWidget("tracks"); + assert(tracks_widget != NULL); + tracks_widget->setMaxLabelLength(MAX_LABEL_LENGTH); } // ----------------------------------------------------------------------------- From bfe84612fa408b070801ba3cd23054592307ec68 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 13 Oct 2014 08:26:45 +1100 Subject: [PATCH 058/112] Let all SFX commands be handled by the sfx manager thread (otherwise events could be handled in the wrong order, e.g. a delete from the main thread before the play in the manager thread, resulting in a crash). Should fix #1511 and #1604. --- src/audio/dummy_sfx.hpp | 5 ++ src/audio/sfx_base.hpp | 4 ++ src/audio/sfx_manager.cpp | 71 +++++++++++++++------- src/audio/sfx_manager.hpp | 4 +- src/audio/sfx_openal.cpp | 45 ++++++++++++-- src/audio/sfx_openal.hpp | 4 ++ src/graphics/hit_sfx.cpp | 5 +- src/graphics/weather.cpp | 6 +- src/items/attachment.cpp | 14 ++--- src/items/bowling.cpp | 6 +- src/items/powerup.cpp | 4 +- src/items/rubber_ball.cpp | 2 +- src/items/swatter.cpp | 2 +- src/karts/controller/player_controller.cpp | 10 +-- src/karts/kart.cpp | 31 +++++----- src/modes/linear_world.cpp | 2 +- src/modes/soccer_world.cpp | 2 +- src/modes/world_status.cpp | 6 +- src/tracks/track_object_presentation.cpp | 44 +++++++++----- 19 files changed, 175 insertions(+), 92 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 012a75d00..adf73d184 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -40,9 +40,14 @@ public: virtual void position(const Vec3 &position) {} virtual void setLoop(bool status) {} virtual void play() {} + virtual void reallyPlayNow() {} virtual void stop() {} + virtual void reallyStopNow() {} virtual void pause() {} + virtual void reallyPauseNow() {} virtual void resume() {} + virtual void reallyResumeNow() {} + virtual void deleteSFX() { delete this; } virtual void speed(float factor) {} virtual void volume(float gain) {} virtual SFXManager::SFXStatus getStatus() { return SFXManager::SFX_STOPPED; } diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index 65809307b..3ade04eb8 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -52,8 +52,12 @@ public: virtual void play() = 0; virtual void reallyPlayNow() = 0; virtual void stop() = 0; + virtual void reallyStopNow() = 0; virtual void pause() = 0; + virtual void reallyPauseNow() = 0; virtual void resume() = 0; + virtual void reallyResumeNow() = 0; + virtual void deleteSFX() = 0; virtual void speed(float factor) = 0; virtual void volume(float gain) = 0; virtual void setMasterVolume(float gain) = 0; diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 7ebc2c061..968adc5d9 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -124,13 +124,15 @@ SFXManager::~SFXManager() pthread_cond_destroy(&m_cond_request); // ---- clear m_all_sfx - const int sfx_amount = (int) m_all_sfx.size(); + // not strictly necessary, but might avoid copy&paste problems + m_all_sfx.lock(); + const int sfx_amount = (int) m_all_sfx.getData().size(); for (int n=0; n::iterator i = m_quick_sounds.begin(); @@ -226,7 +228,15 @@ void* SFXManager::mainLoop(void *obj) me->m_sfx_commands.unlock(); switch(current->m_command) { - case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; + case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; + case SFX_STOP: current->m_sfx->reallyStopNow(); break; + case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; + case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; + case SFX_DELETE: { + current->m_sfx->reallyStopNow(); + me->deleteSFX(current->m_sfx); + break; + } default: assert("Not yet supported."); } delete current; @@ -262,12 +272,13 @@ void SFXManager::soundToggled(const bool on) } resumeAll(); - - const int sfx_amount = (int)m_all_sfx.size(); + m_all_sfx.lock(); + const int sfx_amount = (int)m_all_sfx.getData().size(); for (int n=0; nonSoundEnabledBack(); + m_all_sfx.getData()[n]->onSoundEnabledBack(); } + m_all_sfx.unlock(); } else { @@ -451,7 +462,14 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer, sfx->setMasterVolume(m_master_gain); - if (add_to_SFX_list) m_all_sfx.push_back(sfx); + if (add_to_SFX_list) + { + m_all_sfx.lock(); + m_all_sfx.getData().push_back(sfx); + m_all_sfx.unlock(); + } + else + printf(""); return sfx; } // createSoundSource @@ -511,21 +529,26 @@ void SFXManager::deleteSFXMapping(const std::string &name) */ void SFXManager::deleteSFX(SFXBase *sfx) { - if(sfx) sfx->stop(); + if(sfx) sfx->reallyStopNow(); std::vector::iterator i; - i=std::find(m_all_sfx.begin(), m_all_sfx.end(), sfx); + + // The whole block needs to be locked, otherwise the iterator + // could become invalid. + m_all_sfx.lock(); + i=std::find(m_all_sfx.getData().begin(), m_all_sfx.getData().end(), sfx); - if(i==m_all_sfx.end()) + if(i==m_all_sfx.getData().end()) { Log::warn("SFXManager", - "SFXManager::deleteSFX : Warning: sfx not found in list."); + "SFXManager::deleteSFX : Warning: sfx '%s' %lx not found in list.", + sfx->getBuffer()->getFileName().c_str(), sfx); return; } + m_all_sfx.getData().erase(i); delete sfx; - m_all_sfx.erase(i); - + m_all_sfx.unlock(); } // deleteSFX //---------------------------------------------------------------------------- @@ -535,11 +558,13 @@ void SFXManager::deleteSFX(SFXBase *sfx) */ void SFXManager::pauseAll() { - for (std::vector::iterator i=m_all_sfx.begin(); - i!=m_all_sfx.end(); i++) + m_all_sfx.lock(); + for (std::vector::iterator i= m_all_sfx.getData().begin(); + i!=m_all_sfx.getData().end(); i++) { (*i)->pause(); } // for i in m_all_sfx + m_all_sfx.unlock(); } // pauseAll //---------------------------------------------------------------------------- @@ -551,13 +576,15 @@ void SFXManager::resumeAll() // ignore unpausing if sound is disabled if (!sfxAllowed()) return; - for (std::vector::iterator i=m_all_sfx.begin(); - i!=m_all_sfx.end(); i++) + m_all_sfx.lock(); + for (std::vector::iterator i =m_all_sfx.getData().begin(); + i!=m_all_sfx.getData().end(); i++) { SFXStatus status = (*i)->getStatus(); // Initial happens when if (status==SFX_PAUSED) (*i)->resume(); } // for i in m_all_sfx + m_all_sfx.unlock(); } // resumeAll //----------------------------------------------------------------------------- @@ -594,11 +621,13 @@ void SFXManager::setMasterSFXVolume(float gain) // regular SFX { - for (std::vector::iterator i=m_all_sfx.begin(); - i!=m_all_sfx.end(); i++) + m_all_sfx.lock(); + for (std::vector::iterator i =m_all_sfx.getData().begin(); + i!=m_all_sfx.getData().end(); i++) { (*i)->setMasterVolume(m_master_gain); } // for i in m_all_sfx + m_all_sfx.unlock(); } // quick SFX diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 90e0ce323..00ca9375e 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -122,7 +122,7 @@ private: std::map m_all_sfx_types; /** The actual instances (sound sources) */ - std::vector m_all_sfx; + Synchronised > m_all_sfx; /** The list of sound effects to be played in the next update. */ Synchronised< std::vector > m_sfx_commands; @@ -150,6 +150,7 @@ private: virtual ~SFXManager(); static void* mainLoop(void *obj); + void deleteSFX(SFXBase *sfx); public: static void create(); static void destroy(); @@ -182,7 +183,6 @@ public: SFXBase* createSoundSource(const std::string &name, const bool addToSFXList=true); - void deleteSFX(SFXBase *sfx); void deleteSFXMapping(const std::string &name); void pauseAll(); void resumeAll(); diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 029f1d9f1..c596ac55b 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -182,9 +182,16 @@ void SFXOpenAL::setLoop(bool status) } // loop //----------------------------------------------------------------------------- -/** Stops playing this sound effect. +/** Queues a stop for this effect to the sound manager. */ void SFXOpenAL::stop() +{ + SFXManager::get()->queue(SFXManager::SFX_STOP, this); +} // stop +//----------------------------------------------------------------------------- +/** The sfx manager thread executes a stop for this sfx. + */ +void SFXOpenAL::reallyStopNow() { if(!m_ok) return; @@ -193,23 +200,39 @@ void SFXOpenAL::stop() alSourcei(m_soundSource, AL_LOOPING, AL_FALSE); alSourceStop(m_soundSource); SFXManager::checkError("stoping"); -} // stop +} // reallyStopNow + +//----------------------------------------------------------------------------- +/** Queues up a pause command for this sfx. + */ +void SFXOpenAL::pause() +{ + SFXManager::get()->queue(SFXManager::SFX_PAUSE, this); +} // pause //----------------------------------------------------------------------------- /** Pauses a SFX that's currently played. Nothing happens it the effect is * currently not being played. */ -void SFXOpenAL::pause() +void SFXOpenAL::reallyPauseNow() { if(!m_ok) return; alSourcePause(m_soundSource); SFXManager::checkError("pausing"); -} // pause +} // reallyPauseNow + +//----------------------------------------------------------------------------- +/** Queues up a resume command for this sound effect. + */ +void SFXOpenAL::resume() +{ + SFXManager::get()->queue(SFXManager::SFX_RESUME, this); +} // resume //----------------------------------------------------------------------------- /** Resumes a sound effect. */ -void SFXOpenAL::resume() +void SFXOpenAL::reallyResumeNow() { if (!m_ok) { @@ -222,7 +245,17 @@ void SFXOpenAL::resume() alSourcePlay(m_soundSource); SFXManager::checkError("resuming"); -} // resume +} // reallyResumeNow + +//----------------------------------------------------------------------------- +/** Queues up a delete request for this object. This is necessary to avoid + * a crash if the sfx manager thread might be delayed and access this object + * after it was deleted. + */ +void SFXOpenAL::deleteSFX() +{ + SFXManager::get()->queue(SFXManager::SFX_DELETE, this); +} // deleteSFX //----------------------------------------------------------------------------- /** This actually queues up the sfx in the sfx manager. It will be started diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 807111a33..0de11c78a 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -77,8 +77,12 @@ public: virtual void setLoop(bool status); virtual bool isPlaying(); virtual void stop(); + virtual void reallyStopNow(); virtual void pause(); + virtual void reallyPauseNow(); virtual void resume(); + virtual void reallyResumeNow(); + virtual void deleteSFX(); virtual void speed(float factor); virtual void position(const Vec3 &position); virtual void volume(float gain); diff --git a/src/graphics/hit_sfx.cpp b/src/graphics/hit_sfx.cpp index 53800b28c..507ce3cee 100644 --- a/src/graphics/hit_sfx.cpp +++ b/src/graphics/hit_sfx.cpp @@ -42,10 +42,7 @@ HitSFX::HitSFX(const Vec3& coord, const char* explosion_sound) */ HitSFX::~HitSFX() { - if (m_sfx->getStatus() == SFXManager::SFX_PLAYING) - m_sfx->stop(); - - SFXManager::get()->deleteSFX(m_sfx); + m_sfx->deleteSFX(); } // ~HitEffect //----------------------------------------------------------------------------- diff --git a/src/graphics/weather.cpp b/src/graphics/weather.cpp index 79f51b983..8162f8f11 100644 --- a/src/graphics/weather.cpp +++ b/src/graphics/weather.cpp @@ -51,11 +51,11 @@ Weather::Weather(bool lightning, std::string sound) Weather::~Weather() { if (m_thunder_sound != NULL) - SFXManager::get()->deleteSFX(m_thunder_sound); + m_thunder_sound->deleteSFX(); if (m_weather_sound != NULL) - SFXManager::get()->deleteSFX(m_weather_sound); -} + m_weather_sound->deleteSFX(); +} // ~Weather // ---------------------------------------------------------------------------- diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index ec6816354..02513b4a4 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -80,13 +80,13 @@ Attachment::~Attachment() if (m_bomb_sound) { - SFXManager::get()->deleteSFX(m_bomb_sound); + m_bomb_sound->deleteSFX(); m_bomb_sound = NULL; } if (m_bubble_explode_sound) { - SFXManager::get()->deleteSFX(m_bubble_explode_sound); + m_bubble_explode_sound->deleteSFX(); m_bubble_explode_sound = NULL; } } // ~Attachment @@ -139,7 +139,7 @@ void Attachment::set(AttachmentType type, float time, break; case ATTACH_BOMB: m_node->setMesh(attachment_manager->getMesh(type)); - if (m_bomb_sound) SFXManager::get()->deleteSFX(m_bomb_sound); + if (m_bomb_sound) m_bomb_sound->deleteSFX(); m_bomb_sound = SFXManager::get()->createSoundSource("clock"); m_bomb_sound->setLoop(true); m_bomb_sound->position(m_kart->getXYZ()); @@ -198,8 +198,7 @@ void Attachment::clear() if (m_bomb_sound) { - m_bomb_sound->stop(); - SFXManager::get()->deleteSFX(m_bomb_sound); + m_bomb_sound->deleteSFX(); m_bomb_sound = NULL; } @@ -460,8 +459,7 @@ void Attachment::update(float dt) if (m_bomb_sound) { - m_bomb_sound->stop(); - SFXManager::get()->deleteSFX(m_bomb_sound); + m_bomb_sound->deleteSFX(); m_bomb_sound = NULL; } } @@ -474,7 +472,7 @@ void Attachment::update(float dt) if (m_time_left < 0) { m_time_left = 0.0f; - if (m_bubble_explode_sound) SFXManager::get()->deleteSFX(m_bubble_explode_sound); + if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX(); m_bubble_explode_sound = SFXManager::get()->createSoundSource("bubblegum_explode"); m_bubble_explode_sound->position(m_kart->getXYZ()); m_bubble_explode_sound->play(); diff --git a/src/items/bowling.cpp b/src/items/bowling.cpp index ae0d821d7..28b239e47 100644 --- a/src/items/bowling.cpp +++ b/src/items/bowling.cpp @@ -87,9 +87,9 @@ Bowling::Bowling(AbstractKart *kart) */ Bowling::~Bowling() { - if(m_roll_sfx->getStatus()==SFXManager::SFX_PLAYING) - m_roll_sfx->stop(); - SFXManager::get()->deleteSFX(m_roll_sfx); + // This will stop the sfx and delete the object. + m_roll_sfx->deleteSFX(); + } // ~RubberBall // ----------------------------------------------------------------------------- diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index 6752edc56..9cdbcd8b0 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -53,7 +53,7 @@ Powerup::Powerup(AbstractKart* kart) */ Powerup::~Powerup() { - if(m_sound_use) SFXManager::get()->deleteSFX(m_sound_use); + if(m_sound_use) m_sound_use->deleteSFX(); } // ~Powerup //----------------------------------------------------------------------------- @@ -88,7 +88,7 @@ void Powerup::set(PowerupManager::PowerupType type, int n) if(m_sound_use != NULL) { - SFXManager::get()->deleteSFX(m_sound_use); + m_sound_use->deleteSFX(); m_sound_use = NULL; } diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 566e69e53..8f9309517 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -109,7 +109,7 @@ RubberBall::~RubberBall() { if(m_ping_sfx->getStatus()==SFXManager::SFX_PLAYING) m_ping_sfx->stop(); - SFXManager::get()->deleteSFX(m_ping_sfx); + m_ping_sfx->deleteSFX(); } // ~RubberBall // ---------------------------------------------------------------------------- diff --git a/src/items/swatter.cpp b/src/items/swatter.cpp index 78a44cc7a..60513aba3 100644 --- a/src/items/swatter.cpp +++ b/src/items/swatter.cpp @@ -100,7 +100,7 @@ Swatter::~Swatter() } if (m_swat_sound) { - SFXManager::get()->deleteSFX(m_swat_sound); + m_swat_sound->deleteSFX(); } } // ~Swatter diff --git a/src/karts/controller/player_controller.cpp b/src/karts/controller/player_controller.cpp index 61298f308..a7a1a3403 100644 --- a/src/karts/controller/player_controller.cpp +++ b/src/karts/controller/player_controller.cpp @@ -74,11 +74,11 @@ PlayerController::PlayerController(AbstractKart *kart, */ PlayerController::~PlayerController() { - SFXManager::get()->deleteSFX(m_bzzt_sound); - SFXManager::get()->deleteSFX(m_wee_sound ); - SFXManager::get()->deleteSFX(m_ugh_sound ); - SFXManager::get()->deleteSFX(m_grab_sound); - SFXManager::get()->deleteSFX(m_full_sound); + m_bzzt_sound->deleteSFX(); + m_wee_sound ->deleteSFX(); + m_ugh_sound ->deleteSFX(); + m_grab_sound->deleteSFX(); + m_full_sound->deleteSFX(); } // ~PlayerController //----------------------------------------------------------------------------- diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 3e8112ced..4c0430c74 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -246,15 +246,15 @@ Kart::~Kart() SFXManager::get()->deleteSFX(m_custom_sounds[n]); }*/ - SFXManager::get()->deleteSFX(m_engine_sound ); - SFXManager::get()->deleteSFX(m_crash_sound ); - SFXManager::get()->deleteSFX(m_skid_sound ); - SFXManager::get()->deleteSFX(m_goo_sound ); - SFXManager::get()->deleteSFX(m_beep_sound ); - SFXManager::get()->deleteSFX(m_boing_sound ); + m_engine_sound->deleteSFX(); + m_crash_sound ->deleteSFX(); + m_skid_sound ->deleteSFX(); + m_goo_sound ->deleteSFX(); + m_beep_sound ->deleteSFX(); + m_boing_sound ->deleteSFX(); delete m_kart_gfx; - if(m_terrain_sound) SFXManager::get()->deleteSFX(m_terrain_sound); - if(m_previous_terrain_sound) SFXManager::get()->deleteSFX(m_previous_terrain_sound); + if(m_terrain_sound) m_terrain_sound->deleteSFX(); + if(m_previous_terrain_sound) m_previous_terrain_sound->deleteSFX(); if(m_collision_particles) delete m_collision_particles; if(m_slipstream) delete m_slipstream; if(m_sky_particles_emitter) delete m_sky_particles_emitter; @@ -363,16 +363,15 @@ void Kart::reset() if(m_terrain_sound) { - SFXManager::get()->deleteSFX(m_terrain_sound); + m_terrain_sound->deleteSFX(); + m_terrain_sound = NULL; } if(m_previous_terrain_sound) { - SFXManager::get()->deleteSFX(m_previous_terrain_sound); + m_previous_terrain_sound->deleteSFX(); + m_previous_terrain_sound = NULL; } - m_terrain_sound = NULL; - m_previous_terrain_sound = NULL; - if(m_engine_sound) m_engine_sound->stop(); @@ -1430,7 +1429,7 @@ void Kart::handleMaterialSFX(const Material *material) // can be used again. if(m_previous_terrain_sound) { - SFXManager::get()->deleteSFX(m_previous_terrain_sound); + m_previous_terrain_sound->deleteSFX(); } m_previous_terrain_sound = m_terrain_sound; if(m_previous_terrain_sound) @@ -1467,7 +1466,7 @@ void Kart::handleMaterialSFX(const Material *material) // We don't modify the position of m_previous_terrain_sound // anymore, so that it keeps on playing at the place where the // kart left the material. - SFXManager::get()->deleteSFX(m_previous_terrain_sound); + m_previous_terrain_sound->deleteSFX(); m_previous_terrain_sound = NULL; } @@ -1592,7 +1591,7 @@ void Kart::handleMaterialGFX() (m_terrain_sound == NULL || m_terrain_sound->getStatus() == SFXManager::SFX_STOPPED)) { - if (m_previous_terrain_sound) SFXManager::get()->deleteSFX(m_previous_terrain_sound); + if (m_previous_terrain_sound) m_previous_terrain_sound->deleteSFX(); m_previous_terrain_sound = m_terrain_sound; if(m_previous_terrain_sound) m_previous_terrain_sound->setLoop(false); diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 9cbd969d2..8883d0aec 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -73,7 +73,7 @@ void LinearWorld::init() */ LinearWorld::~LinearWorld() { - SFXManager::get()->deleteSFX(m_last_lap_sfx); + m_last_lap_sfx->deleteSFX(); } // ~LinearWorld //----------------------------------------------------------------------------- diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index c853570fe..672411ac3 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -60,7 +60,7 @@ SoccerWorld::SoccerWorld() : WorldWithRank() */ SoccerWorld::~SoccerWorld() { - SFXManager::get()->deleteSFX(m_goal_sound); + m_goal_sound->deleteSFX(); } // ~SoccerWorld //----------------------------------------------------------------------------- diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index 1deeb3903..62419091e 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -74,9 +74,9 @@ void WorldStatus::reset() */ WorldStatus::~WorldStatus() { - SFXManager::get()->deleteSFX(m_prestart_sound); - SFXManager::get()->deleteSFX(m_start_sound); - SFXManager::get()->deleteSFX(m_track_intro_sound); + m_prestart_sound->deleteSFX(); + m_start_sound->deleteSFX(); + m_track_intro_sound->deleteSFX(); IrrlichtDevice *device = irr_driver->getDevice(); if (device->getTimer()->isStopped()) diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index c6ba494f2..7b7f7af29 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -382,8 +382,9 @@ void TrackObjectPresentationMesh::reset() // ---------------------------------------------------------------------------- -TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_node, scene::ISceneNode* parent) : - TrackObjectPresentation(xml_node) +TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_node, + scene::ISceneNode* parent) + : TrackObjectPresentation(xml_node) { // TODO: respect 'parent' if any @@ -440,8 +441,9 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_no { ItemManager::get()->newItem(m_init_xyz, trigger_distance, this); } -} +} // TrackObjectPresentationSound +// ---------------------------------------------------------------------------- void TrackObjectPresentationSound::update(float dt) { if (m_sound != NULL) @@ -451,16 +453,18 @@ void TrackObjectPresentationSound::update(float dt) // moved m_sound->position(m_xyz); } -} +} // update +// ---------------------------------------------------------------------------- void TrackObjectPresentationSound::onTriggerItemApproached(Item* who) { if (m_sound != NULL && m_sound->getStatus() != SFXManager::SFX_PLAYING) { m_sound->play(); } -} +} // onTriggerItemApproached +// ---------------------------------------------------------------------------- void TrackObjectPresentationSound::triggerSound(bool loop) { if (m_sound != NULL) @@ -468,34 +472,37 @@ void TrackObjectPresentationSound::triggerSound(bool loop) m_sound->setLoop(loop); m_sound->play(); } -} +} // triggerSound +// ---------------------------------------------------------------------------- void TrackObjectPresentationSound::stopSound() { if (m_sound != NULL) m_sound->stop(); -} +} // stopSound +// ---------------------------------------------------------------------------- TrackObjectPresentationSound::~TrackObjectPresentationSound() { if (m_sound) { - //delete m_sound->getBuffer(); - SFXManager::get()->deleteSFX(m_sound); + m_sound->deleteSFX(); } -} +} // ~TrackObjectPresentationSound -void TrackObjectPresentationSound::move(const core::vector3df& xyz, const core::vector3df& hpr, +// ---------------------------------------------------------------------------- +void TrackObjectPresentationSound::move(const core::vector3df& xyz, + const core::vector3df& hpr, const core::vector3df& scale) { m_xyz = xyz; if (m_sound != NULL) m_sound->position(xyz); -} +} // move // ---------------------------------------------------------------------------- - -TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode& xml_node, scene::ISceneNode* parent) : - TrackObjectPresentationSceneNode(xml_node) +TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode& xml_node, + scene::ISceneNode* parent) + : TrackObjectPresentationSceneNode(xml_node) { std::string texture_name; float width, height; @@ -529,6 +536,7 @@ TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode m_node->setPosition(m_init_xyz); } +// ---------------------------------------------------------------------------- void TrackObjectPresentationBillboard::update(float dt) { if (m_fade_out_when_close) @@ -554,6 +562,7 @@ void TrackObjectPresentationBillboard::update(float dt) } } +// ---------------------------------------------------------------------------- TrackObjectPresentationBillboard::~TrackObjectPresentationBillboard() { if (m_node) @@ -613,6 +622,7 @@ TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode } } +// ---------------------------------------------------------------------------- TrackObjectPresentationParticles::~TrackObjectPresentationParticles() { if (m_emitter) @@ -626,6 +636,7 @@ TrackObjectPresentationParticles::~TrackObjectPresentationParticles() } } +// ---------------------------------------------------------------------------- void TrackObjectPresentationParticles::update(float dt) { if (m_emitter != NULL) @@ -634,6 +645,7 @@ void TrackObjectPresentationParticles::update(float dt) } } +// ---------------------------------------------------------------------------- void TrackObjectPresentationParticles::triggerParticles() { if (m_emitter != NULL) @@ -671,6 +683,7 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_no } } +// ---------------------------------------------------------------------------- TrackObjectPresentationLight::~TrackObjectPresentationLight() { } @@ -693,6 +706,7 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(const ItemManager::get()->newItem(m_init_xyz, trigger_distance, this); } +// ---------------------------------------------------------------------------- void TrackObjectPresentationActionTrigger::onTriggerItemApproached(Item* who) { if (!m_action_active) return; From 2b90cb2a69d5bc4464c46b4a1347583b606f73d0 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sun, 12 Oct 2014 20:12:40 -0400 Subject: [PATCH 059/112] Use case-insensitive comparison for animated textures, for some reason --- src/tracks/track.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 076458a5b..1319d4084 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1419,6 +1419,9 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml) continue; } + // to lower case, for case-insensitive comparison + name = StringUtils::toLowerCase(name); + for(unsigned int i=0; igetMaterialCount(); i++) { video::SMaterial &irrMaterial=node->getMaterial(i); @@ -1426,9 +1429,13 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml) { video::ITexture* t=irrMaterial.getTexture(j); if(!t) continue; - const std::string texture_name = + std::string texture_name = StringUtils::getBasename(core::stringc(t->getName()).c_str()); - if(texture_name!=name) continue; + + // to lower case, for case-insensitive comparison + texture_name = StringUtils::toLowerCase(texture_name); + + if (texture_name != name) continue; core::matrix4 *m = &irrMaterial.getTextureMatrix(j); m_animated_textures.push_back(new MovingTexture(m, *texture_node)); } // for j Date: Mon, 13 Oct 2014 22:04:46 +1100 Subject: [PATCH 060/112] Removed status check when queueing sfx, to get more consistent runtime behaviour. --- src/audio/sfx_manager.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 968adc5d9..9842e687f 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -167,10 +167,6 @@ SFXManager::~SFXManager() */ void SFXManager::queue(SFXCommands command, SFXBase *sfx) { - // Don't add sfx that are either not working correctly (e.g. because sfx - // are disabled); - if(sfx && sfx->getStatus()==SFX_UNKNOWN ) return; - SFXCommand *sfx_command = new SFXCommand(command, sfx); m_sfx_commands.lock(); @@ -255,7 +251,7 @@ void* SFXManager::mainLoop(void *obj) } // mainLoop //---------------------------------------------------------------------------- -/** Called then sound is globally switched on or off. It either pauses or +/** Called when sound is globally switched on or off. It either pauses or * resumes all sound effects. * \param on If sound is switched on or off. */ From 5cf7b0dca9575f0247efb7ac6ce07b85e05820cd Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 13 Oct 2014 22:06:05 +1100 Subject: [PATCH 061/112] Added computation of the duration of a sound buffer (unused atm). --- src/audio/sfx_buffer.cpp | 54 ++++++++++++++++++++++++------- src/audio/sfx_buffer.hpp | 70 ++++++++++++++++++++++++---------------- 2 files changed, 86 insertions(+), 38 deletions(-) diff --git a/src/audio/sfx_buffer.cpp b/src/audio/sfx_buffer.cpp index 910b29f88..0ac37f2d2 100644 --- a/src/audio/sfx_buffer.cpp +++ b/src/audio/sfx_buffer.cpp @@ -36,27 +36,37 @@ #endif //---------------------------------------------------------------------------- - +/** Creates a sfx. The parameter are taken from the parameters: + * \param file File name of the buffer. + * \param positional If the sfx is positional. + * \param rolloff Rolloff value of this sfx. + * \param max_dist Maximum distance the sfx can be heard. + * \param gain Gain value of this sfx. + */ SFXBuffer::SFXBuffer(const std::string& file, bool positional, float rolloff, - float max_width, + float max_dist, float gain) { m_buffer = 0; m_gain = 1.0f; m_rolloff = 0.1f; m_loaded = false; - m_max_dist = max_width; + m_max_dist = max_dist; + m_duration = -1.0f; m_file = file; m_rolloff = rolloff; m_positional = positional; m_gain = gain; -} +} // SFXBuffer //---------------------------------------------------------------------------- - +/** Constructor getting the sfx parameters from an XML node. + * \param file File name of the data. + * \param node XML Node with the data for this sfx. + */ SFXBuffer::SFXBuffer(const std::string& file, const XMLNode* node) { @@ -64,6 +74,7 @@ SFXBuffer::SFXBuffer(const std::string& file, m_gain = 1.0f; m_rolloff = 0.1f; m_max_dist = 300.0f; + m_duration = -1.0f; m_positional = false; m_loaded = false; m_file = file; @@ -72,10 +83,15 @@ SFXBuffer::SFXBuffer(const std::string& file, node->get("positional", &m_positional ); node->get("volume", &m_gain ); node->get("max_dist", &m_max_dist ); -} + node->get("duration", &m_duration ); +} // SFXBuffer(XMLNode) //---------------------------------------------------------------------------- - +/** \brief load the buffer from file into OpenAL. + * \note If this buffer is already loaded, this call does nothing and + * returns false. + * \return Whether loading was successful. + */ bool SFXBuffer::load() { if (UserConfigParams::m_sfx == false) return false; @@ -103,9 +119,13 @@ bool SFXBuffer::load() m_loaded = true; return true; -} +} // load //---------------------------------------------------------------------------- +/** \brief Frees the loaded buffer. + * Cannot appear in destructor because copy-constructors may be used, + * and the OpenAL source must not be deleted on a copy + */ void SFXBuffer::unload() { @@ -117,7 +137,7 @@ void SFXBuffer::unload() } #endif m_loaded = false; -} +} // unload //---------------------------------------------------------------------------- /** Load a vorbis file into an OpenAL buffer @@ -164,7 +184,7 @@ bool SFXBuffer::loadVorbisBuffer(const std::string &name, ALuint buffer) if(!data) { ov_clear(&oggFile); - Log::error("SFXBuffer", "[SFXBuffer] loadVorbisBuffer() - Error : LoadVorbisBuffer() - couldn't allocate decode buffer\n"); + Log::error("SFXBuffer", "[SFXBuffer] Could not allocate decode buffer."); return false; } @@ -188,9 +208,21 @@ bool SFXBuffer::loadVorbisBuffer(const std::string &name, ALuint buffer) ov_clear(&oggFile); fclose(file); + + // Allow the xml data to overwrite the duration, but if there is no + // duration (which is the norm), compute it: + if(m_duration < 0) + { + ALint buffer_size, frequency, bits_per_sample, channels; + alGetBufferi(buffer, AL_SIZE, &buffer_size ); + alGetBufferi(buffer, AL_FREQUENCY, &frequency ); + alGetBufferi(buffer, AL_CHANNELS, &channels ); + alGetBufferi(buffer, AL_BITS, &bits_per_sample); + m_duration = float(buffer_size) / (frequency*channels*(bits_per_sample / 8)); + } return success; #else return false; #endif -} +} // loadVorbisBuffer diff --git a/src/audio/sfx_buffer.hpp b/src/audio/sfx_buffer.hpp index 98ffbc8e4..e0583b67c 100644 --- a/src/audio/sfx_buffer.hpp +++ b/src/audio/sfx_buffer.hpp @@ -46,18 +46,32 @@ class SFXBuffer { private: + LEAK_CHECK() + /** Whether the contents of the file was loaded */ bool m_loaded; /** The file that contains the OGG audio data */ std::string m_file; + /** The openal buffer id. */ ALuint m_buffer; + + /** If the sound is positional. */ bool m_positional; + + /** The roll-off value. */ float m_rolloff; + + /** The volume gain value. */ float m_gain; + + /** Maximum distance the sfx can be heard. */ float m_max_dist; + /** Duration of the sfx. */ + float m_duration; + bool loadVorbisBuffer(const std::string &name, ALuint buffer); public: @@ -70,41 +84,43 @@ public: SFXBuffer(const std::string& file, const XMLNode* node); - ~SFXBuffer() { - } + } // ~SFXBuffer - /** - * \brief load the buffer from file into OpenAL. - * \note If this buffer is already loaded, this call does nothing and returns false - * \return whether loading was successful - */ - bool load(); - /** - * \brief Frees the loaded buffer - * Cannot appear in destructor because copy-constructors may be used, - * and the OpenAL source must not be deleted on a copy - */ - void unload(); + bool load(); + void unload(); + // ------------------------------------------------------------------------ /** \return whether this buffer was loaded from disk */ - bool isLoaded() const { return m_loaded; } - + bool isLoaded() const { return m_loaded; } + // ------------------------------------------------------------------------ /** Only returns a valid buffer if isLoaded() returned true */ - ALuint getBufferID() const { return m_buffer; } + ALuint getBufferID() const { return m_buffer; } + // ------------------------------------------------------------------------ + /** Returns if the buffer is positional. */ + bool isPositional() const { return m_positional; } + // ------------------------------------------------------------------------ + /** Returns the rolloff value of this buffer. */ + float getRolloff() const { return m_rolloff; } + // ------------------------------------------------------------------------ + /** Returns the gain for this sfx. */ + float getGain() const { return m_gain; } + // ------------------------------------------------------------------------ + /** Returns the maximum distance this sfx can be heard. */ + float getMaxDist() const { return m_max_dist; } + // ------------------------------------------------------------------------ + /** Returns the file name of this buffer. */ + const std::string& getFileName() const { return m_file; } + // ------------------------------------------------------------------------ + /** Sets if this buffer is positional or not. */ + void setPositional(bool positional) { m_positional = positional; } + // ------------------------------------------------------------------------ + /** Returns how long this buffer will play. */ + float getDuration() const { return m_duration; } - bool isPositional() const { return m_positional; } - float getRolloff() const { return m_rolloff; } - float getGain() const { return m_gain; } - float getMaxDist() const { return m_max_dist; } - std::string getFileName() const { return m_file; } - - void setPositional(bool positional) { m_positional = positional; } - - LEAK_CHECK() -}; +}; // class SFXBuffer #endif // HEADER_SFX_BUFFER_HPP From 665f14692381aa198396cbec95f9a31505095b0b Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 14 Oct 2014 08:05:04 +1100 Subject: [PATCH 062/112] Moved SFXStatus enum to SFXBase. --- src/audio/dummy_sfx.hpp | 3 +- src/audio/sfx_base.hpp | 11 ++- src/audio/sfx_manager.cpp | 8 +- src/audio/sfx_manager.hpp | 7 -- src/audio/sfx_openal.cpp | 109 +++++++++++---------- src/audio/sfx_openal.hpp | 13 ++- src/graphics/hit_sfx.cpp | 6 +- src/graphics/material.cpp | 4 +- src/items/bowling.cpp | 2 +- src/items/rubber_ball.cpp | 4 +- src/karts/controller/player_controller.cpp | 2 +- src/karts/kart.cpp | 13 +-- src/modes/linear_world.cpp | 2 +- src/modes/soccer_world.cpp | 2 +- src/modes/world_status.cpp | 2 +- src/states_screens/race_result_gui.cpp | 4 +- src/tracks/track_object_presentation.cpp | 2 +- 17 files changed, 100 insertions(+), 94 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index adf73d184..a14accbf7 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -23,7 +23,6 @@ #include "audio/sfx_base.hpp" - /** * \brief Dummy sound when ogg or openal aren't available * \ingroup audio @@ -50,7 +49,7 @@ public: virtual void deleteSFX() { delete this; } virtual void speed(float factor) {} virtual void volume(float gain) {} - virtual SFXManager::SFXStatus getStatus() { return SFXManager::SFX_STOPPED; } + virtual SFXStatus getStatus() { return SFX_STOPPED; } virtual void onSoundEnabledBack() {} virtual void setRolloff(float rolloff) {} virtual bool isPlaying() { return false; } diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index 3ade04eb8..7fa948390 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -42,6 +42,13 @@ class Vec3; class SFXBase : public NoCopy { public: + /** Status of a sound effect. */ + enum SFXStatus + { + SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2, + SFX_INITIAL = 3 + }; + virtual ~SFXBase() {} /** Late creation, if SFX was initially disabled */ @@ -64,9 +71,9 @@ public: virtual void onSoundEnabledBack() = 0; virtual void setRolloff(float rolloff) = 0; virtual const SFXBuffer* getBuffer() const = 0; - virtual SFXManager::SFXStatus getStatus() = 0; + virtual SFXStatus getStatus() = 0; -}; // SfxBase +}; // SFXBase #endif // HEADER_SFX_HPP diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 9842e687f..4d64e9919 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -167,6 +167,10 @@ SFXManager::~SFXManager() */ void SFXManager::queue(SFXCommands command, SFXBase *sfx) { + // Don't add sfx that are either not working correctly (e.g. because sfx + // are disabled); + if(sfx && sfx->getStatus()==SFXBase::SFX_UNKNOWN) return; + SFXCommand *sfx_command = new SFXCommand(command, sfx); m_sfx_commands.lock(); @@ -576,9 +580,7 @@ void SFXManager::resumeAll() for (std::vector::iterator i =m_all_sfx.getData().begin(); i!=m_all_sfx.getData().end(); i++) { - SFXStatus status = (*i)->getStatus(); - // Initial happens when - if (status==SFX_PAUSED) (*i)->resume(); + (*i)->resume(); } // for i in m_all_sfx m_all_sfx.unlock(); } // resumeAll diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 00ca9375e..f559407d4 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -89,13 +89,6 @@ public: NUM_CUSTOMS }; - /** Status of a sound effect. */ - enum SFXStatus - { - SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2, - SFX_INITIAL = 3 - }; - private: /** Data structure for the queue, which stores a sfx and the command to diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index c596ac55b..2497b1056 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -40,16 +40,16 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBuffer) : SFXBase() { - m_soundBuffer = buffer; - m_soundSource = 0; - m_ok = false; - m_is_playing = false; - m_positional = positional; - m_defaultGain = gain; - m_loop = false; - m_gain = -1.0f; - m_master_gain = 1.0f; - m_owns_buffer = ownsBuffer; + m_sound_buffer = buffer; + m_sound_source = 0; + m_ok = false; + m_is_playing = false; + m_positional = positional; + m_defaultGain = gain; + m_loop = false; + m_gain = -1.0f; + m_master_gain = 1.0f; + m_owns_buffer = ownsBuffer; // Don't initialise anything else if the sfx manager was not correctly // initialised. First of all the initialisation will not work, and it @@ -66,13 +66,13 @@ SFXOpenAL::~SFXOpenAL() { if (m_ok) { - alDeleteSources(1, &m_soundSource); + alDeleteSources(1, &m_sound_source); } - if (m_owns_buffer && m_soundBuffer != NULL) + if (m_owns_buffer && m_sound_buffer != NULL) { - m_soundBuffer->unload(); - delete m_soundBuffer; + m_sound_buffer->unload(); + delete m_sound_buffer; } } // ~SFXOpenAL @@ -80,40 +80,40 @@ SFXOpenAL::~SFXOpenAL() bool SFXOpenAL::init() { - alGenSources(1, &m_soundSource ); + alGenSources(1, &m_sound_source ); if (!SFXManager::checkError("generating a source")) return false; - assert( alIsBuffer(m_soundBuffer->getBufferID()) ); - assert( alIsSource(m_soundSource) ); + assert( alIsBuffer(m_sound_buffer->getBufferID()) ); + assert( alIsSource(m_sound_source) ); //Log::info("SFXOpenAL", "Setting a source with buffer, %p, rolloff %f, gain = %f, position = %s", - // m_soundBuffer, rolloff, m_defaultGain, positional ? "true" : "false"); + // m_sound_buffer, rolloff, m_defaultGain, positional ? "true" : "false"); - alSourcei (m_soundSource, AL_BUFFER, m_soundBuffer->getBufferID()); + alSourcei (m_sound_source, AL_BUFFER, m_sound_buffer->getBufferID()); if (!SFXManager::checkError("attaching the buffer to the source")) return false; - alSource3f(m_soundSource, AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(m_soundSource, AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(m_soundSource, AL_DIRECTION, 0.0, 0.0, 0.0); + alSource3f(m_sound_source, AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(m_sound_source, AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(m_sound_source, AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (m_soundSource, AL_ROLLOFF_FACTOR, m_soundBuffer->getRolloff()); - alSourcef (m_soundSource, AL_MAX_DISTANCE, m_soundBuffer->getMaxDist()); + alSourcef (m_sound_source, AL_ROLLOFF_FACTOR, m_sound_buffer->getRolloff()); + alSourcef (m_sound_source, AL_MAX_DISTANCE, m_sound_buffer->getMaxDist()); if (m_gain < 0.0f) { - alSourcef (m_soundSource, AL_GAIN, m_defaultGain * m_master_gain); + alSourcef (m_sound_source, AL_GAIN, m_defaultGain * m_master_gain); } else { - alSourcef (m_soundSource, AL_GAIN, m_gain * m_master_gain); + alSourcef (m_sound_source, AL_GAIN, m_gain * m_master_gain); } - if (m_positional) alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_FALSE); - else alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_TRUE); + if (m_positional) alSourcei (m_sound_source, AL_SOURCE_RELATIVE, AL_FALSE); + else alSourcei (m_sound_source, AL_SOURCE_RELATIVE, AL_TRUE); - alSourcei(m_soundSource, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE); + alSourcei(m_sound_source, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE); m_ok = SFXManager::checkError("setting up the source"); @@ -137,7 +137,7 @@ void SFXOpenAL::speed(float factor) { factor = 0.5f; } - alSourcef(m_soundSource,AL_PITCH,factor); + alSourcef(m_sound_source,AL_PITCH,factor); SFXManager::checkError("changing the speed"); } // speed @@ -151,7 +151,7 @@ void SFXOpenAL::volume(float gain) if(!m_ok) return; - alSourcef(m_soundSource, AL_GAIN, m_gain * m_master_gain); + alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain); SFXManager::checkError("setting volume"); } // volume @@ -163,7 +163,7 @@ void SFXOpenAL::setMasterVolume(float gain) if(!m_ok) return; - alSourcef(m_soundSource, AL_GAIN, + alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); SFXManager::checkError("setting volume"); } //setMasterVolume @@ -177,7 +177,7 @@ void SFXOpenAL::setLoop(bool status) if(!m_ok) return; - alSourcei(m_soundSource, AL_LOOPING, status ? AL_TRUE : AL_FALSE); + alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE); SFXManager::checkError("looping"); } // loop @@ -197,8 +197,8 @@ void SFXOpenAL::reallyStopNow() m_is_playing = false; m_loop = false; - alSourcei(m_soundSource, AL_LOOPING, AL_FALSE); - alSourceStop(m_soundSource); + alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); + alSourceStop(m_sound_source); SFXManager::checkError("stoping"); } // reallyStopNow @@ -217,7 +217,7 @@ void SFXOpenAL::pause() void SFXOpenAL::reallyPauseNow() { if(!m_ok) return; - alSourcePause(m_soundSource); + alSourcePause(m_sound_source); SFXManager::checkError("pausing"); } // reallyPauseNow @@ -243,7 +243,8 @@ void SFXOpenAL::reallyResumeNow() if (!m_ok) return; } - alSourcePlay(m_soundSource); + if(getStatus()==SFX_PAUSED) + alSourcePlay(m_sound_source); SFXManager::checkError("resuming"); } // reallyResumeNow @@ -285,7 +286,7 @@ void SFXOpenAL::reallyPlayNow() if (!m_ok) return; } - alSourcePlay(m_soundSource); + alSourcePlay(m_sound_source); SFXManager::checkError("playing"); } // reallyPlayNow @@ -307,7 +308,7 @@ void SFXOpenAL::position(const Vec3 &position) return; if (!m_ok) { - Log::warn("SFX", "Position called on non-ok SFX <%s>", m_soundBuffer->getFileName().c_str()); + Log::warn("SFX", "Position called on non-ok SFX <%s>", m_sound_buffer->getFileName().c_str()); return; } if (!m_positional) @@ -322,16 +323,16 @@ void SFXOpenAL::position(const Vec3 &position) return; } - alSource3f(m_soundSource, AL_POSITION, + alSource3f(m_sound_source, AL_POSITION, (float)position.getX(), (float)position.getY(), (float)position.getZ()); - if (SFXManager::get()->getListenerPos().distance(position) > m_soundBuffer->getMaxDist()) + if (SFXManager::get()->getListenerPos().distance(position) > m_sound_buffer->getMaxDist()) { - alSourcef(m_soundSource, AL_GAIN, 0); + alSourcef(m_sound_source, AL_GAIN, 0); } else { - alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); + alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); } SFXManager::checkError("positioning"); @@ -340,19 +341,19 @@ void SFXOpenAL::position(const Vec3 &position) //----------------------------------------------------------------------------- /** Returns the status of this sound effect. */ -SFXManager::SFXStatus SFXOpenAL::getStatus() +SFXBase::SFXStatus SFXOpenAL::getStatus() { - if(!m_ok) return SFXManager::SFX_UNKNOWN; + if(!m_ok) return SFX_UNKNOWN; int state = 0; - alGetSourcei(m_soundSource, AL_SOURCE_STATE, &state); + alGetSourcei(m_sound_source, AL_SOURCE_STATE, &state); switch(state) { - case AL_STOPPED: return SFXManager::SFX_STOPPED; - case AL_PLAYING: return SFXManager::SFX_PLAYING; - case AL_PAUSED: return SFXManager::SFX_PAUSED; - case AL_INITIAL: return SFXManager::SFX_INITIAL; - default: return SFXManager::SFX_UNKNOWN; + case AL_STOPPED: return SFX_STOPPED; + case AL_PLAYING: return SFX_PLAYING; + case AL_PAUSED: return SFX_PAUSED; + case AL_INITIAL: return SFX_INITIAL; + default: return SFX_UNKNOWN; } } // getStatus @@ -365,10 +366,10 @@ void SFXOpenAL::onSoundEnabledBack() if (!m_ok) init(); if (m_ok) { - alSourcef(m_soundSource, AL_GAIN, 0); + alSourcef(m_sound_source, AL_GAIN, 0); play(); pause(); - alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); + alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); } } } @@ -377,7 +378,7 @@ void SFXOpenAL::onSoundEnabledBack() void SFXOpenAL::setRolloff(float rolloff) { - alSourcef (m_soundSource, AL_ROLLOFF_FACTOR, rolloff); + alSourcef (m_sound_source, AL_ROLLOFF_FACTOR, rolloff); } #endif //if HAVE_OGGVORBIS diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 0de11c78a..8b63fc41a 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -28,7 +28,6 @@ # include #endif #include "audio/sfx_base.hpp" -#include "audio/sfx_manager.hpp" #include "utils/leak_check.hpp" /** @@ -38,8 +37,12 @@ class SFXOpenAL : public SFXBase { private: - SFXBuffer* m_soundBuffer; //!< Buffers hold sound data. - ALuint m_soundSource; //!< Sources are points emitting sound. + /** Buffers hold sound data. */ + SFXBuffer* m_sound_buffer; + + /** Sources are points emitting sound. */ + ALuint m_sound_source; + bool m_ok; bool m_positional; float m_defaultGain; @@ -87,11 +90,11 @@ public: virtual void position(const Vec3 &position); virtual void volume(float gain); virtual void setMasterVolume(float gain); - virtual SFXManager::SFXStatus getStatus(); + virtual SFXStatus getStatus(); virtual void onSoundEnabledBack(); virtual void setRolloff(float rolloff); - virtual const SFXBuffer* getBuffer() const { return m_soundBuffer; } + virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; } LEAK_CHECK() diff --git a/src/graphics/hit_sfx.cpp b/src/graphics/hit_sfx.cpp index 507ce3cee..391d7118a 100644 --- a/src/graphics/hit_sfx.cpp +++ b/src/graphics/hit_sfx.cpp @@ -64,7 +64,7 @@ void HitSFX::setPlayerKartHit() */ bool HitSFX::updateAndDelete(float dt) { - SFXManager::SFXStatus status = m_sfx->getStatus(); - if(status==SFXManager::SFX_INITIAL) return false; - return status!= SFXManager::SFX_PLAYING; + SFXBase::SFXStatus status = m_sfx->getStatus(); + if(status==SFXBase::SFX_INITIAL) return false; + return status!= SFXBase::SFX_PLAYING; } // updateAndDelete diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index b9244c1a6..725c0908c 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -646,14 +646,14 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) con if (speed < 0) speed = -speed; // If we paused it due to too low speed earlier, we can continue now. - if (sfx->getStatus() == SFXManager::SFX_PAUSED) + if (sfx->getStatus() == SFXBase::SFX_PAUSED) { if (speedplay(); } - else if (sfx->getStatus() == SFXManager::SFX_PLAYING) + else if (sfx->getStatus() == SFXBase::SFX_PLAYING) { if (speedgetStatus()==SFXManager::SFX_PLAYING) + if (m_roll_sfx->getStatus()==SFXBase::SFX_PLAYING) m_roll_sfx->position(getXYZ()); return false; diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 8f9309517..f3b6b5f19 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -107,7 +107,7 @@ RubberBall::RubberBall(AbstractKart *kart) */ RubberBall::~RubberBall() { - if(m_ping_sfx->getStatus()==SFXManager::SFX_PLAYING) + if(m_ping_sfx->getStatus()==SFXBase::SFX_PLAYING) m_ping_sfx->stop(); m_ping_sfx->deleteSFX(); } // ~RubberBall @@ -541,7 +541,7 @@ float RubberBall::updateHeight() if(m_height_timer>m_interval) { m_height_timer -= m_interval; - if(m_ping_sfx->getStatus()!=SFXManager::SFX_PLAYING) + if(m_ping_sfx->getStatus()!=SFXBase::SFX_PLAYING) { m_ping_sfx->position(getXYZ()); m_ping_sfx->play(); diff --git a/src/karts/controller/player_controller.cpp b/src/karts/controller/player_controller.cpp index a7a1a3403..d4a6e47eb 100644 --- a/src/karts/controller/player_controller.cpp +++ b/src/karts/controller/player_controller.cpp @@ -439,7 +439,7 @@ void PlayerController::handleZipper(bool play_sound) // Only play a zipper sound if it's not already playing, and // if the material has changed (to avoid machine gun effect // on conveyor belt zippers). - if (play_sound || (m_wee_sound->getStatus() != SFXManager::SFX_PLAYING && + if (play_sound || (m_wee_sound->getStatus() != SFXBase::SFX_PLAYING && m_kart->getMaterial()!=m_kart->getLastMaterial() ) ) { m_wee_sound->play(); diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 4c0430c74..b3daca52c 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1079,6 +1079,7 @@ void Kart::eliminate() */ void Kart::update(float dt) { + Log::verbose("sfx", "%s crash state %d", getIdent().c_str(), m_crash_sound->getStatus()); if ( UserConfigParams::m_graphical_effects ) { // update star effect (call will do nothing if stars are not activated) @@ -1461,7 +1462,7 @@ void Kart::handleMaterialSFX(const Material *material) } if(m_previous_terrain_sound && - m_previous_terrain_sound->getStatus()==SFXManager::SFX_STOPPED) + m_previous_terrain_sound->getStatus()==SFXBase::SFX_STOPPED) { // We don't modify the position of m_previous_terrain_sound // anymore, so that it keeps on playing at the place where the @@ -1477,8 +1478,8 @@ void Kart::handleMaterialSFX(const Material *material) // terrain sound is not necessarily a looping sound so check its status before // setting its speed, to avoid 'ressuscitating' sounds that had already stopped if(m_terrain_sound && - (m_terrain_sound->getStatus()==SFXManager::SFX_PLAYING || - m_terrain_sound->getStatus()==SFXManager::SFX_PAUSED)) + (m_terrain_sound->getStatus()==SFXBase::SFX_PLAYING || + m_terrain_sound->getStatus()==SFXBase::SFX_PAUSED)) { m_terrain_sound->position(getXYZ()); material->setSFXSpeed(m_terrain_sound, m_speed, m_schedule_pause); @@ -1589,7 +1590,7 @@ void Kart::handleMaterialGFX() const std::string &s = surface_material->getSFXName(); if (s != "" && !dynamic_cast(getKartAnimation())&& (m_terrain_sound == NULL || - m_terrain_sound->getStatus() == SFXManager::SFX_STOPPED)) + m_terrain_sound->getStatus() == SFXBase::SFX_STOPPED)) { if (m_previous_terrain_sound) m_previous_terrain_sound->deleteSFX(); m_previous_terrain_sound = m_terrain_sound; @@ -1892,12 +1893,12 @@ void Kart::crashed(const Material* m, AbstractKart *k) // it's not already playing. if (isShielded() || (k != NULL && k->isShielded())) { - if (m_boing_sound->getStatus() != SFXManager::SFX_PLAYING) + if (m_boing_sound->getStatus() != SFXBase::SFX_PLAYING) m_boing_sound->play(); } else { - if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING) + if(m_crash_sound->getStatus() != SFXBase::SFX_PLAYING) m_crash_sound->play(); } } diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 8883d0aec..03086a353 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -155,7 +155,7 @@ void LinearWorld::update(float dt) WorldWithRank::update(dt); if (m_last_lap_sfx_playing && - m_last_lap_sfx->getStatus() != SFXManager::SFX_PLAYING) + m_last_lap_sfx->getStatus() != SFXBase::SFX_PLAYING) { if(music_manager->getCurrentMusic()) music_manager->getCurrentMusic()->resetTemporaryVolume(); diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 672411ac3..022ffc9f0 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -121,7 +121,7 @@ void SoccerWorld::reset() } if (m_goal_sound != NULL && - m_goal_sound->getStatus() == SFXManager::SFX_PLAYING) + m_goal_sound->getStatus() == SFXBase::SFX_PLAYING) { m_goal_sound->stop(); } diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index 62419091e..a969e7efd 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -162,7 +162,7 @@ void WorldStatus::update(const float dt) // ... phase. Since the sound effect is about 3 seconds // long, we use the aux timer to force the next phase // after 3.5 seconds. - if (m_track_intro_sound->getStatus() == SFXManager::SFX_PLAYING && + if (m_track_intro_sound->getStatus() == SFXBase::SFX_PLAYING && m_auxiliary_timer < 3.5f) return; diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 6dc363416..86a25afd3 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -116,7 +116,7 @@ void RaceResultGUI::tearDown() m_font->setMonospaceDigits(m_was_monospace); if (m_finish_sound != NULL && - m_finish_sound->getStatus() == SFXManager::SFX_PLAYING) + m_finish_sound->getStatus() == SFXBase::SFX_PLAYING) { m_finish_sound->stop(); } @@ -600,7 +600,7 @@ void RaceResultGUI::onUpdate(float dt) renderGlobal(dt); if (m_finish_sound != NULL && - m_finish_sound->getStatus() != SFXManager::SFX_PLAYING) + m_finish_sound->getStatus() != SFXBase::SFX_PLAYING) { try { diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 7b7f7af29..3ef6c8d56 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -458,7 +458,7 @@ void TrackObjectPresentationSound::update(float dt) // ---------------------------------------------------------------------------- void TrackObjectPresentationSound::onTriggerItemApproached(Item* who) { - if (m_sound != NULL && m_sound->getStatus() != SFXManager::SFX_PLAYING) + if (m_sound != NULL && m_sound->getStatus() != SFXBase::SFX_PLAYING) { m_sound->play(); } From d753fab7dba3710c989d82a507ba0497fa7e1e06 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 14 Oct 2014 09:01:13 +1100 Subject: [PATCH 063/112] Removed debug output. --- src/karts/kart.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index b3daca52c..fd66b8ebc 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1079,7 +1079,6 @@ void Kart::eliminate() */ void Kart::update(float dt) { - Log::verbose("sfx", "%s crash state %d", getIdent().c_str(), m_crash_sound->getStatus()); if ( UserConfigParams::m_graphical_effects ) { // update star effect (call will do nothing if stars are not activated) From 22633aa363039d655cf2b9c5760768b43002dae7 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 14 Oct 2014 09:01:26 +1100 Subject: [PATCH 064/112] Avoid calling querying the openal status in getStatus (which causes a slowdown of sfx). --- src/audio/sfx_manager.cpp | 1 + src/audio/sfx_openal.cpp | 107 +++++++++++++++++++++----------------- src/audio/sfx_openal.hpp | 61 ++++++++++++---------- 3 files changed, 93 insertions(+), 76 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 4d64e9919..a10b3b474 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -589,6 +589,7 @@ void SFXManager::resumeAll() /** Returns whether or not an openal error has occurred. If so, an error * message is printed containing the given context. * \param context Context to specify in the error message. + * \return True if no error happened. */ bool SFXManager::checkError(const std::string &context) { diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 2497b1056..a29d3ab44 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -23,8 +23,7 @@ #include "audio/sfx_buffer.hpp" #include "config/user_config.hpp" -#include "io/file_manager.hpp" -#include "race/race_manager.hpp" +#include "modes/world.hpp" #include "utils/vs.hpp" #ifdef __APPLE__ @@ -38,18 +37,19 @@ #include #include -SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBuffer) : SFXBase() +SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool owns_buffer) : SFXBase() { m_sound_buffer = buffer; m_sound_source = 0; - m_ok = false; + m_status = SFX_UNKNOWN; m_is_playing = false; m_positional = positional; m_defaultGain = gain; m_loop = false; m_gain = -1.0f; m_master_gain = 1.0f; - m_owns_buffer = ownsBuffer; + m_owns_buffer = owns_buffer; + m_end_time = -1.0f; // Don't initialise anything else if the sfx manager was not correctly // initialised. First of all the initialisation will not work, and it @@ -61,15 +61,16 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBu } // SFXOpenAL //----------------------------------------------------------------------------- - +/** Deletes the sfx source, and if it owns the buffer, also deletes the sound + * buffer. */ SFXOpenAL::~SFXOpenAL() { - if (m_ok) + if (m_status!=SFX_UNKNOWN) { alDeleteSources(1, &m_sound_source); } - if (m_owns_buffer && m_sound_buffer != NULL) + if (m_owns_buffer && m_sound_buffer) { m_sound_buffer->unload(); delete m_sound_buffer; @@ -86,9 +87,6 @@ bool SFXOpenAL::init() assert( alIsBuffer(m_sound_buffer->getBufferID()) ); assert( alIsSource(m_sound_source) ); - //Log::info("SFXOpenAL", "Setting a source with buffer, %p, rolloff %f, gain = %f, position = %s", - // m_sound_buffer, rolloff, m_defaultGain, positional ? "true" : "false"); - alSourcei (m_sound_source, AL_BUFFER, m_sound_buffer->getBufferID()); if (!SFXManager::checkError("attaching the buffer to the source")) @@ -115,18 +113,35 @@ bool SFXOpenAL::init() alSourcei(m_sound_source, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE); - m_ok = SFXManager::checkError("setting up the source"); + if(SFXManager::checkError("setting up the source")) + m_status = SFX_INITIAL; - return m_ok; + return m_status==SFX_INITIAL; } // init +// ------------------------------------------------------------------------ +/** Returns the status of this sfx. */ +SFXBase::SFXStatus SFXOpenAL::getStatus() +{ + if(m_status==SFX_PLAYING) + { + if(m_loop) return SFX_PLAYING; + if(World::getWorld() && World::getWorld()->getTime() > m_end_time) + { + m_status = SFX_STOPPED; + return m_status; + } + } + return m_status; +} // getStatus; + //----------------------------------------------------------------------------- /** Changes the pitch of a sound effect. * \param factor Speedup/slowdown between 0.5 and 2.0 */ void SFXOpenAL::speed(float factor) { - if(!m_ok || isnan(factor)) return; + if(m_status==SFX_UNKNOWN || isnan(factor)) return; //OpenAL only accepts pitches in the range of 0.5 to 2.0 if(factor > 2.0f) @@ -149,7 +164,7 @@ void SFXOpenAL::volume(float gain) { m_gain = m_defaultGain * gain; - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain); SFXManager::checkError("setting volume"); @@ -161,7 +176,7 @@ void SFXOpenAL::setMasterVolume(float gain) { m_master_gain = gain; - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); @@ -175,7 +190,7 @@ void SFXOpenAL::setLoop(bool status) { m_loop = status; - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE); SFXManager::checkError("looping"); @@ -193,9 +208,10 @@ void SFXOpenAL::stop() */ void SFXOpenAL::reallyStopNow() { - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; m_is_playing = false; + m_status = SFX_STOPPED; m_loop = false; alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); alSourceStop(m_sound_source); @@ -216,7 +232,8 @@ void SFXOpenAL::pause() */ void SFXOpenAL::reallyPauseNow() { - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; + m_status = SFX_PAUSED; alSourcePause(m_sound_source); SFXManager::checkError("pausing"); } // reallyPauseNow @@ -234,18 +251,21 @@ void SFXOpenAL::resume() */ void SFXOpenAL::reallyResumeNow() { - if (!m_ok) + if (m_status==SFX_UNKNOWN) { // lazily create OpenAL source when needed init(); // creation of OpenAL source failed, giving up - if (!m_ok) return; + if (m_status==SFX_UNKNOWN) return; } - if(getStatus()==SFX_PAUSED) + if(m_status==SFX_PAUSED) + { alSourcePlay(m_sound_source); - SFXManager::checkError("resuming"); + SFXManager::checkError("resuming"); + m_status = SFX_PLAYING; + } } // reallyResumeNow //----------------------------------------------------------------------------- @@ -277,17 +297,24 @@ void SFXOpenAL::play() void SFXOpenAL::reallyPlayNow() { if (!SFXManager::get()->sfxAllowed()) return; - if (!m_ok) + if (m_status==SFX_UNKNOWN) { // lazily create OpenAL source when needed init(); // creation of OpenAL source failed, giving up - if (!m_ok) return; + if (m_status==SFX_UNKNOWN) return; } alSourcePlay(m_sound_source); + m_status = SFX_PLAYING; SFXManager::checkError("playing"); + + // At non-race time the end time is not important + if(World::getWorld()) + m_end_time = World::getWorld()->getTime()+m_sound_buffer->getDuration(); + else + m_end_time = 1.0f; } // reallyPlayNow //----------------------------------------------------------------------------- @@ -306,9 +333,10 @@ void SFXOpenAL::position(const Vec3 &position) { if(!UserConfigParams::m_sfx) return; - if (!m_ok) + if (m_status==SFX_UNKNOWN) { - Log::warn("SFX", "Position called on non-ok SFX <%s>", m_sound_buffer->getFileName().c_str()); + Log::warn("SFX", "Position called on non-ok SFX <%s>", + m_sound_buffer->getFileName().c_str()); return; } if (!m_positional) @@ -338,33 +366,14 @@ void SFXOpenAL::position(const Vec3 &position) SFXManager::checkError("positioning"); } // position -//----------------------------------------------------------------------------- -/** Returns the status of this sound effect. - */ -SFXBase::SFXStatus SFXOpenAL::getStatus() -{ - if(!m_ok) return SFX_UNKNOWN; - - int state = 0; - alGetSourcei(m_sound_source, AL_SOURCE_STATE, &state); - switch(state) - { - case AL_STOPPED: return SFX_STOPPED; - case AL_PLAYING: return SFX_PLAYING; - case AL_PAUSED: return SFX_PAUSED; - case AL_INITIAL: return SFX_INITIAL; - default: return SFX_UNKNOWN; - } -} // getStatus - //----------------------------------------------------------------------------- void SFXOpenAL::onSoundEnabledBack() { if (m_loop) { - if (!m_ok) init(); - if (m_ok) + if (m_status==SFX_UNKNOWN) init(); + if (m_status!=SFX_UNKNOWN) { alSourcef(m_sound_source, AL_GAIN, 0); play(); @@ -372,7 +381,7 @@ void SFXOpenAL::onSoundEnabledBack() alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); } } -} +} // onSoundEnabledBack //----------------------------------------------------------------------------- diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 8b63fc41a..cc975e192 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -37,13 +37,17 @@ class SFXOpenAL : public SFXBase { private: + LEAK_CHECK() + /** Buffers hold sound data. */ SFXBuffer* m_sound_buffer; /** Sources are points emitting sound. */ ALuint m_sound_source; - bool m_ok; + /** The status of this SFX. */ + SFXStatus m_status; + bool m_positional; float m_defaultGain; @@ -65,39 +69,42 @@ private: /** The master gain set in user preferences */ float m_master_gain; + /** If this sfx should also free the sound buffer. */ bool m_owns_buffer; + /** Time at which a sfx ends playing. Used to avoid frequently getting + * the openl status (which can slow down stk). */ + float m_end_time; + public: - SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, - bool owns_buffer = false); - virtual ~SFXOpenAL(); + SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, + bool owns_buffer = false); + virtual ~SFXOpenAL(); - /** Late creation, if SFX was initially disabled */ - virtual bool init(); - - virtual void play(); - virtual void reallyPlayNow(); - virtual void setLoop(bool status); - virtual bool isPlaying(); - virtual void stop(); - virtual void reallyStopNow(); - virtual void pause(); - virtual void reallyPauseNow(); - virtual void resume(); - virtual void reallyResumeNow(); - virtual void deleteSFX(); - virtual void speed(float factor); - virtual void position(const Vec3 &position); - virtual void volume(float gain); - virtual void setMasterVolume(float gain); - virtual SFXStatus getStatus(); - virtual void onSoundEnabledBack(); - virtual void setRolloff(float rolloff); + virtual bool init(); + virtual void play(); + virtual void reallyPlayNow(); + virtual void setLoop(bool status); + virtual bool isPlaying(); + virtual void stop(); + virtual void reallyStopNow(); + virtual void pause(); + virtual void reallyPauseNow(); + virtual void resume(); + virtual void reallyResumeNow(); + virtual void deleteSFX(); + virtual void speed(float factor); + virtual void position(const Vec3 &position); + virtual void volume(float gain); + virtual void setMasterVolume(float gain); + virtual void onSoundEnabledBack(); + virtual void setRolloff(float rolloff); + virtual SFXStatus getStatus(); + // ------------------------------------------------------------------------ + /** Returns the buffer associated with this sfx. */ virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; } - LEAK_CHECK() - }; // SFXOpenAL #endif From c18579d86a67414051d5b56dd7f85d34520c944c Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 14 Oct 2014 09:57:53 +1100 Subject: [PATCH 065/112] Fixed compiler warning. --- src/physics/btKart.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index c1f3bf3f5..503f22f0c 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -247,8 +247,6 @@ btScalar btKart::rayCast(unsigned int index) wheel.m_raycastInfo.m_contactPointWS = source + rayvector; const btVector3& target = wheel.m_raycastInfo.m_contactPointWS; - btScalar param = btScalar(0.); - btVehicleRaycaster::btVehicleRaycasterResult rayResults; btAssert(m_vehicleRaycaster); From 6dd9feff3662234fc03ba4e2850a02dc808f1a85 Mon Sep 17 00:00:00 2001 From: quizywiz Date: Sun, 12 Oct 2014 15:57:18 +0530 Subject: [PATCH 066/112] escape or back on friends profile takes you to your profile Also, fixed bug where user info dialog was accessing m_enter_profile after it was deleted --- src/states_screens/dialogs/user_info_dialog.cpp | 3 ++- src/states_screens/online_profile_base.cpp | 16 ++++++++++++++++ src/states_screens/online_profile_base.hpp | 2 ++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/states_screens/dialogs/user_info_dialog.cpp b/src/states_screens/dialogs/user_info_dialog.cpp index 8c457f518..698e396ce 100644 --- a/src/states_screens/dialogs/user_info_dialog.cpp +++ b/src/states_screens/dialogs/user_info_dialog.cpp @@ -479,8 +479,9 @@ void UserInfoDialog::onUpdate(float dt) // It's unsafe to delete from inside the event handler so we do it here if (m_self_destroy) { + bool enter_profile = m_enter_profile; ModalDialog::dismiss(); - if (m_enter_profile) + if (enter_profile) StateManager::get()->replaceTopMostScreen(OnlineProfileAchievements::getInstance()); return; } diff --git a/src/states_screens/online_profile_base.cpp b/src/states_screens/online_profile_base.cpp index c7b938a5c..0d90bdd0d 100644 --- a/src/states_screens/online_profile_base.cpp +++ b/src/states_screens/online_profile_base.cpp @@ -17,6 +17,7 @@ #include "states_screens/online_profile_base.hpp" +#include "config/player_manager.hpp" #include "guiengine/engine.hpp" #include "guiengine/scalable_font.hpp" #include "guiengine/screen.hpp" @@ -71,6 +72,8 @@ void OnlineProfileBase::beforeAddingWidget() m_visiting_profile = ProfileManager::get()->getVisitingProfile(); if (!m_visiting_profile || !m_visiting_profile->isCurrentUser()) m_settings_tab->setVisible(false); + else + m_settings_tab->setVisible(true); // If not logged in, don't show profile or friends if (!m_visiting_profile) @@ -103,6 +106,19 @@ void OnlineProfileBase::init() } // init +// ----------------------------------------------------------------------------- +bool OnlineProfileBase::onEscapePressed() +{ + //return to main menu if it's your profile + if (!m_visiting_profile || m_visiting_profile->isCurrentUser()) + return true; + + //return to your profile if it's another profile + ProfileManager::get()->setVisiting(PlayerManager::getCurrentOnlineId()); + StateManager::get()->replaceTopMostScreen(OnlineProfileAchievements::getInstance()); + return false; +} // onEscapePressed + // ----------------------------------------------------------------------------- /** Called when an event occurs (i.e. user clicks on something). */ diff --git a/src/states_screens/online_profile_base.hpp b/src/states_screens/online_profile_base.hpp index 956b43d9b..247de6e95 100644 --- a/src/states_screens/online_profile_base.hpp +++ b/src/states_screens/online_profile_base.hpp @@ -62,6 +62,8 @@ public: /** \brief implement callback from parent class GUIEngine::Screen */ virtual void init() OVERRIDE; + virtual bool onEscapePressed() OVERRIDE; + virtual void beforeAddingWidget() OVERRIDE; }; From 8fcc373b2a2abab27135a9956213e423896bfadd Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 15 Oct 2014 07:55:18 +1100 Subject: [PATCH 067/112] Add volume, speed, and position settings to be done by the sfx thread. Removed more unnecessary error checks (which mostly flood stdout with 'not playing ...' messages), and renamed volume, position and speed to setVolume, setPosition and setSpeed. --- src/audio/dummy_sfx.hpp | 39 ++++++------ src/audio/sfx_base.hpp | 43 +++++++------ src/audio/sfx_manager.cpp | 67 ++++++++++++++++----- src/audio/sfx_manager.hpp | 45 +++++++++++--- src/audio/sfx_openal.cpp | 51 +++++++++++++--- src/audio/sfx_openal.hpp | 9 ++- src/graphics/hit_sfx.cpp | 6 +- src/graphics/material.cpp | 4 +- src/items/attachment.cpp | 6 +- src/items/bowling.cpp | 2 +- src/items/powerup.cpp | 26 ++++---- src/items/rubber_ball.cpp | 2 +- src/items/swatter.cpp | 2 +- src/karts/kart.cpp | 48 +++++++-------- src/states_screens/options_screen_audio.cpp | 2 +- src/tracks/track_object_presentation.cpp | 6 +- 16 files changed, 230 insertions(+), 128 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index a14accbf7..8f5572431 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -36,24 +36,27 @@ public: /** Late creation, if SFX was initially disabled */ virtual bool init() { return true; } - virtual void position(const Vec3 &position) {} - virtual void setLoop(bool status) {} - virtual void play() {} - virtual void reallyPlayNow() {} - virtual void stop() {} - virtual void reallyStopNow() {} - virtual void pause() {} - virtual void reallyPauseNow() {} - virtual void resume() {} - virtual void reallyResumeNow() {} - virtual void deleteSFX() { delete this; } - virtual void speed(float factor) {} - virtual void volume(float gain) {} - virtual SFXStatus getStatus() { return SFX_STOPPED; } - virtual void onSoundEnabledBack() {} - virtual void setRolloff(float rolloff) {} - virtual bool isPlaying() { return false; } - virtual const SFXBuffer* getBuffer() const { return NULL; } + virtual void setLoop(bool status) {} + virtual void setPosition(const Vec3 &p) {} + virtual void reallySetPosition(const Vec3 &p) {} + virtual void play() {} + virtual void reallyPlayNow() {} + virtual void stop() {} + virtual void reallyStopNow() {} + virtual void pause() {} + virtual void reallyPauseNow() {} + virtual void resume() {} + virtual void reallyResumeNow() {} + virtual void deleteSFX() { delete this; } + virtual void setSpeed(float factor) {} + virtual void reallySetSpeed(float factor) {} + virtual void setVolume(float gain) {} + virtual void reallySetVolume(float gain) {} + virtual SFXStatus getStatus() { return SFX_STOPPED; } + virtual void onSoundEnabledBack() {} + virtual void setRolloff(float rolloff) {} + virtual bool isPlaying() { return false; } + virtual const SFXBuffer* getBuffer() const { return NULL; } }; // DummySFX diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index 7fa948390..a23ef0dbb 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -52,26 +52,29 @@ public: virtual ~SFXBase() {} /** Late creation, if SFX was initially disabled */ - virtual bool init() = 0; - virtual void position(const Vec3 &position) = 0; - virtual void setLoop(bool status) = 0; - virtual bool isPlaying() = 0; - virtual void play() = 0; - virtual void reallyPlayNow() = 0; - virtual void stop() = 0; - virtual void reallyStopNow() = 0; - virtual void pause() = 0; - virtual void reallyPauseNow() = 0; - virtual void resume() = 0; - virtual void reallyResumeNow() = 0; - virtual void deleteSFX() = 0; - virtual void speed(float factor) = 0; - virtual void volume(float gain) = 0; - virtual void setMasterVolume(float gain) = 0; - virtual void onSoundEnabledBack() = 0; - virtual void setRolloff(float rolloff) = 0; - virtual const SFXBuffer* getBuffer() const = 0; - virtual SFXStatus getStatus() = 0; + virtual bool init() = 0; + virtual void setPosition(const Vec3 &p) = 0; + virtual void reallySetPosition(const Vec3 &p) = 0; + virtual void setLoop(bool status) = 0; + virtual bool isPlaying() = 0; + virtual void play() = 0; + virtual void reallyPlayNow() = 0; + virtual void stop() = 0; + virtual void reallyStopNow() = 0; + virtual void pause() = 0; + virtual void reallyPauseNow() = 0; + virtual void resume() = 0; + virtual void reallyResumeNow() = 0; + virtual void deleteSFX() = 0; + virtual void setSpeed(float factor) = 0; + virtual void reallySetSpeed(float factor) = 0; + virtual void setVolume(float gain) = 0; + virtual void reallySetVolume(float gain) = 0; + virtual void setMasterVolume(float gain) = 0; + virtual void onSoundEnabledBack() = 0; + virtual void setRolloff(float rolloff) = 0; + virtual const SFXBuffer* getBuffer() const = 0; + virtual SFXStatus getStatus() = 0; }; // SFXBase diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index a10b3b474..288e80c85 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -160,26 +160,59 @@ SFXManager::~SFXManager() } // ~SFXManager //---------------------------------------------------------------------------- -/** Adds a sound effect to the queue of sfx to be started by the sfx manager. - * Starting a sfx can sometimes cause a 5ms delay, so it is done in a - * separate thread. +/** Adds a sound effect command to the queue of the sfx manager. Openal + * commands can sometimes cause a 5ms delay, so it is done in a separate + * thread. + * \param command The command to execute. * \param sfx The sound effect to be started. */ void SFXManager::queue(SFXCommands command, SFXBase *sfx) { - // Don't add sfx that are either not working correctly (e.g. because sfx - // are disabled); - if(sfx && sfx->getStatus()==SFXBase::SFX_UNKNOWN) return; - SFXCommand *sfx_command = new SFXCommand(command, sfx); + queueCommand(sfx_command); +} // queue +//---------------------------------------------------------------------------- +/** Adds a sound effect command with a single floating point parameter to the + * queue of the sfx manager. Openal commands can sometimes cause a 5ms delay, + * so it is done in a separate thread. + * \param command The command to execute. + * \param sfx The sound effect to be started. + * \param f Floating point parameter for the command. + */ +void SFXManager::queue(SFXCommands command, SFXBase *sfx, float f) +{ + SFXCommand *sfx_command = new SFXCommand(command, sfx, f); + queueCommand(sfx_command); +} // queue(float) + +//---------------------------------------------------------------------------- +/** Adds a sound effect command with a Vec3 parameter to the queue of the sfx + * manager. Openal commands can sometimes cause a 5ms delay, so it is done in + * a separate thread. + * \param command The command to execute. + * \param sfx The sound effect to be started. + * \param p A Vec3 parameter for the command. + */ +void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p) +{ + SFXCommand *sfx_command = new SFXCommand(command, sfx, p); + queueCommand(sfx_command); +} // queue (Vec3) + +//---------------------------------------------------------------------------- +/** Enqueues a command to the sfx queue threadsafe. Then signal the + * sfx manager to wake up. + * \param command Pointer to the command to queue up. + */ +void SFXManager::queueCommand(SFXCommand *command) +{ m_sfx_commands.lock(); - m_sfx_commands.getData().push_back(sfx_command); + m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); // Wake up the sfx thread pthread_cond_signal(&m_cond_request); - -} // queue +} // queueCommand //---------------------------------------------------------------------------- /** Puts a NULL request into the queue, which will trigger the thread to @@ -228,10 +261,16 @@ void* SFXManager::mainLoop(void *obj) me->m_sfx_commands.unlock(); switch(current->m_command) { - case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; - case SFX_STOP: current->m_sfx->reallyStopNow(); break; - case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; - case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; + case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; + case SFX_STOP: current->m_sfx->reallyStopNow(); break; + case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; + case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; + case SFX_SPEED: current->m_sfx->reallySetSpeed( + current->m_parameter.getX()); break; + case SFX_POSITION: current->m_sfx->reallySetPosition( + current->m_parameter); break; + case SFX_VOLUME: current->m_sfx->reallySetVolume( + current->m_parameter.getX()); break; case SFX_DELETE: { current->m_sfx->reallyStopNow(); me->deleteSFX(current->m_sfx); diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index f559407d4..8f9edc25b 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -62,12 +62,15 @@ public: * for each sfx. */ enum SFXCommands { - SFX_PLAY = 1, - SFX_STOP = 2, - SFX_PAUSE = 3, - SFX_RESUME = 4, - SFX_DELETE = 5, - SFX_EXIT = 6, + SFX_PLAY = 1, + SFX_STOP, + SFX_PAUSE, + SFX_RESUME, + SFX_DELETE, + SFX_SPEED, + SFX_POSITION, + SFX_VOLUME, + SFX_EXIT, }; // SFXCommands /** @@ -98,15 +101,34 @@ private: private: LEAK_CHECK() public: + /** The sound effect for which the command should be executed. */ SFXBase *m_sfx; + /** The command to execute. */ SFXCommands m_command; + /** Optional parameter for commands that need more input. */ + Vec3 m_parameter; + // -------------------------------------------------------------------- SFXCommand(SFXCommands command, SFXBase *base) { - m_command = command; - m_sfx = base; - } + m_command = command; + m_sfx = base; + } // SFXCommand() + // -------------------------------------------------------------------- + SFXCommand(SFXCommands command, SFXBase *base, float parameter) + { + m_command = command; + m_sfx = base; + m_parameter.setX(parameter); + } // SFXCommand(float) + // -------------------------------------------------------------------- + SFXCommand(SFXCommands command, SFXBase *base, const Vec3 ¶meter) + { + m_command = command; + m_sfx = base; + m_parameter = parameter; + } // SFXCommand(Vec3) }; // SFXCommand - + // ======================================================================== /** Listener position */ Vec3 m_position; @@ -144,10 +166,13 @@ private: static void* mainLoop(void *obj); void deleteSFX(SFXBase *sfx); + void queueCommand(SFXCommand *command); public: static void create(); static void destroy(); void queue(SFXCommands command, SFXBase *sfx); + void queue(SFXCommands command, SFXBase *sfx, float f); + void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p); // ------------------------------------------------------------------------ /** Static function to get the singleton sfx manager. */ static SFXManager *get() diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index a29d3ab44..5494222c9 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -136,13 +136,23 @@ SFXBase::SFXStatus SFXOpenAL::getStatus() } // getStatus; //----------------------------------------------------------------------------- -/** Changes the pitch of a sound effect. +/** Queues up a change of the pitch of a sound effect to the sfx manager. * \param factor Speedup/slowdown between 0.5 and 2.0 */ -void SFXOpenAL::speed(float factor) +void SFXOpenAL::setSpeed(float factor) { - if(m_status==SFX_UNKNOWN || isnan(factor)) return; + if(m_status==SFX_UNKNOWN) return; + assert(!isnan(factor)); + SFXManager::get()->queue(SFXManager::SFX_SPEED, this, factor); +} // setSpeed +//----------------------------------------------------------------------------- +/** Changes the pitch of a sound effect. Executed from the sfx manager thread. + * \param factor Speedup/slowdown between 0.5 and 2.0 + */ +void SFXOpenAL::reallySetSpeed(float factor) +{ + if(m_status==SFX_UNKNOWN) return; //OpenAL only accepts pitches in the range of 0.5 to 2.0 if(factor > 2.0f) { @@ -153,22 +163,32 @@ void SFXOpenAL::speed(float factor) factor = 0.5f; } alSourcef(m_sound_source,AL_PITCH,factor); - SFXManager::checkError("changing the speed"); -} // speed +} // reallySetSpeed //----------------------------------------------------------------------------- /** Changes the volume of a sound effect. * \param gain Volume adjustment between 0.0 (mute) and 1.0 (full volume). */ -void SFXOpenAL::volume(float gain) +void SFXOpenAL::setVolume(float gain) { + if(m_status==SFX_UNKNOWN) return; + assert(!isnan(gain)) ; + SFXManager::get()->queue(SFXManager::SFX_VOLUME, this, gain); +} // setVolume + +//----------------------------------------------------------------------------- +/** Changes the volume of a sound effect. + * \param gain Volume adjustment between 0.0 (mute) and 1.0 (full volume). + */ +void SFXOpenAL::reallySetVolume(float gain) +{ + if(m_status==SFX_UNKNOWN) return; m_gain = m_defaultGain * gain; if(m_status==SFX_UNKNOWN) return; alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain); - SFXManager::checkError("setting volume"); -} // volume +} // reallySetVolume //----------------------------------------------------------------------------- @@ -329,7 +349,18 @@ bool SFXOpenAL::isPlaying() /** Sets the position where this sound effects is played. * \param position Position of the sound effect. */ -void SFXOpenAL::position(const Vec3 &position) +void SFXOpenAL::setPosition(const Vec3 &position) +{ + if (m_status == SFX_UNKNOWN) return; + SFXManager::get()->queue(SFXManager::SFX_POSITION, this, position); + +} // setPosition + +//----------------------------------------------------------------------------- +/** Sets the position where this sound effects is played. + * \param position Position of the sound effect. + */ +void SFXOpenAL::reallySetPosition(const Vec3 &position) { if(!UserConfigParams::m_sfx) return; @@ -364,7 +395,7 @@ void SFXOpenAL::position(const Vec3 &position) } SFXManager::checkError("positioning"); -} // position +} // reallySetPosition //----------------------------------------------------------------------------- diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index cc975e192..a4b59b587 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -93,9 +93,12 @@ public: virtual void resume(); virtual void reallyResumeNow(); virtual void deleteSFX(); - virtual void speed(float factor); - virtual void position(const Vec3 &position); - virtual void volume(float gain); + virtual void setSpeed(float factor); + virtual void reallySetSpeed(float factor); + virtual void setPosition(const Vec3 &position); + virtual void reallySetPosition(const Vec3 &p); + virtual void setVolume(float gain); + virtual void reallySetVolume(float gain); virtual void setMasterVolume(float gain); virtual void onSoundEnabledBack(); virtual void setRolloff(float rolloff); diff --git a/src/graphics/hit_sfx.cpp b/src/graphics/hit_sfx.cpp index 391d7118a..e9018a474 100644 --- a/src/graphics/hit_sfx.cpp +++ b/src/graphics/hit_sfx.cpp @@ -27,13 +27,13 @@ HitSFX::HitSFX(const Vec3& coord, const char* explosion_sound) : HitEffect() { m_sfx = SFXManager::get()->createSoundSource( explosion_sound ); - m_sfx->position(coord); + m_sfx->setPosition(coord); // in multiplayer mode, sounds are NOT positional (because we have // multiple listeners) so the sounds of all AIs are constantly heard. // Therefore reduce volume of sounds. float vol = race_manager->getNumLocalPlayers() > 1 ? 0.5f : 1.0f; - m_sfx->volume(vol); + m_sfx->setVolume(vol); m_sfx->play(); } // HitSFX @@ -53,7 +53,7 @@ HitSFX::~HitSFX() void HitSFX::setPlayerKartHit() { if(race_manager->getNumLocalPlayers()) - m_sfx->volume(1.0f); + m_sfx->setVolume(1.0f); } // setPlayerKartHit //----------------------------------------------------------------------------- diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 725c0908c..7a4ddca5f 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -664,12 +664,12 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) con } if (speed > m_sfx_max_speed) { - sfx->speed(m_sfx_max_pitch); + sfx->setSpeed(m_sfx_max_pitch); return; } float f = m_sfx_pitch_per_speed*(speed-m_sfx_min_speed) + m_sfx_min_pitch; - sfx->speed(f); + sfx->setSpeed(f); } // setSFXSpeed //----------------------------------------------------------------------------- diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 02513b4a4..3974ed3f2 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -142,7 +142,7 @@ void Attachment::set(AttachmentType type, float time, if (m_bomb_sound) m_bomb_sound->deleteSFX(); m_bomb_sound = SFXManager::get()->createSoundSource("clock"); m_bomb_sound->setLoop(true); - m_bomb_sound->position(m_kart->getXYZ()); + m_bomb_sound->setPosition(m_kart->getXYZ()); m_bomb_sound->play(); break; default: @@ -439,7 +439,7 @@ void Attachment::update(float dt) break; case ATTACH_BOMB: - if (m_bomb_sound) m_bomb_sound->position(m_kart->getXYZ()); + if (m_bomb_sound) m_bomb_sound->setPosition(m_kart->getXYZ()); // Mesh animation frames are 1 to 61 frames (60 steps) // The idea is change second by second, counterclockwise 60 to 0 secs @@ -474,7 +474,7 @@ void Attachment::update(float dt) m_time_left = 0.0f; if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX(); m_bubble_explode_sound = SFXManager::get()->createSoundSource("bubblegum_explode"); - m_bubble_explode_sound->position(m_kart->getXYZ()); + m_bubble_explode_sound->setPosition(m_kart->getXYZ()); m_bubble_explode_sound->play(); // drop a small bubble gum diff --git a/src/items/bowling.cpp b/src/items/bowling.cpp index 7ac248ee4..4d0b8c935 100644 --- a/src/items/bowling.cpp +++ b/src/items/bowling.cpp @@ -173,7 +173,7 @@ bool Bowling::updateAndDelete(float dt) } if (m_roll_sfx->getStatus()==SFXBase::SFX_PLAYING) - m_roll_sfx->position(getXYZ()); + m_roll_sfx->setPosition(getXYZ()); return false; } // updateAndDelete diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index 9cdbcd8b0..22652271a 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -140,18 +140,14 @@ Material *Powerup::getIcon() const // Check if it's one of the types which have a separate // data file which includes the icon: return powerup_manager->getIcon(m_type); -} - - - - +} // getIcon //----------------------------------------------------------------------------- /** Does the sound configuration. */ void Powerup::adjustSound() { - m_sound_use->position(m_owner->getXYZ()); + m_sound_use->setPosition(m_owner->getXYZ()); // in multiplayer mode, sounds are NOT positional (because we have multiple listeners) // so the sounds of all AIs are constantly heard. So reduce volume of sounds. if (race_manager->getNumLocalPlayers() > 1) @@ -160,14 +156,16 @@ void Powerup::adjustSound() if (m_owner->getController()->isPlayerController()) { - m_sound_use->volume( 1.0f ); + m_sound_use->setVolume( 1.0f ); } else { - m_sound_use->volume( std::min(0.5f, 1.0f / race_manager->getNumberOfKarts()) ); + m_sound_use->setVolume( + std::min(0.5f, 1.0f / race_manager->getNumberOfKarts()) ); } } -} +} // adjustSound + //----------------------------------------------------------------------------- /** Use (fire) this powerup. */ @@ -205,7 +203,7 @@ void Powerup::use() case PowerupManager::POWERUP_SWITCH: { ItemManager::get()->switchItems(); - m_sound_use->position(m_owner->getXYZ()); + m_sound_use->setPosition(m_owner->getXYZ()); m_sound_use->play(); break; } @@ -310,9 +308,9 @@ void Powerup::use() // Meanwhile, don't play it near AI karts since they obviously // don't hear anything if(kart->getController()->isPlayerController()) - m_sound_use->position(kart->getXYZ()); + m_sound_use->setPosition(kart->getXYZ()); else - m_sound_use->position(m_owner->getXYZ()); + m_sound_use->setPosition(m_owner->getXYZ()); m_sound_use->play(); break; @@ -352,9 +350,9 @@ void Powerup::use() // Meanwhile, don't play it near AI karts since they obviously // don't hear anything if(m_owner->getController()->isPlayerController()) - m_sound_use->position(m_owner->getXYZ()); + m_sound_use->setPosition(m_owner->getXYZ()); else if(player_kart) - m_sound_use->position(player_kart->getXYZ()); + m_sound_use->setPosition(player_kart->getXYZ()); m_sound_use->play(); } break; diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index f3b6b5f19..b9ca9a3f7 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -543,7 +543,7 @@ float RubberBall::updateHeight() m_height_timer -= m_interval; if(m_ping_sfx->getStatus()!=SFXBase::SFX_PLAYING) { - m_ping_sfx->position(getXYZ()); + m_ping_sfx->setPosition(getXYZ()); m_ping_sfx->play(); } diff --git a/src/items/swatter.cpp b/src/items/swatter.cpp index 60513aba3..baf735112 100644 --- a/src/items/swatter.cpp +++ b/src/items/swatter.cpp @@ -275,7 +275,7 @@ void Swatter::squashThingsAround() assert(swatter_node); Vec3 swatter_pos = swatter_node->getAbsolutePosition(); - m_swat_sound->position(swatter_pos); + m_swat_sound->setPosition(swatter_pos); m_swat_sound->play(); // Squash karts around diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index fd66b8ebc..d017ba85d 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -183,19 +183,19 @@ void Kart::init(RaceManager::KartType type) { // players have louder sounds than AIs const float factor = std::min(1.0f, race_manager->getNumLocalPlayers()/2.0f); - m_goo_sound->volume( 1.0f / factor ); - m_skid_sound->volume( 1.0f / factor ); - m_crash_sound->volume( 1.0f / factor ); - m_boing_sound->volume( 1.0f / factor ); - m_beep_sound->volume( 1.0f / factor ); + m_goo_sound->setVolume( 1.0f / factor ); + m_skid_sound->setVolume( 1.0f / factor ); + m_crash_sound->setVolume( 1.0f / factor ); + m_boing_sound->setVolume( 1.0f / factor ); + m_beep_sound->setVolume( 1.0f / factor ); } else { - m_goo_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); - m_skid_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); - m_crash_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); - m_beep_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); - m_boing_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); + m_goo_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() ); + m_skid_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() ); + m_crash_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() ); + m_beep_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() ); + m_boing_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() ); } } @@ -756,12 +756,12 @@ void Kart::startEngineSFX() const float players_volume = (np * 2.0f) / (np*2.0f + np); if (m_controller->isPlayerController()) - m_engine_sound->volume( players_volume / np ); + m_engine_sound->setVolume( players_volume / np ); else - m_engine_sound->volume( (1.0f - players_volume) / nai ); + m_engine_sound->setVolume( (1.0f - players_volume) / nai ); } - m_engine_sound->speed(0.6f); + m_engine_sound->setSpeed(0.6f); m_engine_sound->setLoop(true); m_engine_sound->play(); } // startEngineSFX @@ -928,7 +928,7 @@ void Kart::collectedItem(Item *item, int add_info) m_kart_properties->getBubblegumSpeedFraction(), m_kart_properties->getBubblegumFadeInTime(), m_bubblegum_time); - m_goo_sound->position(getXYZ()); + m_goo_sound->setPosition(getXYZ()); m_goo_sound->play(); // Play appropriate custom character sound playCustomSFX(SFXManager::CUSTOM_GOO); @@ -1184,11 +1184,11 @@ void Kart::update(float dt) } */ - m_beep_sound->position ( getXYZ() ); - m_engine_sound->position ( getXYZ() ); - m_crash_sound->position ( getXYZ() ); - m_skid_sound->position ( getXYZ() ); - m_boing_sound->position ( getXYZ() ); + m_beep_sound->setPosition ( getXYZ() ); + m_engine_sound->setPosition ( getXYZ() ); + m_crash_sound->setPosition ( getXYZ() ); + m_skid_sound->setPosition ( getXYZ() ); + m_boing_sound->setPosition ( getXYZ() ); // Check if a kart is (nearly) upside down and not moving much --> // automatic rescue @@ -1447,7 +1447,7 @@ void Kart::handleMaterialSFX(const Material *material) { if (!m_controller->isPlayerController()) { - m_terrain_sound->volume( 0.0f ); + m_terrain_sound->setVolume( 0.0f ); } } @@ -1480,7 +1480,7 @@ void Kart::handleMaterialSFX(const Material *material) (m_terrain_sound->getStatus()==SFXBase::SFX_PLAYING || m_terrain_sound->getStatus()==SFXBase::SFX_PAUSED)) { - m_terrain_sound->position(getXYZ()); + m_terrain_sound->setPosition(getXYZ()); material->setSFXSpeed(m_terrain_sound, m_speed, m_schedule_pause); } @@ -2123,15 +2123,15 @@ void Kart::updateEngineSFX() if (f>1.0f) f=1.0f; float gears = 3.0f * fmod(f, 0.333334f); - m_engine_sound->speed(0.6f + (f +gears)* 0.35f); + m_engine_sound->setSpeed(0.6f + (f +gears)* 0.35f); } else { // When flying, fixed value but not too high pitch // This gives some variation (vs previous "on wheels" one) - m_engine_sound->speed(0.9f); + m_engine_sound->setSpeed(0.9f); } - m_engine_sound->position(getXYZ()); + m_engine_sound->setPosition(getXYZ()); } // updateEngineSFX //----------------------------------------------------------------------------- diff --git a/src/states_screens/options_screen_audio.cpp b/src/states_screens/options_screen_audio.cpp index b0ac7c419..c3cfc751b 100644 --- a/src/states_screens/options_screen_audio.cpp +++ b/src/states_screens/options_screen_audio.cpp @@ -138,7 +138,7 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name, assert(w != NULL); if (sample_sound == NULL) sample_sound = SFXManager::get()->createSoundSource( "pre_start_race" ); - sample_sound->volume(1); + sample_sound->setVolume(1); SFXManager::get()->setMasterSFXVolume( w->getValue()/10.0f ); UserConfigParams::m_sfx_volume = w->getValue()/10.0f; diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 3ef6c8d56..f8367f233 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -427,7 +427,7 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_no m_sound = SFXManager::get()->createSoundSource(buffer, true, true); if (m_sound != NULL) { - m_sound->position(m_init_xyz); + m_sound->setPosition(m_init_xyz); if (!trigger_when_near && m_trigger_condition.empty()) { m_sound->setLoop(true); @@ -451,7 +451,7 @@ void TrackObjectPresentationSound::update(float dt) // muting when too far is implemented manually since not supported by OpenAL // so need to call this every frame to update the muting state if listener // moved - m_sound->position(m_xyz); + m_sound->setPosition(m_xyz); } } // update @@ -495,7 +495,7 @@ void TrackObjectPresentationSound::move(const core::vector3df& xyz, const core::vector3df& scale) { m_xyz = xyz; - if (m_sound != NULL) m_sound->position(xyz); + if (m_sound != NULL) m_sound->setPosition(xyz); } // move // ---------------------------------------------------------------------------- From 607e94ea84863ecb1483197f47129a0565e9a3c5 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 15 Oct 2014 08:20:06 +1100 Subject: [PATCH 068/112] Fixed #1622 (missing password field in login screen). --- src/states_screens/user_screen.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp index 148848885..048e55e90 100644 --- a/src/states_screens/user_screen.cpp +++ b/src/states_screens/user_screen.cpp @@ -212,11 +212,15 @@ void BaseUserScreen::makeEntryFieldsVisible() getWidget("label_remember")->setVisible(online); getWidget("remember-user")->setVisible(online); PlayerProfile *player = getSelectedPlayer(); + // Don't show the password fields if the player wants to be online - // and either is the current player (no need to enter a password then) - // or has a saved session. + // and either is the current player and logged in (no need to enter a + // password then) or has a saved session. if(player && online && - (player->hasSavedSession() || player==PlayerManager::getCurrentPlayer())) + (player->hasSavedSession() || + (player==PlayerManager::getCurrentPlayer() && player->isLoggedIn() ) + ) + ) { // If we show the online login fields, but the player has a // saved session, don't show the password field. @@ -451,6 +455,7 @@ void BaseUserScreen::onUpdate(float dt) { player->clearSession(); makeEntryFieldsVisible(); + m_username_tb->setText(player->getLastOnlineName()); } } } // onUpdate From 514d0c4dfee8302470cd42c72be9554733f3f417 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Tue, 14 Oct 2014 19:59:42 -0400 Subject: [PATCH 069/112] Work around #1626 --- src/guiengine/widgets/dynamic_ribbon_widget.cpp | 2 +- src/states_screens/options_screen_video.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index ce6428911..57e110276 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -1085,7 +1085,7 @@ bool DynamicRibbonWidget::setSelection(int item_id, const int playerID, if (iterations > 50) { - Log::fatal("DynamicRibbonWidget::setSelection", "Cannot find item %d (%s)", item_id, name.c_str()); + Log::error("DynamicRibbonWidget::setSelection", "Cannot find item %d (%s)", item_id, name.c_str()); return false; } diff --git a/src/states_screens/options_screen_video.cpp b/src/states_screens/options_screen_video.cpp index c6c3a121c..ff4042496 100644 --- a/src/states_screens/options_screen_video.cpp +++ b/src/states_screens/options_screen_video.cpp @@ -310,6 +310,7 @@ void OptionsScreenVideo::init() } // end if not inited + res->setActivated(); res->updateItemDisplay(); // ---- select current resolution every time From 3fe2870c396200b7a129016f81f6db95124c90f2 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Tue, 14 Oct 2014 20:03:50 -0400 Subject: [PATCH 070/112] Cleaner fix for #1626, closes #1626 --- src/guiengine/widgets/dynamic_ribbon_widget.cpp | 6 +++--- src/guiengine/widgets/dynamic_ribbon_widget.hpp | 2 +- src/states_screens/options_screen_video.cpp | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index 57e110276..cd3d16c05 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -757,9 +757,9 @@ void DynamicRibbonWidget::onRibbonWidgetFocus(RibbonWidget* emitter, const int p #pragma mark Setters / Actions #endif -void DynamicRibbonWidget::scroll(const int x_delta) +void DynamicRibbonWidget::scroll(int x_delta, bool evenIfDeactivated) { - if (m_deactivated) return; + if (m_deactivated && !evenIfDeactivated) return; // Refuse to scroll when everything is visible if ((int)m_items.size() <= m_row_amount*m_col_amount) return; @@ -1081,7 +1081,7 @@ bool DynamicRibbonWidget::setSelection(int item_id, const int playerID, while (!findItemInRows(name.c_str(), &row, &id)) { // if we get here it means the item is scrolled out. Try to find it. - scroll(1); + scroll(1, evenIfDeactivated); if (iterations > 50) { diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.hpp b/src/guiengine/widgets/dynamic_ribbon_widget.hpp index a46a28202..d2e842cf8 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.hpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.hpp @@ -159,7 +159,7 @@ namespace GUIEngine void buildInternalStructure(); /** Call this to scroll within a scrollable ribbon */ - void scroll(const int x_delta); + void scroll(int x_delta, bool evenIfDeactivated = false); /** Used for combo ribbons, to contain the ID of the currently selected item for each player */ int m_selected_item[MAX_PLAYER_COUNT]; diff --git a/src/states_screens/options_screen_video.cpp b/src/states_screens/options_screen_video.cpp index ff4042496..c6c3a121c 100644 --- a/src/states_screens/options_screen_video.cpp +++ b/src/states_screens/options_screen_video.cpp @@ -310,7 +310,6 @@ void OptionsScreenVideo::init() } // end if not inited - res->setActivated(); res->updateItemDisplay(); // ---- select current resolution every time From 7e4e857b4190ff6d516f84dcf5e5c84653238d1b Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 15 Oct 2014 23:38:13 +1100 Subject: [PATCH 071/112] Improve situation of #1624 - it should only happen now if you pause the game in the first one or two seconds after start (still wip). --- src/audio/sfx_openal.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 5494222c9..dd1fdb086 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -223,6 +223,7 @@ void SFXOpenAL::stop() { SFXManager::get()->queue(SFXManager::SFX_STOP, this); } // stop + //----------------------------------------------------------------------------- /** The sfx manager thread executes a stop for this sfx. */ @@ -252,7 +253,11 @@ void SFXOpenAL::pause() */ void SFXOpenAL::reallyPauseNow() { - if(m_status==SFX_UNKNOWN) return; + // This updates the status, i.e. potentially switches from + // playing to stopped. + getStatus(); + if(m_status!=SFX_PLAYING) return; + m_status = SFX_PAUSED; alSourcePause(m_sound_source); SFXManager::checkError("pausing"); @@ -271,15 +276,8 @@ void SFXOpenAL::resume() */ void SFXOpenAL::reallyResumeNow() { - if (m_status==SFX_UNKNOWN) - { - // lazily create OpenAL source when needed - init(); - - // creation of OpenAL source failed, giving up - if (m_status==SFX_UNKNOWN) return; - } - + // Will init the sfx (lazy) if necessary. + getStatus(); if(m_status==SFX_PAUSED) { alSourcePlay(m_sound_source); From bba7156affbdc37638cb8324f6b3130a6a4cb99a Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 15 Oct 2014 23:42:59 +1100 Subject: [PATCH 072/112] Handle the setting of the listener position in the sfx thread. --- src/audio/sfx_manager.cpp | 76 +++++++++++++++++++--------- src/audio/sfx_manager.hpp | 24 ++++++--- src/graphics/camera.cpp | 7 ++- src/modes/cutscene_world.cpp | 3 +- src/states_screens/state_manager.cpp | 2 +- 5 files changed, 76 insertions(+), 36 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 288e80c85..079c59714 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -74,7 +74,10 @@ SFXManager::SFXManager() m_initialized = music_manager->initialized(); m_master_gain = UserConfigParams::m_sfx_volume; // Init position, since it can be used before positionListener is called. - m_position = Vec3(0,0,0); + // No need to use lock here, since the thread will be created later. + m_listener_position.getData() = Vec3(0, 0, 0); + m_listener_front = Vec3(0, 0, 1); + m_listener_up = Vec3(0, 1, 0); loadSfx(); @@ -261,21 +264,21 @@ void* SFXManager::mainLoop(void *obj) me->m_sfx_commands.unlock(); switch(current->m_command) { - case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; - case SFX_STOP: current->m_sfx->reallyStopNow(); break; - case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; - case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; - case SFX_SPEED: current->m_sfx->reallySetSpeed( + case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; + case SFX_STOP: current->m_sfx->reallyStopNow(); break; + case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; + case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; + case SFX_SPEED: current->m_sfx->reallySetSpeed( current->m_parameter.getX()); break; case SFX_POSITION: current->m_sfx->reallySetPosition( current->m_parameter); break; - case SFX_VOLUME: current->m_sfx->reallySetVolume( + case SFX_VOLUME: current->m_sfx->reallySetVolume( current->m_parameter.getX()); break; - case SFX_DELETE: { - current->m_sfx->reallyStopNow(); - me->deleteSFX(current->m_sfx); - break; - } + case SFX_DELETE: { + current->m_sfx->reallyStopNow(); + me->deleteSFX(current->m_sfx); break; + } + case SFX_LISTENER: me->reallyPositionListenerNow(); break; default: assert("Not yet supported."); } delete current; @@ -702,28 +705,51 @@ const std::string SFXManager::getErrorString(int err) /** Sets the position and orientation of the listener. * \param position Position of the listener. * \param front Which way the listener is facing. + * \param up The up direction of the listener. */ -void SFXManager::positionListener(const Vec3 &position, const Vec3 &front) +void SFXManager::positionListener(const Vec3 &position, const Vec3 &front, + const Vec3 &up) +{ + m_listener_position.lock(); + m_listener_position.getData() = position; + m_listener_front = front; + m_listener_up = up; + m_listener_position.unlock(); + queue(SFX_LISTENER, NULL); +} // positionListener + +//----------------------------------------------------------------------------- +/** Sets the position and orientation of the listener. + * \param position Position of the listener. + * \param front Which way the listener is facing. + */ +void SFXManager::reallyPositionListenerNow() { #if HAVE_OGGVORBIS if (!UserConfigParams::m_sfx || !m_initialized) return; - m_position = position; + m_listener_position.lock(); + { - //forward vector - m_listenerVec[0] = front.getX(); - m_listenerVec[1] = front.getY(); - m_listenerVec[2] = front.getZ(); + //forward vector + float orientation[6]; + orientation[0] = m_listener_front.getX(); + orientation[1] = m_listener_front.getY(); + orientation[2] = m_listener_front.getZ(); - //up vector - m_listenerVec[3] = 0; - m_listenerVec[4] = 0; - m_listenerVec[5] = 1; + //up vector + orientation[3] = m_listener_up.getX(); + orientation[4] = m_listener_up.getY(); + orientation[5] = m_listener_up.getZ(); + + const Vec3 &pos = m_listener_position.getData(); + alListener3f(AL_POSITION, pos.getX(), pos.getY(), pos.getZ()); + alListenerfv(AL_ORIENTATION, orientation); + } + m_listener_position.unlock(); - alListener3f(AL_POSITION, position.getX(), position.getY(), position.getZ()); - alListenerfv(AL_ORIENTATION, m_listenerVec); #endif -} +} // reallyPositionListenerNow //----------------------------------------------------------------------------- /** Positional sound is cool, but creating a new object just to play a simple diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 8f9edc25b..6d5d2e542 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -70,6 +70,7 @@ public: SFX_SPEED, SFX_POSITION, SFX_VOLUME, + SFX_LISTENER, SFX_EXIT, }; // SFXCommands @@ -129,8 +130,17 @@ private: } // SFXCommand(Vec3) }; // SFXCommand // ======================================================================== - /** Listener position */ - Vec3 m_position; + + /** The position of the listener. Its lock will be used to + * access m_listener_{position,front, up}. */ + Synchronised m_listener_position; + + /** The direction the listener is facing. */ + Vec3 m_listener_front; + + /** Up vector of the listener. */ + Vec3 m_listener_up; + /** The buffers and info for all sound effects. These are shared among all * instances of SFXOpenal. */ @@ -145,9 +155,6 @@ private: /** To play non-positional sounds without having to create a new object for each */ std::map m_quick_sounds; - /** listener vector (position vector + up vector) */ - float m_listenerVec[6]; - /** If the sfx manager has been initialised. */ bool m_initialized; @@ -167,6 +174,8 @@ private: static void* mainLoop(void *obj); void deleteSFX(SFXBase *sfx); void queueCommand(SFXCommand *command); + void reallyPositionListenerNow(); + public: static void create(); static void destroy(); @@ -211,7 +220,8 @@ public: static bool checkError(const std::string &context); static const std::string getErrorString(int err); - void positionListener(const Vec3 &position, const Vec3 &front); + void positionListener(const Vec3 &position, + const Vec3 &front, const Vec3 &up); SFXBase* quickSound(const std::string &soundName); /** Called when sound was muted/unmuted */ @@ -224,7 +234,7 @@ public: // ------------------------------------------------------------------------ /** Returns the current position of the listener. */ - Vec3 getListenerPos() const { return m_position; } + Vec3 getListenerPos() const { return m_listener_position.getData(); } }; diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 446f308c1..5195773dd 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -372,7 +372,9 @@ void Camera::smoothMoveCamera(float dt) if (race_manager->getNumLocalPlayers() < 2) { - SFXManager::get()->positionListener(current_position, current_target - current_position); + SFXManager::get()->positionListener(current_position, + current_target - current_position, + Vec3(0,1,0)); } } // smoothMoveCamera @@ -578,7 +580,8 @@ void Camera::positionCamera(float dt, float above_kart, float cam_angle, if (race_manager->getNumLocalPlayers() < 2) { SFXManager::get()->positionListener(m_camera->getPosition(), - wanted_target - m_camera->getPosition()); + wanted_target - m_camera->getPosition(), + Vec3(0, 1, 0)); } } diff --git a/src/modes/cutscene_world.cpp b/src/modes/cutscene_world.cpp index 5134c4850..1713e3d0b 100644 --- a/src/modes/cutscene_world.cpp +++ b/src/modes/cutscene_world.cpp @@ -309,7 +309,8 @@ void CutsceneWorld::update(float dt) SFXManager::get()->positionListener(m_camera->getAbsolutePosition(), m_camera->getTarget() - - m_camera->getAbsolutePosition()); + m_camera->getAbsolutePosition(), + Vec3(0,1,0)); break; } diff --git a/src/states_screens/state_manager.cpp b/src/states_screens/state_manager.cpp index 366520c24..a1356e7d2 100644 --- a/src/states_screens/state_manager.cpp +++ b/src/states_screens/state_manager.cpp @@ -201,7 +201,7 @@ void StateManager::onGameStateChange(GameState new_state) { irr_driver->showPointer(); input_manager->setMode(InputManager::MENU); - SFXManager::get()->positionListener( Vec3(0,0,0), Vec3(0,1,0) ); + SFXManager::get()->positionListener( Vec3(0,0,0), Vec3(0,1,0), Vec3(0, 1, 0) ); if (new_state == MENU) { From aae834ba4b217985b9fd9adbb3b422ae8bc76892 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 08:13:55 +1100 Subject: [PATCH 073/112] Run the music manager from the sfx thread. --- src/audio/sfx_manager.cpp | 16 ++++++++++++++-- src/audio/sfx_manager.hpp | 2 ++ src/main_loop.cpp | 4 ++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 079c59714..b836d25ea 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -214,9 +214,19 @@ void SFXManager::queueCommand(SFXCommand *command) m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); // Wake up the sfx thread - pthread_cond_signal(&m_cond_request); } // queueCommand +//---------------------------------------------------------------------------- +/** Make sures that the sfx thread is started at least one per frame. It also + * adds an update command for the music manager. + * \param dt Time step size. + */ +void SFXManager::update(float dt) +{ + queue(SFX_UPDATE_MUSIC, NULL, dt); + pthread_cond_signal(&m_cond_request); +} // update + //---------------------------------------------------------------------------- /** Puts a NULL request into the queue, which will trigger the thread to * exit. @@ -279,6 +289,8 @@ void* SFXManager::mainLoop(void *obj) me->deleteSFX(current->m_sfx); break; } case SFX_LISTENER: me->reallyPositionListenerNow(); break; + case SFX_UPDATE_MUSIC: music_manager->update( + current->m_parameter.getX()); break; default: assert("Not yet supported."); } delete current; @@ -326,7 +338,7 @@ void SFXManager::soundToggled(const bool on) { pauseAll(); } -} +} // soundToggled //---------------------------------------------------------------------------- /** Returns if sfx can be played. This means sfx are enabled and diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 6d5d2e542..eb41f701c 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -71,6 +71,7 @@ public: SFX_POSITION, SFX_VOLUME, SFX_LISTENER, + SFX_UPDATE_MUSIC, SFX_EXIT, }; // SFXCommands @@ -213,6 +214,7 @@ public: void deleteSFXMapping(const std::string &name); void pauseAll(); void resumeAll(); + void update(float dt); bool soundExist(const std::string &name); void setMasterSFXVolume(float gain); float getMasterSFXVolume() const { return m_master_gain; } diff --git a/src/main_loop.cpp b/src/main_loop.cpp index 216bdcbc6..4e7bccff0 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -21,7 +21,7 @@ #include -#include "audio/music_manager.hpp" +#include "audio/sfx_manager.hpp" #include "config/user_config.hpp" #include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" @@ -138,7 +138,7 @@ void MainLoop::run() if (!m_abort && !ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); - music_manager->update(dt); + SFXManager::get()->update(dt); input_manager->update(dt); #ifdef ENABLE_WIIUSE From 140ea5ed84cb9356b928ee41e422b6e07d8818e3 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 08:21:26 +1100 Subject: [PATCH 074/112] Update comments. --- src/audio/sfx_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index b836d25ea..6374c401d 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -213,7 +213,6 @@ void SFXManager::queueCommand(SFXCommand *command) m_sfx_commands.lock(); m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); - // Wake up the sfx thread } // queueCommand //---------------------------------------------------------------------------- @@ -224,6 +223,7 @@ void SFXManager::queueCommand(SFXCommand *command) void SFXManager::update(float dt) { queue(SFX_UPDATE_MUSIC, NULL, dt); + // Wake up the sfx thread to handle all queued up audio commands. pthread_cond_signal(&m_cond_request); } // update From 0cccb5f1d598666699fe2df395c4359e35a83ca6 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 09:11:56 +1100 Subject: [PATCH 075/112] Fixed typo. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85c5e0c76..960ff5cd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ * Added Tutorial * Added new Supertux difficulty * New bubblegum shield weapon -* New Speeodmeter and nitro meter +* New Speedometer and nitro meter * Add ability to filter addons * Updated nitro models * Add ability to save and resume Grand Prix From c61b7d632df0938afb6a9b920a4b7c3cb5bbd373 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 12:48:48 +1100 Subject: [PATCH 076/112] Fix stk hanging on exit. --- src/audio/sfx_manager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 6374c401d..40eadb184 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -234,6 +234,8 @@ void SFXManager::update(float dt) void SFXManager::stopThread() { queue(SFX_EXIT, NULL); + // Make sure the thread wakes up. + pthread_cond_signal(&m_cond_request); } // stopThread //---------------------------------------------------------------------------- From a18766e3e649f26ec5cd0332fe6c08c63d09cd0f Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 16:57:12 +1100 Subject: [PATCH 077/112] Handle looping in sfx thread. --- src/audio/dummy_sfx.hpp | 1 + src/audio/sfx_base.hpp | 1 + src/audio/sfx_manager.cpp | 2 ++ src/audio/sfx_manager.hpp | 1 + src/audio/sfx_openal.cpp | 10 +++++++++- src/audio/sfx_openal.hpp | 1 + 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 8f5572431..6f0997f71 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -37,6 +37,7 @@ public: virtual bool init() { return true; } virtual void setLoop(bool status) {} + virtual void reallySetLoop(bool status) {} virtual void setPosition(const Vec3 &p) {} virtual void reallySetPosition(const Vec3 &p) {} virtual void play() {} diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index a23ef0dbb..ea0e33a14 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -56,6 +56,7 @@ public: virtual void setPosition(const Vec3 &p) = 0; virtual void reallySetPosition(const Vec3 &p) = 0; virtual void setLoop(bool status) = 0; + virtual void reallySetLoop(bool status) = 0; virtual bool isPlaying() = 0; virtual void play() = 0; virtual void reallyPlayNow() = 0; diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 40eadb184..5efd57c90 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -286,6 +286,8 @@ void* SFXManager::mainLoop(void *obj) current->m_parameter); break; case SFX_VOLUME: current->m_sfx->reallySetVolume( current->m_parameter.getX()); break; + case SFX_LOOP: current->m_sfx->reallySetLoop( + current->m_parameter.getX()!=0); break; case SFX_DELETE: { current->m_sfx->reallyStopNow(); me->deleteSFX(current->m_sfx); break; diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index eb41f701c..0f5db39f2 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -70,6 +70,7 @@ public: SFX_SPEED, SFX_POSITION, SFX_VOLUME, + SFX_LOOP, SFX_LISTENER, SFX_UPDATE_MUSIC, SFX_EXIT, diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index dd1fdb086..63d0e973c 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -207,6 +207,14 @@ void SFXOpenAL::setMasterVolume(float gain) /** Loops this sound effect. */ void SFXOpenAL::setLoop(bool status) +{ + SFXManager::get()->queue(SFXManager::SFX_LOOP, this, status ? 1.0f : 0.0f); +} // setLoop + +//----------------------------------------------------------------------------- +/** Loops this sound effect. + */ +void SFXOpenAL::reallySetLoop(bool status) { m_loop = status; @@ -214,7 +222,7 @@ void SFXOpenAL::setLoop(bool status) alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE); SFXManager::checkError("looping"); -} // loop +} // reallySetLoop //----------------------------------------------------------------------------- /** Queues a stop for this effect to the sound manager. diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index a4b59b587..64d134cf7 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -85,6 +85,7 @@ public: virtual void play(); virtual void reallyPlayNow(); virtual void setLoop(bool status); + virtual void reallySetLoop(bool status); virtual bool isPlaying(); virtual void stop(); virtual void reallyStopNow(); From e4e0724cb9afe7a01df6f582a4fecfbf865b6a02 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 17:03:13 +1100 Subject: [PATCH 078/112] Removed unnecessary stop of music (music will stop anyway once the buffer is finished, but if music is completely threaded it might just keep on playing). --- src/modes/world_status.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index a969e7efd..d6bdb73f5 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -39,8 +39,6 @@ WorldStatus::WorldStatus() m_start_sound = SFXManager::get()->createSoundSource("start_race"); m_track_intro_sound = SFXManager::get()->createSoundSource("track_intro"); - music_manager->stopMusic(); - m_play_racestart_sounds = true; IrrlichtDevice *device = irr_driver->getDevice(); From 4bb1091f3e181b07aea336d9a5685ed96f2b8ee2 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 17:11:15 +1100 Subject: [PATCH 079/112] Moved sfx thread update to happen after graphics code is finished. This improves performance since threads in graphics code do not compete with threads in sfx handling anymore. --- src/main_loop.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main_loop.cpp b/src/main_loop.cpp index 4e7bccff0..730b663a6 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -138,7 +138,6 @@ void MainLoop::run() if (!m_abort && !ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); - SFXManager::get()->update(dt); input_manager->update(dt); #ifdef ENABLE_WIIUSE @@ -152,6 +151,13 @@ void MainLoop::run() irr_driver->update(dt); PROFILER_POP_CPU_MARKER(); + // Update sfx and music after graphics, so that graphics code + // can use as many threads as possible without interfering + // with audia + PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); + SFXManager::get()->update(dt); + PROFILER_POP_CPU_MARKER(); + PROFILER_PUSH_CPU_MARKER("Protocol manager update", 0x7F, 0x00, 0x7F); ProtocolManager::getInstance()->update(); PROFILER_POP_CPU_MARKER(); From 014bc7394055c5cdc9e03b72eb6711702e726b83 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 21:46:31 +1100 Subject: [PATCH 080/112] Don't create a sound effect for AIs if its volume is set to 0. --- src/karts/kart.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index d017ba85d..e361b4508 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1436,21 +1436,14 @@ void Kart::handleMaterialSFX(const Material *material) m_previous_terrain_sound->setLoop(false); const std::string &s = material->getSFXName(); - if (s != "") + + // In multiplayer mode sounds are NOT positional, because we have + // multiple listeners. This would make the sounds of all AIs be + // audible at all times. So silence AI karts. + if (s.size()!=0 && (race_manager->getNumPlayers()==1 || + m_controller->isPlayerController() ) ) { m_terrain_sound = SFXManager::get()->createSoundSource(s); - - // In multiplayer mode sounds are NOT positional, because we have - // multiple listeners. This would make the sounds of all AIs be - // audible at all times. So silence AI karts. - if (race_manager->getNumLocalPlayers() > 1) - { - if (!m_controller->isPlayerController()) - { - m_terrain_sound->setVolume( 0.0f ); - } - } - m_terrain_sound->play(); m_terrain_sound->setLoop(true); } From 3d15f13c741aeb64e485fc2be05bab0221f14c47 Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Oct 2014 23:45:09 +1100 Subject: [PATCH 081/112] iFixed #1624 (though it is a bit of a hack). --- src/audio/sfx_openal.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 63d0e973c..c95f6497c 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -338,7 +338,18 @@ void SFXOpenAL::reallyPlayNow() // At non-race time the end time is not important if(World::getWorld()) - m_end_time = World::getWorld()->getTime()+m_sound_buffer->getDuration(); + { + float t= World::getWorld()->getTime(); + // A special case: the track intro music starts at world clock = 0, + // and has a duration of 3.7 seconds. So if the game is paused in the + // first 3.7 seconds, the sfx wil be considered to be not finished + // (since the world clock stays at 0 before the race start), and + // therefore resumed if the game is resumed, which means it is + // played again. To avoid this, any sound starting at t=0 is set + // to have an end time of 0 - which means the track intro music is + // not resumed in this case. + m_end_time = t>0 ? t+m_sound_buffer->getDuration() : 0; + } else m_end_time = 1.0f; } // reallyPlayNow From 3499975b03c142b3fff07b5c4a1756c226edcda7 Mon Sep 17 00:00:00 2001 From: Deve Date: Thu, 16 Oct 2014 19:33:54 +0200 Subject: [PATCH 082/112] Move track name to center. It allows a bit longer track names and looks better. --- data/gui/select_challenge.stkgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/gui/select_challenge.stkgui b/data/gui/select_challenge.stkgui index e45870601..931b51db8 100644 --- a/data/gui/select_challenge.stkgui +++ b/data/gui/select_challenge.stkgui @@ -2,7 +2,7 @@
-
+
From a40d6d8a00810abcb172df09d1f7725fb9b1e358 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 08:27:40 +1100 Subject: [PATCH 083/112] Removed isPlaying function, and use getStatus instead. --- src/audio/dummy_sfx.hpp | 1 - src/audio/sfx_base.hpp | 1 - src/audio/sfx_manager.cpp | 2 -- src/audio/sfx_manager.hpp | 2 +- src/audio/sfx_openal.cpp | 61 ++++++++++++++++++--------------------- src/audio/sfx_openal.hpp | 9 +++--- src/karts/kart.cpp | 4 +-- 7 files changed, 35 insertions(+), 45 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 6f0997f71..72f2ac17e 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -56,7 +56,6 @@ public: virtual SFXStatus getStatus() { return SFX_STOPPED; } virtual void onSoundEnabledBack() {} virtual void setRolloff(float rolloff) {} - virtual bool isPlaying() { return false; } virtual const SFXBuffer* getBuffer() const { return NULL; } }; // DummySFX diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index ea0e33a14..e0663ec0d 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -57,7 +57,6 @@ public: virtual void reallySetPosition(const Vec3 &p) = 0; virtual void setLoop(bool status) = 0; virtual void reallySetLoop(bool status) = 0; - virtual bool isPlaying() = 0; virtual void play() = 0; virtual void reallyPlayNow() = 0; virtual void stop() = 0; diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 5efd57c90..2fcff4e5c 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -526,8 +526,6 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer, m_all_sfx.getData().push_back(sfx); m_all_sfx.unlock(); } - else - printf(""); return sfx; } // createSoundSource diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 0f5db39f2..aa9d918ff 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -207,7 +207,7 @@ public: const bool load = true); SFXBase* createSoundSource(SFXBuffer* info, - const bool addToSFXList=true, + const bool add_to_SFX_list=true, const bool owns_buffer=false); SFXBase* createSoundSource(const std::string &name, const bool addToSFXList=true); diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index c95f6497c..53e5e5b8e 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -1,7 +1,8 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2006-2013 Patrick Ammann -// Copyright (C) 2009-2013 Marianne Gagnon +// Copyright (C) 2014 Joerg Henrichs +// Copyright (C) 2006-2014 Patrick Ammann +// Copyright (C) 2009-2014 Marianne Gagnon // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -37,14 +38,15 @@ #include #include -SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool owns_buffer) : SFXBase() +SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, + bool owns_buffer) + : SFXBase() { m_sound_buffer = buffer; m_sound_source = 0; m_status = SFX_UNKNOWN; - m_is_playing = false; m_positional = positional; - m_defaultGain = gain; + m_default_gain = gain; m_loop = false; m_gain = -1.0f; m_master_gain = 1.0f; @@ -78,7 +80,8 @@ SFXOpenAL::~SFXOpenAL() } // ~SFXOpenAL //----------------------------------------------------------------------------- - +/** Initialises the sfx. + */ bool SFXOpenAL::init() { alGenSources(1, &m_sound_source ); @@ -101,7 +104,7 @@ bool SFXOpenAL::init() if (m_gain < 0.0f) { - alSourcef (m_sound_source, AL_GAIN, m_defaultGain * m_master_gain); + alSourcef (m_sound_source, AL_GAIN, m_default_gain * m_master_gain); } else { @@ -113,10 +116,11 @@ bool SFXOpenAL::init() alSourcei(m_sound_source, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE); - if(SFXManager::checkError("setting up the source")) - m_status = SFX_INITIAL; + if(!SFXManager::checkError("setting up the source")) + return false; - return m_status==SFX_INITIAL; + m_status = SFX_STOPPED; + return true; } // init // ------------------------------------------------------------------------ @@ -152,7 +156,6 @@ void SFXOpenAL::setSpeed(float factor) */ void SFXOpenAL::reallySetSpeed(float factor) { - if(m_status==SFX_UNKNOWN) return; //OpenAL only accepts pitches in the range of 0.5 to 2.0 if(factor > 2.0f) { @@ -182,8 +185,7 @@ void SFXOpenAL::setVolume(float gain) */ void SFXOpenAL::reallySetVolume(float gain) { - if(m_status==SFX_UNKNOWN) return; - m_gain = m_defaultGain * gain; + m_gain = m_default_gain * gain; if(m_status==SFX_UNKNOWN) return; @@ -199,7 +201,7 @@ void SFXOpenAL::setMasterVolume(float gain) if(m_status==SFX_UNKNOWN) return; alSourcef(m_sound_source, AL_GAIN, - (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); + (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); SFXManager::checkError("setting volume"); } //setMasterVolume @@ -239,7 +241,6 @@ void SFXOpenAL::reallyStopNow() { if(m_status==SFX_UNKNOWN) return; - m_is_playing = false; m_status = SFX_STOPPED; m_loop = false; alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); @@ -313,7 +314,7 @@ void SFXOpenAL::play() // Technically the sfx is only playing after the sfx thread starts it, // but for STK this is correct since we don't want to start the same // sfx twice. - m_is_playing = true; + m_status = SFX_PLAYING; SFXManager::get()->queue(SFXManager::SFX_PLAY, this); } // play @@ -333,7 +334,6 @@ void SFXOpenAL::reallyPlayNow() } alSourcePlay(m_sound_source); - m_status = SFX_PLAYING; SFXManager::checkError("playing"); // At non-race time the end time is not important @@ -354,14 +354,6 @@ void SFXOpenAL::reallyPlayNow() m_end_time = 1.0f; } // reallyPlayNow -//----------------------------------------------------------------------------- -/** Returns true if the sound effect is currently playing. - */ -bool SFXOpenAL::isPlaying() -{ - return m_is_playing; -} // isPlaying - //----------------------------------------------------------------------------- /** Sets the position where this sound effects is played. * \param position Position of the sound effect. @@ -389,9 +381,9 @@ void SFXOpenAL::reallySetPosition(const Vec3 &position) } if (!m_positional) { - // in multiplayer, all sounds are positional, so in this case don't bug users with - // an error message if (race_manager->getNumLocalPlayers() > 1) - // (note that 0 players is also possible, in cutscenes) + // in multiplayer, all sounds are positional, so in this case don't + // bug users with an error message if (note that 0 players is also + // possible, in cutscenes) if (race_manager->getNumLocalPlayers() < 2) { Log::warn("SFX", "Position called on non-positional SFX"); @@ -399,16 +391,18 @@ void SFXOpenAL::reallySetPosition(const Vec3 &position) return; } - alSource3f(m_sound_source, AL_POSITION, - (float)position.getX(), (float)position.getY(), (float)position.getZ()); + alSource3f(m_sound_source, AL_POSITION, (float)position.getX(), + (float)position.getY(), (float)position.getZ()); - if (SFXManager::get()->getListenerPos().distance(position) > m_sound_buffer->getMaxDist()) + if (SFXManager::get()->getListenerPos().distance(position) + > m_sound_buffer->getMaxDist()) { alSourcef(m_sound_source, AL_GAIN, 0); } else { - alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); + alSourcef(m_sound_source, AL_GAIN, + (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); } SFXManager::checkError("positioning"); @@ -426,7 +420,8 @@ void SFXOpenAL::onSoundEnabledBack() alSourcef(m_sound_source, AL_GAIN, 0); play(); pause(); - alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); + alSourcef(m_sound_source, AL_GAIN, + (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); } } } // onSoundEnabledBack diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 64d134cf7..7ba7ca456 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -48,8 +48,11 @@ private: /** The status of this SFX. */ SFXStatus m_status; + /** If the sfx is positional. */ bool m_positional; - float m_defaultGain; + + /** Default gain value. */ + float m_default_gain; /** The OpenAL source contains this info, but if audio is disabled initially then the sound source won't be created and we'll be left with no clue when enabling @@ -62,9 +65,6 @@ private: the sound source won't be created and we'll be left with no clue when enabling sounds later. */ float m_gain; - - /** True when the sfx is currently playing. */ - bool m_is_playing; /** The master gain set in user preferences */ float m_master_gain; @@ -86,7 +86,6 @@ public: virtual void reallyPlayNow(); virtual void setLoop(bool status); virtual void reallySetLoop(bool status); - virtual bool isPlaying(); virtual void stop(); virtual void reallyStopNow(); virtual void pause(); diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index e361b4508..42f6c8577 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -2010,10 +2010,10 @@ void Kart::updatePhysics(float dt) m_skidding->getSkidState() == Skidding::SKID_ACCUMULATE_RIGHT ) && m_skidding->getGraphicalJumpOffset()==0) { - if(!m_skid_sound->isPlaying() && !isWheeless()) + if(m_skid_sound->getStatus()!=SFXBase::SFX_PLAYING && !isWheeless()) m_skid_sound->play(); } - else if(m_skid_sound->isPlaying()) + else if(m_skid_sound->getStatus()==SFXBase::SFX_PLAYING) { m_skid_sound->stop(); } From 1bd9fc0423499597220f92301e544d5c1ef32664 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Thu, 16 Oct 2014 18:40:49 -0400 Subject: [PATCH 084/112] Fix mesh tangents caching --- src/graphics/mesh_tools.cpp | 41 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/graphics/mesh_tools.cpp b/src/graphics/mesh_tools.cpp index a5fc3db63..2993dfd6c 100644 --- a/src/graphics/mesh_tools.cpp +++ b/src/graphics/mesh_tools.cpp @@ -388,28 +388,28 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh, bool(*predic { switch (vType) { - case video::EVT_STANDARD: - { - const video::S3DVertex* v = - (const video::S3DVertex*)original->getVertices(); - vNew = video::S3DVertexTangents( - v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); - } + case video::EVT_STANDARD: + { + const video::S3DVertex* v = + (const video::S3DVertex*)original->getVertices(); + vNew = video::S3DVertexTangents( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); + } break; - case video::EVT_2TCOORDS: - { - const video::S3DVertex2TCoords* v = - (const video::S3DVertex2TCoords*)original->getVertices(); - vNew = video::S3DVertexTangents( - v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); - } + case video::EVT_2TCOORDS: + { + const video::S3DVertex2TCoords* v = + (const video::S3DVertex2TCoords*)original->getVertices(); + vNew = video::S3DVertexTangents( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); + } break; - case video::EVT_TANGENTS: - { - const video::S3DVertexTangents* v = - (const video::S3DVertexTangents*)original->getVertices(); - vNew = v[idx[i]]; - } + case video::EVT_TANGENTS: + { + const video::S3DVertexTangents* v = + (const video::S3DVertexTangents*)original->getVertices(); + vNew = v[idx[i]]; + } break; } core::map::Node* n = vertMap.find(vNew); @@ -457,7 +457,6 @@ scene::IMesh* MeshTools::createMeshWithTangents(scene::IMesh* mesh, bool(*predic scene::SAnimatedMesh* amesh = new scene::SAnimatedMesh(clone); meshCache->addMesh(path, amesh); - amesh->drop(); World::getWorld()->getTrack()->addCachedMesh(amesh); From 813edc7ddf1f5432175aff187d302692eb6a13e4 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 12:00:00 +1100 Subject: [PATCH 085/112] Remove SFX_INITIAL state. --- src/audio/sfx_base.hpp | 3 +-- src/audio/sfx_openal.cpp | 6 ++++-- src/graphics/hit_sfx.cpp | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index e0663ec0d..50fc0aee9 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -45,8 +45,7 @@ public: /** Status of a sound effect. */ enum SFXStatus { - SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2, - SFX_INITIAL = 3 + SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2 }; virtual ~SFXBase() {} diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 53e5e5b8e..20d6a0d59 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -312,8 +312,10 @@ void SFXOpenAL::deleteSFX() void SFXOpenAL::play() { // Technically the sfx is only playing after the sfx thread starts it, - // but for STK this is correct since we don't want to start the same - // sfx twice. + // but this is important to set this here since stk might decide the + // delete a sfx if it has finished playing (i.e. is in stopped state) + // - which can happen if the sfx thread had no time to actually start + // it yet. m_status = SFX_PLAYING; SFXManager::get()->queue(SFXManager::SFX_PLAY, this); } // play diff --git a/src/graphics/hit_sfx.cpp b/src/graphics/hit_sfx.cpp index e9018a474..1a1f45c58 100644 --- a/src/graphics/hit_sfx.cpp +++ b/src/graphics/hit_sfx.cpp @@ -65,6 +65,5 @@ void HitSFX::setPlayerKartHit() bool HitSFX::updateAndDelete(float dt) { SFXBase::SFXStatus status = m_sfx->getStatus(); - if(status==SFXBase::SFX_INITIAL) return false; return status!= SFXBase::SFX_PLAYING; } // updateAndDelete From c7f37297b1cbd7515d1f0f873151ed92ca4181e7 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 12:02:23 +1100 Subject: [PATCH 086/112] Fixed potential deadlock (if a sfx is not found in the queue, which shouldn't happen); stop sounds which are deleted only once, slightly reduce size of locked region. --- src/audio/sfx_manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 2fcff4e5c..81370c94b 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -289,7 +289,6 @@ void* SFXManager::mainLoop(void *obj) case SFX_LOOP: current->m_sfx->reallySetLoop( current->m_parameter.getX()!=0); break; case SFX_DELETE: { - current->m_sfx->reallyStopNow(); me->deleteSFX(current->m_sfx); break; } case SFX_LISTENER: me->reallyPositionListenerNow(); break; @@ -598,13 +597,14 @@ void SFXManager::deleteSFX(SFXBase *sfx) Log::warn("SFXManager", "SFXManager::deleteSFX : Warning: sfx '%s' %lx not found in list.", sfx->getBuffer()->getFileName().c_str(), sfx); + m_all_sfx.unlock(); return; } m_all_sfx.getData().erase(i); - delete sfx; - m_all_sfx.unlock(); + + delete sfx; } // deleteSFX //---------------------------------------------------------------------------- From 403702d6bbdf8d2acb96b2e15bd77ab5ff3363c6 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 16:26:15 +1100 Subject: [PATCH 087/112] Handle pauseAll and resumeAll completely in thread now. Avoids a crash (caused by pauseAll trying to pause a sfx that is still in the list of all sfx, but has a delete command already queued up). --- src/audio/sfx_manager.cpp | 35 +++++++++++++++++++++++++++-------- src/audio/sfx_manager.hpp | 6 +++++- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 81370c94b..3cf632c17 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -233,7 +233,7 @@ void SFXManager::update(float dt) */ void SFXManager::stopThread() { - queue(SFX_EXIT, NULL); + queue(SFX_EXIT); // Make sure the thread wakes up. pthread_cond_signal(&m_cond_request); } // stopThread @@ -291,7 +291,9 @@ void* SFXManager::mainLoop(void *obj) case SFX_DELETE: { me->deleteSFX(current->m_sfx); break; } - case SFX_LISTENER: me->reallyPositionListenerNow(); break; + case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break; + case SFX_RESUME_ALL: me->reallyResumeAllNow(); break; + case SFX_LISTENER: me->reallyPositionListenerNow(); break; case SFX_UPDATE_MUSIC: music_manager->update( current->m_parameter.getX()); break; default: assert("Not yet supported."); @@ -610,24 +612,41 @@ void SFXManager::deleteSFX(SFXBase *sfx) //---------------------------------------------------------------------------- /** Pauses all looping SFXs. Non-looping SFX will be finished, since it's * otherwise not possible to determine which SFX must be resumed (i.e. were - * actually playing at the time pause was called. + * actually playing at the time pause was called). */ void SFXManager::pauseAll() +{ + queue(SFX_PAUSE_ALL); +} // pauseAll + +//---------------------------------------------------------------------------- +/** Pauses all looping SFXs. Non-looping SFX will be finished, since it's + * otherwise not possible to determine which SFX must be resumed (i.e. were + * actually playing at the time pause was called. + */ +void SFXManager::reallyPauseAllNow() { m_all_sfx.lock(); for (std::vector::iterator i= m_all_sfx.getData().begin(); i!=m_all_sfx.getData().end(); i++) { - (*i)->pause(); + (*i)->reallyPauseNow(); } // for i in m_all_sfx m_all_sfx.unlock(); } // pauseAll //---------------------------------------------------------------------------- -/** - * Resumes all paused SFXs. If sound is disabled, does nothing. +/** Resumes all paused SFXs. If sound is disabled, does nothing. */ void SFXManager::resumeAll() +{ + queue(SFX_RESUME_ALL); +} // resumeAll + +//---------------------------------------------------------------------------- +/** Resumes all paused SFXs. If sound is disabled, does nothing. + */ +void SFXManager::reallyResumeAllNow() { // ignore unpausing if sound is disabled if (!sfxAllowed()) return; @@ -636,7 +655,7 @@ void SFXManager::resumeAll() for (std::vector::iterator i =m_all_sfx.getData().begin(); i!=m_all_sfx.getData().end(); i++) { - (*i)->resume(); + (*i)->reallyResumeNow(); } // for i in m_all_sfx m_all_sfx.unlock(); } // resumeAll @@ -729,7 +748,7 @@ void SFXManager::positionListener(const Vec3 &position, const Vec3 &front, m_listener_front = front; m_listener_up = up; m_listener_position.unlock(); - queue(SFX_LISTENER, NULL); + queue(SFX_LISTENER); } // positionListener //----------------------------------------------------------------------------- diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index aa9d918ff..09ba8ba42 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -65,7 +65,9 @@ public: SFX_PLAY = 1, SFX_STOP, SFX_PAUSE, + SFX_PAUSE_ALL, SFX_RESUME, + SFX_RESUME_ALL, SFX_DELETE, SFX_SPEED, SFX_POSITION, @@ -181,7 +183,7 @@ private: public: static void create(); static void destroy(); - void queue(SFXCommands command, SFXBase *sfx); + void queue(SFXCommands command, SFXBase *sfx=NULL); void queue(SFXCommands command, SFXBase *sfx, float f); void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p); // ------------------------------------------------------------------------ @@ -214,7 +216,9 @@ public: void deleteSFXMapping(const std::string &name); void pauseAll(); + void reallyPauseAllNow(); void resumeAll(); + void reallyResumeAllNow(); void update(float dt); bool soundExist(const std::string &name); void setMasterSFXVolume(float gain); From 0a39842b04270a3157c41ec57663130974cad0d3 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 16:49:14 +1100 Subject: [PATCH 088/112] Throttle sfx command if the queue should get too long (might need some tuning). Non-essential sfx (positioning, speed, looping, and play) are discarded. --- src/audio/sfx_manager.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 3cf632c17..f255f1e82 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -101,7 +101,7 @@ SFXManager::SFXManager() delete m_thread_id.getData(); m_thread_id.unlock(); m_thread_id.setAtomic(0); - Log::error("HTTP Manager", "Could not create thread, error=%d.", + Log::error("SFXManager", "Could not create thread, error=%d.", errno); } pthread_attr_destroy(&attr); @@ -211,6 +211,23 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p) void SFXManager::queueCommand(SFXCommand *command) { m_sfx_commands.lock(); + if(m_sfx_commands.getData().size() > 20*race_manager->getNumberOfKarts()+20) + { + if(command->m_command==SFX_POSITION || command->m_command==SFX_LOOP || + command->m_command==SFX_PLAY || command->m_command==SFX_SPEED ) + { + delete command; + static int count_messages = 0; + if(count_messages < 5) + { + Log::warn("SFXManager", "Throttling sfx - queue size %d", + m_sfx_commands.getData().size()); + count_messages++; + } + m_sfx_commands.unlock(); + return; + } // if throttling + } m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); } // queueCommand @@ -266,13 +283,12 @@ void* SFXManager::mainLoop(void *obj) pthread_cond_wait(&me->m_cond_request, me->m_sfx_commands.getMutex()); empty = me->m_sfx_commands.getData().empty(); } - SFXCommand *current = me->m_sfx_commands.getData().front(); me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); if (current->m_command == SFX_EXIT) break; - + Log::verbose("sfx", "%d", me->m_sfx_commands.getData().size()); me->m_sfx_commands.unlock(); switch(current->m_command) { @@ -443,7 +459,7 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name, } if (UserConfigParams::logMisc()) - Log::debug("SFXManager", "Loading SFX %s\n", sfx_file.c_str()); + Log::debug("SFXManager", "Loading SFX %s", sfx_file.c_str()); if (load && buffer->load()) return buffer; @@ -463,7 +479,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, if (node->get("filename", &filename) == 0) { Log::error("SFXManager", - "/!\\ The 'filename' attribute is mandatory in the SFX XML file!\n"); + "The 'filename' attribute is mandatory in the SFX XML file!"); return NULL; } @@ -472,7 +488,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, if(m_all_sfx_types.find(sfx_name)!=m_all_sfx_types.end()) { Log::error("SFXManager", - "There is already a sfx named '%s' installed - new one is ignored.\n", + "There is already a sfx named '%s' installed - new one is ignored.", sfx_name.c_str()); return NULL; } @@ -540,7 +556,7 @@ SFXBase* SFXManager::createSoundSource(const std::string &name, { Log::error("SFXManager", "SFXManager::createSoundSource could not find the " - "requested sound effect : '%s'\n", name.c_str()); + "requested sound effect : '%s'.", name.c_str()); return NULL; } From 7103ea8e88410f65036c40211de3f2f7a4f88420 Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 17 Oct 2014 16:49:14 +1100 Subject: [PATCH 089/112] Throttle sfx command if the queue should get too long (might need some tuning). Non-essential sfx (positioning, speed, looping, and play) are discarded. --- src/audio/sfx_manager.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 3cf632c17..fb4251931 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -101,7 +101,7 @@ SFXManager::SFXManager() delete m_thread_id.getData(); m_thread_id.unlock(); m_thread_id.setAtomic(0); - Log::error("HTTP Manager", "Could not create thread, error=%d.", + Log::error("SFXManager", "Could not create thread, error=%d.", errno); } pthread_attr_destroy(&attr); @@ -211,6 +211,23 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p) void SFXManager::queueCommand(SFXCommand *command) { m_sfx_commands.lock(); + if(m_sfx_commands.getData().size() > 20*race_manager->getNumberOfKarts()+20) + { + if(command->m_command==SFX_POSITION || command->m_command==SFX_LOOP || + command->m_command==SFX_PLAY || command->m_command==SFX_SPEED ) + { + delete command; + static int count_messages = 0; + if(count_messages < 5) + { + Log::warn("SFXManager", "Throttling sfx - queue size %d", + m_sfx_commands.getData().size()); + count_messages++; + } + m_sfx_commands.unlock(); + return; + } // if throttling + } m_sfx_commands.getData().push_back(command); m_sfx_commands.unlock(); } // queueCommand @@ -266,13 +283,11 @@ void* SFXManager::mainLoop(void *obj) pthread_cond_wait(&me->m_cond_request, me->m_sfx_commands.getMutex()); empty = me->m_sfx_commands.getData().empty(); } - SFXCommand *current = me->m_sfx_commands.getData().front(); me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); if (current->m_command == SFX_EXIT) break; - me->m_sfx_commands.unlock(); switch(current->m_command) { @@ -443,7 +458,7 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name, } if (UserConfigParams::logMisc()) - Log::debug("SFXManager", "Loading SFX %s\n", sfx_file.c_str()); + Log::debug("SFXManager", "Loading SFX %s", sfx_file.c_str()); if (load && buffer->load()) return buffer; @@ -463,7 +478,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, if (node->get("filename", &filename) == 0) { Log::error("SFXManager", - "/!\\ The 'filename' attribute is mandatory in the SFX XML file!\n"); + "The 'filename' attribute is mandatory in the SFX XML file!"); return NULL; } @@ -472,7 +487,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, if(m_all_sfx_types.find(sfx_name)!=m_all_sfx_types.end()) { Log::error("SFXManager", - "There is already a sfx named '%s' installed - new one is ignored.\n", + "There is already a sfx named '%s' installed - new one is ignored.", sfx_name.c_str()); return NULL; } @@ -540,7 +555,7 @@ SFXBase* SFXManager::createSoundSource(const std::string &name, { Log::error("SFXManager", "SFXManager::createSoundSource could not find the " - "requested sound effect : '%s'\n", name.c_str()); + "requested sound effect : '%s'.", name.c_str()); return NULL; } From f67f207d4b6fcda59bc0396625778213ce4391e0 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Oct 2014 18:19:23 +0200 Subject: [PATCH 090/112] Start fixing speedmeter --- src/graphics/glwrap.cpp | 33 +++++++++++++++++ src/graphics/glwrap.hpp | 66 +++++++++++++++++++++++++++++++++ src/states_screens/race_gui.cpp | 6 +-- 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 86a84c5a5..d6d0ef9bf 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -655,6 +655,39 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect glGetError(); } +void draw2DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) +{ + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); + return; + } + GLuint tmpvao, tmpvbo, tmpibo; + glGenVertexArrays(1, &tmpvao); + glBindVertexArray(tmpvao); + glGenBuffers(1, &tmpvbo); + glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); + glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); + glGenBuffers(1, &tmpibo); + glBindBuffer(GL_ARRAY_BUFFER, tmpibo); + glBufferData(GL_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); + + glUseProgram(MeshShader::TransparentShader::getInstance()->Program); + MeshShader::TransparentShader::getInstance()->setUniforms(core::IdentityMatrix, core::IdentityMatrix); + const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); + video::ITexture* tex = getUnicolorTexture(video::SColor(255, 255, 255, 255)); + compressTexture(tex, false); + MeshShader::TransparentShader::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); + glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); + + glDeleteVertexArrays(1, &tmpvao); + glDeleteBuffers(1, &tmpvbo); + glDeleteBuffers(1, &tmpibo); + +} + void GL32_draw2DRectangle(video::SColor color, const core::rect& position, const core::rect* clip) { diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 3477b649b..dabf530f8 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -132,6 +132,68 @@ public: void BlitToDefault(size_t, size_t, size_t, size_t); }; +class VertexUtils +{ +public: + static void bindVertexArrayAttrib(enum video::E_VERTEX_TYPE tp) + { + switch (tp) + { + case video::EVT_STANDARD: + // Position + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), 0); + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)12); + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(tp), (GLvoid*)24); + // Texcoord + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)28); + break; + case video::EVT_2TCOORDS: + // Position + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), 0); + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)12); + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(tp), (GLvoid*)24); + // Texcoord + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)28); + // SecondTexcoord + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)36); + break; + case video::EVT_TANGENTS: + // Position + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), 0); + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)12); + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(tp), (GLvoid*)24); + // Texcoord + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)28); + // Tangent + glEnableVertexAttribArray(5); + glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)36); + // Bitangent + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)48); + break; + } + } +}; + // core::rect needs these includes #include #include "utils/vec3.hpp" @@ -153,6 +215,10 @@ void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect const irr::core::rect& sourceRect, const irr::core::rect* clipRect, const irr::video::SColor* const colors, bool useAlphaChannelOfTexture); +void draw2DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + video::E_VERTEX_TYPE vType = video::EVT_STANDARD, scene::E_PRIMITIVE_TYPE pType = scene::EPT_TRIANGLES, video::E_INDEX_TYPE iType = video::EIT_16BIT); + void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect& position, const irr::core::rect* clip = 0); diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 5accb0fd0..55b1327a5 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -506,7 +506,7 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart, m.setTexture(0, m_gauge_goal); m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; irr_driver->getVideoDriver()->setMaterial(m); - irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, count, + draw2DVertexPrimitiveList(vertices, count, index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN); } @@ -594,7 +594,7 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart, m.setTexture(0, m_gauge_full); m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; irr_driver->getVideoDriver()->setMaterial(m); - irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, count, + draw2DVertexPrimitiveList(vertices, count, index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN); } @@ -800,7 +800,7 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart, m.setTexture(0, m_speed_bar_icon->getTexture()); m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; irr_driver->getVideoDriver()->setMaterial(m); - irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, count, + draw2DVertexPrimitiveList(vertices, count, index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN); } // drawSpeedEnergyRank From ce7f017adf0ced5f8d7de4780e5676333c97fbe2 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Oct 2014 18:43:39 +0200 Subject: [PATCH 091/112] Some fixes --- data/shaders/primitive2dlist.vert | 27 +++++++++++++++++++++++++++ src/graphics/glwrap.cpp | 13 ++++++++----- src/graphics/shaders.cpp | 10 ++++++++++ src/graphics/shaders.hpp | 7 +++++++ 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 data/shaders/primitive2dlist.vert diff --git a/data/shaders/primitive2dlist.vert b/data/shaders/primitive2dlist.vert new file mode 100644 index 000000000..d0b43a6c5 --- /dev/null +++ b/data/shaders/primitive2dlist.vert @@ -0,0 +1,27 @@ +#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; +layout(location = 4) in vec2 SecondTexcoord; +layout(location = 5) in vec3 Tangent; +layout(location = 6) in vec3 Bitangent; +#else +in vec3 Position; +in vec3 Normal; +in vec4 Color; +in vec2 Texcoord; +in vec2 SecondTexcoord; +in vec3 Tangent; +in vec3 Bitangent; +#endif + +out vec2 uv; +out vec4 color; + +void main(void) +{ + color = Color.zyxw; + gl_Position = vec4(Position, 1.) / vec4(screen, 1., 1.); + uv = Texcoord; +} diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index d6d0ef9bf..cb3c19f88 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -665,21 +665,24 @@ void draw2DVertexPrimitiveList(const void* vertices, return; } GLuint tmpvao, tmpvbo, tmpibo; + primitiveCount += 2; glGenVertexArrays(1, &tmpvao); glBindVertexArray(tmpvao); glGenBuffers(1, &tmpvbo); glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); glGenBuffers(1, &tmpibo); - glBindBuffer(GL_ARRAY_BUFFER, tmpibo); - glBufferData(GL_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); - glUseProgram(MeshShader::TransparentShader::getInstance()->Program); - MeshShader::TransparentShader::getInstance()->setUniforms(core::IdentityMatrix, core::IdentityMatrix); + VertexUtils::bindVertexArrayAttrib(vType); + + glUseProgram(UIShader::Primitive2DList::getInstance()->Program); + UIShader::Primitive2DList::getInstance()->setUniforms(); const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); video::ITexture* tex = getUnicolorTexture(video::SColor(255, 255, 255, 255)); compressTexture(tex, false); - MeshShader::TransparentShader::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); + UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); glDeleteVertexArrays(1, &tmpvao); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 1a5945c04..97e6b6020 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1749,6 +1749,16 @@ namespace FullScreenShader namespace UIShader { + + Primitive2DList::Primitive2DList() + { + Program = LoadProgram(OBJECT, + GL_VERTEX_SHADER, file_manager->getAsset("shaders/primitive2dlist.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/transparent.frag").c_str()); + AssignUniforms(); + AssignSamplerNames(Program, 0, "tex"); + } + TextureRectShader::TextureRectShader() { Program = LoadProgram(OBJECT, diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 1d498c930..edd5a58d4 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -580,6 +580,13 @@ public: namespace UIShader { + +class Primitive2DList : public ShaderHelperSingleton, public TextureRead < Bilinear_Filtered > +{ +public: + Primitive2DList(); +}; + class TextureRectShader : public ShaderHelperSingleton, public TextureRead { public: From 2f45266c6f57e0b1a4923c2e5be5996d3bebad2b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Oct 2014 18:51:41 +0200 Subject: [PATCH 092/112] Fix position of speedmeter Only need to get the texture --- data/shaders/primitive2dlist.vert | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data/shaders/primitive2dlist.vert b/data/shaders/primitive2dlist.vert index d0b43a6c5..ceb835a89 100644 --- a/data/shaders/primitive2dlist.vert +++ b/data/shaders/primitive2dlist.vert @@ -22,6 +22,9 @@ out vec4 color; void main(void) { color = Color.zyxw; - gl_Position = vec4(Position, 1.) / vec4(screen, 1., 1.); + vec3 P = Position / vec3(screen, 1.); + P = 2. * P - 1.; + P.y *= -1; + gl_Position = vec4(P, 1.); uv = Texcoord; } From c95e90b925b6246d43daa96fbedc5b90648b059b Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Fri, 17 Oct 2014 19:24:21 -0400 Subject: [PATCH 093/112] Tweak checkbox position on login screen --- data/gui/user_screen.stkgui | 8 +++++--- data/gui/user_screen_tab.stkgui | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/data/gui/user_screen.stkgui b/data/gui/user_screen.stkgui index 63496bfe3..e636e3f73 100644 --- a/data/gui/user_screen.stkgui +++ b/data/gui/user_screen.stkgui @@ -15,13 +15,15 @@
-
-
Display the saved data m_online_cb->setState(true); makeEntryFieldsVisible(); - m_username_tb->setText(profile->getLastOnlineName()); getWidget("remember-user")->setState( profile->rememberPassword()); if(profile->getLastOnlineName().size()>0) @@ -231,14 +233,6 @@ void BaseUserScreen::makeEntryFieldsVisible() { getWidget("label_password")->setVisible(online); m_password_tb->setVisible(online); - if(player && player->hasSavedSession()) - { - // Even though this field is invisible we need to set - // the name, otherwise in update a change of user name - // will be detected, causing a clearing of this player - // (which then removes the associated online user name). - m_username_tb->setText(player->getLastOnlineName()); - } } } // makeEntryFieldsVisible @@ -446,18 +440,6 @@ void BaseUserScreen::onUpdate(float dt) m_info_widget->setText(StringUtils::loadingDots(message.c_str()), false ); } - PlayerProfile *player = getSelectedPlayer(); - if(player) - { - // If the player changes the online name, clear the saved session - // flag, and make the password field visible again. - if (m_username_tb->getText()!=player->getLastOnlineName()) - { - player->clearSession(); - makeEntryFieldsVisible(); - m_username_tb->setText(player->getLastOnlineName()); - } - } } // onUpdate // ---------------------------------------------------------------------------- From 5efea6fd1a3ef6e5aa5ab7e6add775e6091f9082 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Oct 2014 17:59:30 +0200 Subject: [PATCH 100/112] Factorise attribute binding function --- src/graphics/vaomanager.cpp | 72 +++++++++---------------------------- src/graphics/vaomanager.hpp | 1 + 2 files changed, 18 insertions(+), 55 deletions(-) diff --git a/src/graphics/vaomanager.cpp b/src/graphics/vaomanager.cpp index 9cc094934..adaa080ea 100644 --- a/src/graphics/vaomanager.cpp +++ b/src/graphics/vaomanager.cpp @@ -1,6 +1,7 @@ #include "vaomanager.hpp" #include "irr_driver.hpp" #include "stkmesh.hpp" +#include "glwrap.hpp" VAOManager::VAOManager() { @@ -121,61 +122,8 @@ void VAOManager::regenerateVAO(enum VTXTYPE tp) glGenVertexArrays(1, &vao[tp]); glBindVertexArray(vao[tp]); glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]); - switch (tp) - { - case VTXTYPE_COUNT: break; // avoid compiler warning - case VTXTYPE_STANDARD: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - break; - case VTXTYPE_TCOORD: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - // SecondTexcoord - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36); - break; - case VTXTYPE_TANGENT: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - // Tangent - glEnableVertexAttribArray(5); - glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36); - // Bitangent - glEnableVertexAttribArray(6); - glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)48); - break; - } + + VertexUtils::bindVertexArrayAttrib(getVertexType(tp)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]); glBindVertexArray(0); @@ -319,6 +267,20 @@ VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type) } }; +irr::video::E_VERTEX_TYPE VAOManager::getVertexType(enum VTXTYPE tp) +{ + switch (tp) + { + default: + case VTXTYPE_STANDARD: + return video::EVT_STANDARD; + case VTXTYPE_TCOORD: + return video::EVT_2TCOORDS; + case VTXTYPE_TANGENT: + return video::EVT_TANGENTS; + } +} + void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp) { size_t old_vtx_cnt = last_vertex[tp]; diff --git a/src/graphics/vaomanager.hpp b/src/graphics/vaomanager.hpp index 8a555b7b8..af86bcc6e 100644 --- a/src/graphics/vaomanager.hpp +++ b/src/graphics/vaomanager.hpp @@ -154,6 +154,7 @@ class VAOManager : public Singleton void regenerateInstancedVAO(); size_t getVertexPitch(enum VTXTYPE) const; VTXTYPE getVTXTYPE(irr::video::E_VERTEX_TYPE type); + irr::video::E_VERTEX_TYPE getVertexType(enum VTXTYPE tp); void append(irr::scene::IMeshBuffer *, VTXTYPE tp); public: VAOManager(); From 95cf6c5f4a00d4d713ad9bbca940846e0dc7a9cb Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Oct 2014 18:16:50 +0200 Subject: [PATCH 101/112] Put 2d function in their own header --- src/graphics/2dutils.cpp | 338 ++++++++++++++++++++++ src/graphics/2dutils.hpp | 33 +++ src/graphics/glwrap.cpp | 336 --------------------- src/graphics/glwrap.hpp | 20 -- src/graphics/irr_driver.cpp | 1 + src/guiengine/CGUISpriteBank.cpp | 2 +- src/guiengine/engine.cpp | 2 +- src/guiengine/scalable_font.cpp | 2 +- src/guiengine/skin.cpp | 2 +- src/guiengine/widgets/CGUIEditBox.cpp | 3 +- src/states_screens/cutscene_gui.cpp | 3 +- src/states_screens/race_gui.cpp | 2 +- src/states_screens/race_gui_base.cpp | 2 +- src/states_screens/race_gui_overworld.cpp | 2 +- src/states_screens/race_result_gui.cpp | 2 +- src/utils/profiler.cpp | 2 +- 16 files changed, 383 insertions(+), 369 deletions(-) create mode 100644 src/graphics/2dutils.cpp create mode 100644 src/graphics/2dutils.hpp diff --git a/src/graphics/2dutils.cpp b/src/graphics/2dutils.cpp new file mode 100644 index 000000000..0136d003e --- /dev/null +++ b/src/graphics/2dutils.cpp @@ -0,0 +1,338 @@ +#include "2dutils.hpp" +#include "glwrap.hpp" +#include "utils/cpp2011.hpp" + +#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h" + +static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height, + float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, + float tex_width, float tex_height) +{ + unsigned colors[] = { + col[0].getRed(), col[0].getGreen(), col[0].getBlue(), col[0].getAlpha(), + col[1].getRed(), col[1].getGreen(), col[1].getBlue(), col[1].getAlpha(), + col[2].getRed(), col[2].getGreen(), col[2].getBlue(), col[2].getAlpha(), + col[3].getRed(), col[3].getGreen(), col[3].getBlue(), col[3].getAlpha(), + }; + + glBindBuffer(GL_ARRAY_BUFFER, UIShader::ColoredTextureRectShader::getInstance()->colorvbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(unsigned), colors); + + glUseProgram(UIShader::ColoredTextureRectShader::getInstance()->Program); + glBindVertexArray(UIShader::ColoredTextureRectShader::getInstance()->vao); + + UIShader::ColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); + UIShader::ColoredTextureRectShader::getInstance()->setUniforms( + core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), + core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height)); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glGetError(); +} + +static +void drawTexQuad(GLuint texture, float width, float height, +float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, +float tex_width, float tex_height) +{ + glUseProgram(UIShader::TextureRectShader::getInstance()->Program); + glBindVertexArray(SharedObject::UIVAO); + + UIShader::TextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); + UIShader::TextureRectShader::getInstance()->setUniforms( + core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), + core::vector2df(tex_center_pos_x, tex_center_pos_y), + core::vector2df(tex_width, tex_height)); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glGetError(); +} + +static void +getSize(unsigned texture_width, unsigned texture_height, bool textureisRTT, +const core::rect& destRect, +const core::rect& sourceRect, +float &width, float &height, +float ¢er_pos_x, float ¢er_pos_y, +float &tex_width, float &tex_height, +float &tex_center_pos_x, float &tex_center_pos_y +) +{ + core::dimension2d frame_size = + irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + const int screen_w = frame_size.Width; + const int screen_h = frame_size.Height; + center_pos_x = float(destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X); + center_pos_x /= screen_w; + center_pos_x -= 1.; + center_pos_y = float(destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y); + center_pos_y /= screen_h; + center_pos_y = float(1.f - center_pos_y); + width = float(destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X); + width /= screen_w; + height = float(destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y); + height /= screen_h; + + tex_center_pos_x = float(sourceRect.UpperLeftCorner.X + sourceRect.LowerRightCorner.X); + tex_center_pos_x /= texture_width * 2.f; + tex_center_pos_y = float(sourceRect.UpperLeftCorner.Y + sourceRect.LowerRightCorner.Y); + tex_center_pos_y /= texture_height * 2.f; + tex_width = float(sourceRect.LowerRightCorner.X - sourceRect.UpperLeftCorner.X); + tex_width /= texture_width * 2.f; + tex_height = float(sourceRect.LowerRightCorner.Y - sourceRect.UpperLeftCorner.Y); + tex_height /= texture_height * 2.f; + + if (textureisRTT) + tex_height = -tex_height; + + const f32 invW = 1.f / static_cast(texture_width); + const f32 invH = 1.f / static_cast(texture_height); + const core::rect tcoords( + sourceRect.UpperLeftCorner.X * invW, + sourceRect.UpperLeftCorner.Y * invH, + sourceRect.LowerRightCorner.X * invW, + sourceRect.LowerRightCorner.Y *invH); +} + +void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor &colors, bool useAlphaChannelOfTexture) +{ + if (!irr_driver->isGLSL()) { + video::SColor duplicatedArray[4] = { + colors, colors, colors, colors + }; + draw2DImage(texture, destRect, sourceRect, clipRect, duplicatedArray, useAlphaChannelOfTexture); + return; + } + + float width, height, + center_pos_x, center_pos_y, + tex_width, tex_height, + tex_center_pos_x, tex_center_pos_y; + + getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(), + destRect, sourceRect, width, height, center_pos_x, center_pos_y, + tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); + + if (useAlphaChannelOfTexture) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else + { + glDisable(GL_BLEND); + } + if (clipRect) + { + if (!clipRect->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y, + clipRect->getWidth(), clipRect->getHeight()); + } + + glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); + glBindVertexArray(SharedObject::UIVAO); + + UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); + UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( + core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), colors); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + if (clipRect) + glDisable(GL_SCISSOR_TEST); + glUseProgram(0); + + glGetError(); +} + +void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, + const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor &colors, bool useAlphaChannelOfTexture) +{ + if (useAlphaChannelOfTexture) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + float width, height, + center_pos_x, center_pos_y, + tex_width, tex_height, + tex_center_pos_x, tex_center_pos_y; + + getSize((int)texture_w, (int)texture_h, true, + destRect, sourceRect, width, height, center_pos_x, center_pos_y, + tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); + + glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); + glBindVertexArray(SharedObject::UIVAO); + + UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); + UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( + core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), + core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), + colors); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture) +{ + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); + return; + } + + float width, height, + center_pos_x, center_pos_y, + tex_width, tex_height, + tex_center_pos_x, tex_center_pos_y; + + getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(), + destRect, sourceRect, width, height, center_pos_x, center_pos_y, + tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); + + if (useAlphaChannelOfTexture) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else + { + glDisable(GL_BLEND); + } + if (clipRect) + { + if (!clipRect->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y, + clipRect->getWidth(), clipRect->getHeight()); + } + if (colors) + drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y, + tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); + else + drawTexQuad(static_cast(texture)->getOpenGLTextureName(), width, height, center_pos_x, center_pos_y, + tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); + if (clipRect) + glDisable(GL_SCISSOR_TEST); + glUseProgram(0); + + glGetError(); +} + +void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) +{ + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); + return; + } + GLuint tmpvao, tmpvbo, tmpibo; + primitiveCount += 2; + glGenVertexArrays(1, &tmpvao); + glBindVertexArray(tmpvao); + glGenBuffers(1, &tmpvbo); + glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); + glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); + glGenBuffers(1, &tmpibo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); + + VertexUtils::bindVertexArrayAttrib(vType); + + glUseProgram(UIShader::Primitive2DList::getInstance()->Program); + UIShader::Primitive2DList::getInstance()->setUniforms(); + const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); + compressTexture(tex, false); + UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); + glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); + + glDeleteVertexArrays(1, &tmpvao); + glDeleteBuffers(1, &tmpvbo); + glDeleteBuffers(1, &tmpibo); + +} + +void GL32_draw2DRectangle(video::SColor color, const core::rect& position, + const core::rect* clip) +{ + + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip); + return; + } + + core::dimension2d frame_size = + irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + const int screen_w = frame_size.Width; + const int screen_h = frame_size.Height; + float center_pos_x = float(position.UpperLeftCorner.X + position.LowerRightCorner.X); + center_pos_x /= screen_w; + center_pos_x -= 1; + float center_pos_y = float(position.UpperLeftCorner.Y + position.LowerRightCorner.Y); + center_pos_y /= screen_h; + center_pos_y = 1 - center_pos_y; + float width = float(position.LowerRightCorner.X - position.UpperLeftCorner.X); + width /= screen_w; + float height = float(position.LowerRightCorner.Y - position.UpperLeftCorner.Y); + height /= screen_h; + + if (color.getAlpha() < 255) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else + { + glDisable(GL_BLEND); + } + + if (clip) + { + if (!clip->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + glScissor(clip->UpperLeftCorner.X, renderTargetSize.Height - clip->LowerRightCorner.Y, + clip->getWidth(), clip->getHeight()); + } + + glUseProgram(UIShader::ColoredRectShader::getInstance()->Program); + glBindVertexArray(SharedObject::UIVAO); + UIShader::ColoredRectShader::getInstance()->setUniforms(core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), color); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + if (clip) + glDisable(GL_SCISSOR_TEST); + glUseProgram(0); + + glGetError(); +} diff --git a/src/graphics/2dutils.hpp b/src/graphics/2dutils.hpp new file mode 100644 index 000000000..47b0b1ef5 --- /dev/null +++ b/src/graphics/2dutils.hpp @@ -0,0 +1,33 @@ +#ifndef UTILS2D_HPP +#define UTILS2D_HPP + +#include "gl_headers.hpp" +#include +#include +#include +#include +#include +#include +#include + +void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, + const irr::core::rect& destRect, + const irr::core::rect& sourceRect, const irr::core::rect* clipRect, + const irr::video::SColor &colors, bool useAlphaChannelOfTexture); + +void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, + const irr::core::rect& sourceRect, const irr::core::rect* clipRect, + const irr::video::SColor &color, bool useAlphaChannelOfTexture); + +void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, + const irr::core::rect& sourceRect, const irr::core::rect* clipRect, + const irr::video::SColor* const colors, bool useAlphaChannelOfTexture); + +void draw2DVertexPrimitiveList(irr::video::ITexture *t, const void* vertices, + irr::u32 vertexCount, const void* indexList, irr::u32 primitiveCount, + irr::video::E_VERTEX_TYPE vType = irr::video::EVT_STANDARD, irr::scene::E_PRIMITIVE_TYPE pType = irr::scene::EPT_TRIANGLES, irr::video::E_INDEX_TYPE iType = irr::video::EIT_16BIT); + +void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect& position, + const irr::core::rect* clip = 0); + +#endif \ No newline at end of file diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 7d276e441..50911c6c3 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -6,9 +6,6 @@ #include "utils/profiler.hpp" #include "utils/cpp2011.hpp" - -#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h" - #include #include #include @@ -417,339 +414,6 @@ void draw3DLine(const core::vector3df& start, glGetError(); } -static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height, - float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, - float tex_width, float tex_height) -{ - unsigned colors[] = { - col[0].getRed(), col[0].getGreen(), col[0].getBlue(), col[0].getAlpha(), - col[1].getRed(), col[1].getGreen(), col[1].getBlue(), col[1].getAlpha(), - col[2].getRed(), col[2].getGreen(), col[2].getBlue(), col[2].getAlpha(), - col[3].getRed(), col[3].getGreen(), col[3].getBlue(), col[3].getAlpha(), - }; - - glBindBuffer(GL_ARRAY_BUFFER, UIShader::ColoredTextureRectShader::getInstance()->colorvbo); - glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(unsigned), colors); - - glUseProgram(UIShader::ColoredTextureRectShader::getInstance()->Program); - glBindVertexArray(UIShader::ColoredTextureRectShader::getInstance()->vao); - - UIShader::ColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); - UIShader::ColoredTextureRectShader::getInstance()->setUniforms( - core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), - core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height)); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glGetError(); -} - -static -void drawTexQuad(GLuint texture, float width, float height, - float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, - float tex_width, float tex_height) -{ - glUseProgram(UIShader::TextureRectShader::getInstance()->Program); - glBindVertexArray(SharedObject::UIVAO); - - UIShader::TextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); - UIShader::TextureRectShader::getInstance()->setUniforms( - core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), - core::vector2df(tex_center_pos_x, tex_center_pos_y), - core::vector2df(tex_width, tex_height)); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glGetError(); -} - -static void -getSize(unsigned texture_width, unsigned texture_height, bool textureisRTT, - const core::rect& destRect, - const core::rect& sourceRect, - float &width, float &height, - float ¢er_pos_x, float ¢er_pos_y, - float &tex_width, float &tex_height, - float &tex_center_pos_x, float &tex_center_pos_y - ) -{ - core::dimension2d frame_size = - irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - const int screen_w = frame_size.Width; - const int screen_h = frame_size.Height; - center_pos_x = float(destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X); - center_pos_x /= screen_w; - center_pos_x -= 1.; - center_pos_y = float(destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y); - center_pos_y /= screen_h; - center_pos_y = float(1.f - center_pos_y); - width = float(destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X); - width /= screen_w; - height = float(destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y); - height /= screen_h; - - tex_center_pos_x = float(sourceRect.UpperLeftCorner.X + sourceRect.LowerRightCorner.X); - tex_center_pos_x /= texture_width * 2.f; - tex_center_pos_y = float(sourceRect.UpperLeftCorner.Y + sourceRect.LowerRightCorner.Y); - tex_center_pos_y /= texture_height * 2.f; - tex_width = float(sourceRect.LowerRightCorner.X - sourceRect.UpperLeftCorner.X); - tex_width /= texture_width * 2.f; - tex_height = float(sourceRect.LowerRightCorner.Y - sourceRect.UpperLeftCorner.Y); - tex_height /= texture_height * 2.f; - - if (textureisRTT) - tex_height = -tex_height; - - const f32 invW = 1.f / static_cast(texture_width); - const f32 invH = 1.f / static_cast(texture_height); - const core::rect tcoords( - sourceRect.UpperLeftCorner.X * invW, - sourceRect.UpperLeftCorner.Y * invH, - sourceRect.LowerRightCorner.X * invW, - sourceRect.LowerRightCorner.Y *invH); -} - -void draw2DImage(const video::ITexture* texture, const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, - const video::SColor &colors, bool useAlphaChannelOfTexture) -{ - if (!irr_driver->isGLSL()) { - video::SColor duplicatedArray[4] = { - colors, colors, colors, colors - }; - draw2DImage(texture, destRect, sourceRect, clipRect, duplicatedArray, useAlphaChannelOfTexture); - return; - } - - float width, height, - center_pos_x, center_pos_y, - tex_width, tex_height, - tex_center_pos_x, tex_center_pos_y; - - getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(), - destRect, sourceRect, width, height, center_pos_x, center_pos_y, - tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); - - if (useAlphaChannelOfTexture) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else - { - glDisable(GL_BLEND); - } - if (clipRect) - { - if (!clipRect->isValid()) - return; - - glEnable(GL_SCISSOR_TEST); - const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y, - clipRect->getWidth(), clipRect->getHeight()); - } - - glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); - glBindVertexArray(SharedObject::UIVAO); - - UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(static_cast(texture)->getOpenGLTextureName())); - UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( - core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), colors); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - if (clipRect) - glDisable(GL_SCISSOR_TEST); - glUseProgram(0); - - glGetError(); -} - -void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, - const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, - const video::SColor &colors, bool useAlphaChannelOfTexture) -{ - if (useAlphaChannelOfTexture) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - float width, height, - center_pos_x, center_pos_y, - tex_width, tex_height, - tex_center_pos_x, tex_center_pos_y; - - getSize((int)texture_w, (int)texture_h, true, - destRect, sourceRect, width, height, center_pos_x, center_pos_y, - tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); - - glUseProgram(UIShader::UniformColoredTextureRectShader::getInstance()->Program); - glBindVertexArray(SharedObject::UIVAO); - - UIShader::UniformColoredTextureRectShader::getInstance()->SetTextureUnits(createVector(texture)); - UIShader::UniformColoredTextureRectShader::getInstance()->setUniforms( - core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), - core::vector2df(tex_center_pos_x, tex_center_pos_y), core::vector2df(tex_width, tex_height), - colors); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void draw2DImage(const video::ITexture* texture, const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, - const video::SColor* const colors, bool useAlphaChannelOfTexture) -{ - if (!irr_driver->isGLSL()) - { - irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); - return; - } - - float width, height, - center_pos_x, center_pos_y, - tex_width, tex_height, - tex_center_pos_x, tex_center_pos_y; - - getSize(texture->getOriginalSize().Width, texture->getOriginalSize().Height, texture->isRenderTarget(), - destRect, sourceRect, width, height, center_pos_x, center_pos_y, - tex_width, tex_height, tex_center_pos_x, tex_center_pos_y); - - if (useAlphaChannelOfTexture) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else - { - glDisable(GL_BLEND); - } - if (clipRect) - { - if (!clipRect->isValid()) - return; - - glEnable(GL_SCISSOR_TEST); - const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y, - clipRect->getWidth(), clipRect->getHeight()); - } - if (colors) - drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y, - tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); - else - drawTexQuad(static_cast(texture)->getOpenGLTextureName(), width, height, center_pos_x, center_pos_y, - tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); - if (clipRect) - glDisable(GL_SCISSOR_TEST); - glUseProgram(0); - - glGetError(); -} - -void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) -{ - if (!irr_driver->isGLSL()) - { - irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); - return; - } - GLuint tmpvao, tmpvbo, tmpibo; - primitiveCount += 2; - glGenVertexArrays(1, &tmpvao); - glBindVertexArray(tmpvao); - glGenBuffers(1, &tmpvbo); - glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); - glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); - glGenBuffers(1, &tmpibo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); - - VertexUtils::bindVertexArrayAttrib(vType); - - glUseProgram(UIShader::Primitive2DList::getInstance()->Program); - UIShader::Primitive2DList::getInstance()->setUniforms(); - const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); - compressTexture(tex, false); - UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); - glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); - - glDeleteVertexArrays(1, &tmpvao); - glDeleteBuffers(1, &tmpvbo); - glDeleteBuffers(1, &tmpibo); - -} - -void GL32_draw2DRectangle(video::SColor color, const core::rect& position, - const core::rect* clip) -{ - - if (!irr_driver->isGLSL()) - { - irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip); - return; - } - - core::dimension2d frame_size = - irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - const int screen_w = frame_size.Width; - const int screen_h = frame_size.Height; - float center_pos_x = float(position.UpperLeftCorner.X + position.LowerRightCorner.X); - center_pos_x /= screen_w; - center_pos_x -= 1; - float center_pos_y = float(position.UpperLeftCorner.Y + position.LowerRightCorner.Y); - center_pos_y /= screen_h; - center_pos_y = 1 - center_pos_y; - float width = float(position.LowerRightCorner.X - position.UpperLeftCorner.X); - width /= screen_w; - float height = float(position.LowerRightCorner.Y - position.UpperLeftCorner.Y); - height /= screen_h; - - if (color.getAlpha() < 255) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else - { - glDisable(GL_BLEND); - } - - if (clip) - { - if (!clip->isValid()) - return; - - glEnable(GL_SCISSOR_TEST); - const core::dimension2d& renderTargetSize = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); - glScissor(clip->UpperLeftCorner.X, renderTargetSize.Height - clip->LowerRightCorner.Y, - clip->getWidth(), clip->getHeight()); - } - - glUseProgram(UIShader::ColoredRectShader::getInstance()->Program); - glBindVertexArray(SharedObject::UIVAO); - UIShader::ColoredRectShader::getInstance()->setUniforms(core::vector2df(center_pos_x, center_pos_y), core::vector2df(width, height), color); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - if (clip) - glDisable(GL_SCISSOR_TEST); - glUseProgram(0); - - glGetError(); -} - bool hasGLExtension(const char* extension) { if (glGetStringi != NULL) diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index f1c17d53e..f63d59bc3 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -202,26 +202,6 @@ public: void draw3DLine(const core::vector3df& start, const core::vector3df& end, irr::video::SColor color); -void draw2DImageFromRTT(GLuint texture, size_t texture_w, size_t texture_h, - const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, - const video::SColor &colors, bool useAlphaChannelOfTexture); - -void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, - const irr::core::rect& sourceRect, const irr::core::rect* clipRect, - const irr::video::SColor &color, bool useAlphaChannelOfTexture); - -void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, - const irr::core::rect& sourceRect, const irr::core::rect* clipRect, - const irr::video::SColor* const colors, bool useAlphaChannelOfTexture); - -void draw2DVertexPrimitiveList(video::ITexture *t, const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - video::E_VERTEX_TYPE vType = video::EVT_STANDARD, scene::E_PRIMITIVE_TYPE pType = scene::EPT_TRIANGLES, video::E_INDEX_TYPE iType = video::EIT_16BIT); - -void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect& position, - const irr::core::rect* clip = 0); - bool hasGLExtension(const char* extension); const std::string getGLExtensions(); void getGLLimits(HardwareStats::Json *json); diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 8238b8c3a..594b899bb 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -22,6 +22,7 @@ #include "graphics/callbacks.hpp" #include "graphics/camera.hpp" #include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "graphics/hardware_skinning.hpp" #include "graphics/lens_flare.hpp" #include "graphics/light.hpp" diff --git a/src/guiengine/CGUISpriteBank.cpp b/src/guiengine/CGUISpriteBank.cpp index 6b0970fa6..925a2e1c9 100644 --- a/src/guiengine/CGUISpriteBank.cpp +++ b/src/guiengine/CGUISpriteBank.cpp @@ -9,7 +9,7 @@ #include "IVideoDriver.h" #include "ITexture.h" #include -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" namespace irr { diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index c31366b03..5ea597e62 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -657,7 +657,7 @@ namespace GUIEngine #include "guiengine/engine.hpp" #include "config/user_config.hpp" -#include "graphics/irr_driver.hpp" +#include "graphics/2dutils.hpp" #include "input/input_manager.hpp" #include "io/file_manager.hpp" #include "guiengine/event_handler.hpp" diff --git a/src/guiengine/scalable_font.cpp b/src/guiengine/scalable_font.cpp index 41484cd62..c9ad661e7 100644 --- a/src/guiengine/scalable_font.cpp +++ b/src/guiengine/scalable_font.cpp @@ -13,7 +13,7 @@ #include "guiengine/engine.hpp" #include "io/file_manager.hpp" #include "utils/translation.hpp" -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" namespace irr { diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index 278817772..40e056c39 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -23,7 +23,7 @@ #include #include "config/user_config.hpp" -#include "graphics/irr_driver.hpp" +#include "graphics/2dutils.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" #include "guiengine/scalable_font.hpp" diff --git a/src/guiengine/widgets/CGUIEditBox.cpp b/src/guiengine/widgets/CGUIEditBox.cpp index f2688b3c2..114c63854 100644 --- a/src/guiengine/widgets/CGUIEditBox.cpp +++ b/src/guiengine/widgets/CGUIEditBox.cpp @@ -12,8 +12,7 @@ //#include "os.h" #include "Keycodes.h" -#include "graphics/glwrap.hpp" -#include "graphics/irr_driver.hpp" +#include "graphics/2dutils.hpp" #include "utils/translation.hpp" #include "utils/time.hpp" diff --git a/src/states_screens/cutscene_gui.cpp b/src/states_screens/cutscene_gui.cpp index ac9c7b681..4d4399e5e 100644 --- a/src/states_screens/cutscene_gui.cpp +++ b/src/states_screens/cutscene_gui.cpp @@ -19,8 +19,7 @@ #include "config/user_config.hpp" #include "guiengine/engine.hpp" #include "guiengine/scalable_font.hpp" -#include "graphics/irr_driver.hpp" -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "states_screens/cutscene_gui.hpp" // ----------------------------------------------------------------------------- diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 5f903fb77..de3cb84d7 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -26,8 +26,8 @@ using namespace irr; #include "challenges/unlock_manager.hpp" #include "config/user_config.hpp" #include "graphics/camera.hpp" +#include "graphics/2dutils.hpp" #include "graphics/glwrap.hpp" -#include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" diff --git a/src/states_screens/race_gui_base.cpp b/src/states_screens/race_gui_base.cpp index 185c6ed5e..f68114dad 100644 --- a/src/states_screens/race_gui_base.cpp +++ b/src/states_screens/race_gui_base.cpp @@ -23,7 +23,7 @@ #include "audio/music_manager.hpp" #include "config/user_config.hpp" #include "graphics/camera.hpp" -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "graphics/irr_driver.hpp" #include "graphics/material.hpp" #include "graphics/material_manager.hpp" diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index 57aa620c0..78ccbd861 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -24,8 +24,8 @@ #include "config/player_manager.hpp" #include "config/user_config.hpp" #include "graphics/camera.hpp" +#include "graphics/2dutils.hpp" #include "graphics/glwrap.hpp" -#include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 86a25afd3..c618274c3 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -24,7 +24,7 @@ #include "challenges/unlock_manager.hpp" #include "config/player_manager.hpp" #include "config/user_config.hpp" -#include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "graphics/material.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" diff --git a/src/utils/profiler.cpp b/src/utils/profiler.cpp index 48f91e2c7..4578d97ea 100644 --- a/src/utils/profiler.cpp +++ b/src/utils/profiler.cpp @@ -16,8 +16,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "profiler.hpp" -#include "graphics/irr_driver.hpp" #include "graphics/glwrap.hpp" +#include "graphics/2dutils.hpp" #include "guiengine/event_handler.hpp" #include "guiengine/engine.hpp" #include "guiengine/scalable_font.hpp" From 80c7c5e49bf6cf8902d9288564e5cd045142dd97 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Oct 2014 18:29:37 +0200 Subject: [PATCH 102/112] Remove unused functions --- src/graphics/glwrap.cpp | 16 ---------------- src/graphics/glwrap.hpp | 3 --- 2 files changed, 19 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 50911c6c3..f4a9a0505 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -256,22 +256,6 @@ GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsi return Program; } -void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF) -{ - glActiveTexture(GL_TEXTURE0 + TextureUnit); - glBindTexture(GL_TEXTURE_2D, TextureId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - int aniso = UserConfigParams::m_anisotropic; - if (aniso == 0) aniso = 1; - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, allowAF ? (float)aniso : 1.0f); - - glGetError(); -} - ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t) { if (!UserConfigParams::m_profiler_enabled) return; diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index f63d59bc3..bc6d4adc3 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -17,7 +17,6 @@ namespace HardwareStats void initGL(); GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); video::ITexture* getUnicolorTexture(const video::SColor &c); -void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF = false); GLuint LoadShader(const char * file, unsigned type); template @@ -194,8 +193,6 @@ public: } }; -// core::rect needs these includes -#include #include "utils/vec3.hpp" #include "texturemanager.hpp" From e23aba65f4020f0715cf86b58f728bd0e284b099 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Oct 2014 23:53:16 +0200 Subject: [PATCH 103/112] Move shader load code to shader.cpp instead of glwrap.hpp --- src/graphics/glwrap.cpp | 137 --------------------------------- src/graphics/glwrap.hpp | 70 ----------------- src/graphics/shaders.cpp | 139 ++++++++++++++++++++++++++++++++++ src/graphics/shaders_util.hpp | 71 +++++++++++++++++ 4 files changed, 210 insertions(+), 207 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index f4a9a0505..e13454bef 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -119,143 +119,6 @@ void initGL() #endif } -static std::string LoadHeader() -{ - std::string result; - std::ifstream Stream(file_manager->getAsset("shaders/header.txt").c_str(), std::ios::in); - - if (Stream.is_open()) - { - std::string Line = ""; - while (getline(Stream, Line)) - result += "\n" + Line; - Stream.close(); - } - - return result; -} - -// Mostly from shader tutorial -GLuint LoadShader(const char * file, unsigned type) -{ - GLuint Id = glCreateShader(type); - char versionString[20]; - sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion()); - std::string Code = versionString; - if (irr_driver->hasVSLayerExtension()) - Code += "#extension GL_AMD_vertex_shader_layer : enable\n"; - if (UserConfigParams::m_azdo) - Code += "#extension GL_ARB_bindless_texture : enable\n"; - else - { - Code += "#extension GL_ARB_bindless_texture : disable\n"; - Code += "#undef GL_ARB_bindless_texture\n"; - } - std::ifstream Stream(file, std::ios::in); - Code += "//" + std::string(file) + "\n"; - if (irr_driver->needUBOWorkaround()) - Code += "#define UBO_DISABLED\n"; - if (irr_driver->hasVSLayerExtension()) - Code += "#define VSLayer\n"; - if (irr_driver->needsRGBBindlessWorkaround()) - Code += "#define SRGBBindlessFix\n"; - Code += LoadHeader(); - if (Stream.is_open()) - { - std::string Line = ""; - while (getline(Stream, Line)) - Code += "\n" + Line; - Stream.close(); - } - GLint Result = GL_FALSE; - int InfoLogLength; - Log::info("GLWrap", "Compiling shader : %s", file); - char const * SourcePointer = Code.c_str(); - int length = (int)strlen(SourcePointer); - glShaderSource(Id, 1, &SourcePointer, &length); - glCompileShader(Id); - - glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); - if (Result == GL_FALSE) - { - Log::error("GLWrap", "Error in shader %s", file); - glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); - if(InfoLogLength<0) - InfoLogLength = 1024; - char *ErrorMessage = new char[InfoLogLength]; - ErrorMessage[0]=0; - glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); - Log::error("GLWrap", ErrorMessage); - delete[] ErrorMessage; - } - - glGetError(); - - return Id; -} - -void setAttribute(AttributeType Tp, GLuint ProgramID) -{ - switch (Tp) - { - case OBJECT: - glBindAttribLocation(ProgramID, 0, "Position"); - glBindAttribLocation(ProgramID, 1, "Normal"); - glBindAttribLocation(ProgramID, 2, "Color"); - glBindAttribLocation(ProgramID, 3, "Texcoord"); - glBindAttribLocation(ProgramID, 4, "SecondTexcoord"); - glBindAttribLocation(ProgramID, 5, "Tangent"); - glBindAttribLocation(ProgramID, 6, "Bitangent"); - glBindAttribLocation(ProgramID, 7, "Origin"); - glBindAttribLocation(ProgramID, 8, "Orientation"); - glBindAttribLocation(ProgramID, 9, "Scale"); - break; - case PARTICLES_SIM: - glBindAttribLocation(ProgramID, 0, "particle_position"); - glBindAttribLocation(ProgramID, 1, "lifetime"); - glBindAttribLocation(ProgramID, 2, "particle_velocity"); - glBindAttribLocation(ProgramID, 3, "size"); - glBindAttribLocation(ProgramID, 4, "particle_position_initial"); - glBindAttribLocation(ProgramID, 5, "lifetime_initial"); - glBindAttribLocation(ProgramID, 6, "particle_velocity_initial"); - glBindAttribLocation(ProgramID, 7, "size_initial"); - break; - case PARTICLES_RENDERING: - glBindAttribLocation(ProgramID, 1, "lifetime"); - glBindAttribLocation(ProgramID, 2, "size"); - glBindAttribLocation(ProgramID, 4, "quadcorner"); - glBindAttribLocation(ProgramID, 5, "rotationvec"); - glBindAttribLocation(ProgramID, 6, "anglespeed"); - break; - } -} - -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) -{ - GLuint Program = glCreateProgram(); - loadAndAttach(Program, GL_VERTEX_SHADER, vertex_file_path); - if (irr_driver->getGLSLVersion() < 330) - setAttribute(PARTICLES_SIM, Program); - glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); - glLinkProgram(Program); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(Program, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) - { - glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); - Log::error("GLWrap", ErrorMessage); - delete[] ErrorMessage; - } - - glGetError(); - - return Program; -} - ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t) { if (!UserConfigParams::m_profiler_enabled) return; diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index bc6d4adc3..631fc4cf2 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -15,77 +15,7 @@ namespace HardwareStats } void initGL(); -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); video::ITexture* getUnicolorTexture(const video::SColor &c); -GLuint LoadShader(const char * file, unsigned type); - -template -void loadAndAttach(GLint ProgramID) -{ - return; -} - -template -void loadAndAttach(GLint ProgramID, GLint ShaderType, const char *filepath, Types ... args) -{ - GLint ShaderID = LoadShader(filepath, ShaderType); - glAttachShader(ProgramID, ShaderID); - glDeleteShader(ShaderID); - loadAndAttach(ProgramID, args...); -} - -template -void printFileList() -{ - return; -} - -template -void printFileList(GLint ShaderType, const char *filepath, Types ... args) -{ - Log::error("GLWrapp", filepath); - printFileList(args...); -} - -enum AttributeType -{ - OBJECT, - PARTICLES_SIM, - PARTICLES_RENDERING, -}; - -void setAttribute(AttributeType Tp, GLuint ProgramID); - -template -GLint LoadProgram(AttributeType Tp, Types ... args) -{ - GLint ProgramID = glCreateProgram(); - loadAndAttach(ProgramID, args...); - if (irr_driver->getGLSLVersion() < 330) - setAttribute(Tp, ProgramID); - glLinkProgram(ProgramID); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - Log::error("GLWrapp", "Error when linking these shaders :"); - printFileList(args...); - glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); - Log::error("GLWrapp", ErrorMessage); - delete[] ErrorMessage; - } - - GLenum glErr = glGetError(); - if (glErr != GL_NO_ERROR) - { - Log::warn("IrrDriver", "GLWrap : OpenGL error %i\n", glErr); - } - - return ProgramID; -} class GPUTimer; diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 97e6b6020..6566c25ae 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -123,6 +123,145 @@ Shaders::Shaders() loadShaders(); } +// Shader loading related hook + +static std::string LoadHeader() +{ + std::string result; + std::ifstream Stream(file_manager->getAsset("shaders/header.txt").c_str(), std::ios::in); + + if (Stream.is_open()) + { + std::string Line = ""; + while (getline(Stream, Line)) + result += "\n" + Line; + Stream.close(); + } + + return result; +} + +// Mostly from shader tutorial +GLuint LoadShader(const char * file, unsigned type) +{ + GLuint Id = glCreateShader(type); + char versionString[20]; + sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion()); + std::string Code = versionString; + if (irr_driver->hasVSLayerExtension()) + Code += "#extension GL_AMD_vertex_shader_layer : enable\n"; + if (UserConfigParams::m_azdo) + Code += "#extension GL_ARB_bindless_texture : enable\n"; + else + { + Code += "#extension GL_ARB_bindless_texture : disable\n"; + Code += "#undef GL_ARB_bindless_texture\n"; + } + std::ifstream Stream(file, std::ios::in); + Code += "//" + std::string(file) + "\n"; + if (irr_driver->needUBOWorkaround()) + Code += "#define UBO_DISABLED\n"; + if (irr_driver->hasVSLayerExtension()) + Code += "#define VSLayer\n"; + if (irr_driver->needsRGBBindlessWorkaround()) + Code += "#define SRGBBindlessFix\n"; + Code += LoadHeader(); + if (Stream.is_open()) + { + std::string Line = ""; + while (getline(Stream, Line)) + Code += "\n" + Line; + Stream.close(); + } + GLint Result = GL_FALSE; + int InfoLogLength; + Log::info("GLWrap", "Compiling shader : %s", file); + char const * SourcePointer = Code.c_str(); + int length = (int)strlen(SourcePointer); + glShaderSource(Id, 1, &SourcePointer, &length); + glCompileShader(Id); + + glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); + if (Result == GL_FALSE) + { + Log::error("GLWrap", "Error in shader %s", file); + glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); + if (InfoLogLength<0) + InfoLogLength = 1024; + char *ErrorMessage = new char[InfoLogLength]; + ErrorMessage[0] = 0; + glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); + Log::error("GLWrap", ErrorMessage); + delete[] ErrorMessage; + } + + glGetError(); + + return Id; +} + +void setAttribute(AttributeType Tp, GLuint ProgramID) +{ + switch (Tp) + { + case OBJECT: + glBindAttribLocation(ProgramID, 0, "Position"); + glBindAttribLocation(ProgramID, 1, "Normal"); + glBindAttribLocation(ProgramID, 2, "Color"); + glBindAttribLocation(ProgramID, 3, "Texcoord"); + glBindAttribLocation(ProgramID, 4, "SecondTexcoord"); + glBindAttribLocation(ProgramID, 5, "Tangent"); + glBindAttribLocation(ProgramID, 6, "Bitangent"); + glBindAttribLocation(ProgramID, 7, "Origin"); + glBindAttribLocation(ProgramID, 8, "Orientation"); + glBindAttribLocation(ProgramID, 9, "Scale"); + break; + case PARTICLES_SIM: + glBindAttribLocation(ProgramID, 0, "particle_position"); + glBindAttribLocation(ProgramID, 1, "lifetime"); + glBindAttribLocation(ProgramID, 2, "particle_velocity"); + glBindAttribLocation(ProgramID, 3, "size"); + glBindAttribLocation(ProgramID, 4, "particle_position_initial"); + glBindAttribLocation(ProgramID, 5, "lifetime_initial"); + glBindAttribLocation(ProgramID, 6, "particle_velocity_initial"); + glBindAttribLocation(ProgramID, 7, "size_initial"); + break; + case PARTICLES_RENDERING: + glBindAttribLocation(ProgramID, 1, "lifetime"); + glBindAttribLocation(ProgramID, 2, "size"); + glBindAttribLocation(ProgramID, 4, "quadcorner"); + glBindAttribLocation(ProgramID, 5, "rotationvec"); + glBindAttribLocation(ProgramID, 6, "anglespeed"); + break; + } +} + +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) +{ + GLuint Program = glCreateProgram(); + loadAndAttach(Program, GL_VERTEX_SHADER, vertex_file_path); + if (irr_driver->getGLSLVersion() < 330) + setAttribute(PARTICLES_SIM, Program); + glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); + glLinkProgram(Program); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(Program, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) + { + glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); + Log::error("GLWrap", ErrorMessage); + delete[] ErrorMessage; + } + + glGetError(); + + return Program; +} + GLuint quad_vbo, tri_vbo; GLuint SharedObject::FullScreenQuadVAO = 0; diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 6b1563bed..9631a2cd2 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -12,6 +12,77 @@ bool needsUBO(); unsigned getGLSLVersion(); +GLuint LoadShader(const char * file, unsigned type); +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); + +template +void loadAndAttach(GLint ProgramID) +{ + return; +} + +template +void loadAndAttach(GLint ProgramID, GLint ShaderType, const char *filepath, Types ... args) +{ + GLint ShaderID = LoadShader(filepath, ShaderType); + glAttachShader(ProgramID, ShaderID); + glDeleteShader(ShaderID); + loadAndAttach(ProgramID, args...); +} + +template +void printFileList() +{ + return; +} + +template +void printFileList(GLint ShaderType, const char *filepath, Types ... args) +{ + Log::error("GLWrapp", filepath); + printFileList(args...); +} + +enum AttributeType +{ + OBJECT, + PARTICLES_SIM, + PARTICLES_RENDERING, +}; + +void setAttribute(AttributeType Tp, GLuint ProgramID); + +template +GLint LoadProgram(AttributeType Tp, Types ... args) +{ + GLint ProgramID = glCreateProgram(); + loadAndAttach(ProgramID, args...); + if (irr_driver->getGLSLVersion() < 330) + setAttribute(Tp, ProgramID); + glLinkProgram(ProgramID); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + Log::error("GLWrapp", "Error when linking these shaders :"); + printFileList(args...); + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); + Log::error("GLWrapp", ErrorMessage); + delete[] ErrorMessage; + } + + GLenum glErr = glGetError(); + if (glErr != GL_NO_ERROR) + { + Log::warn("IrrDriver", "GLWrap : OpenGL error %i\n", glErr); + } + + return ProgramID; +} + struct UniformHelper { template From 9b46cdc981b04c7ac39622fc1e031c73106ea3fd Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 18 Oct 2014 19:11:24 -0400 Subject: [PATCH 104/112] Refactor library nodes to be proper TrackObjects, allows animating them with curves --- src/tracks/model_definition_loader.cpp | 14 ++++ src/tracks/model_definition_loader.hpp | 22 ++++++- src/tracks/track.cpp | 83 ++---------------------- src/tracks/track.hpp | 6 +- src/tracks/track_object.cpp | 4 ++ src/tracks/track_object_presentation.cpp | 71 ++++++++++++++++++++ src/tracks/track_object_presentation.hpp | 12 ++++ 7 files changed, 128 insertions(+), 84 deletions(-) diff --git a/src/tracks/model_definition_loader.cpp b/src/tracks/model_definition_loader.cpp index e8444e98a..b4984448e 100644 --- a/src/tracks/model_definition_loader.cpp +++ b/src/tracks/model_definition_loader.cpp @@ -122,3 +122,17 @@ scene::IMesh* ModelDefinitionLoader::getFirstMeshFor(const std::string& name) { return irr_driver->getMesh(m_lod_groups[name][0].m_model_file); } + +// ---------------------------------------------------------------------------- + +void ModelDefinitionLoader::cleanLibraryNodesAfterLoad() +{ + for (std::map::iterator it = m_library_nodes.begin(); + it != m_library_nodes.end(); it++) + { + delete it->second; + + file_manager->popTextureSearchPath(); + file_manager->popModelSearchPath(); + } +} \ No newline at end of file diff --git a/src/tracks/model_definition_loader.hpp b/src/tracks/model_definition_loader.hpp index b3bf75694..5cfb3a7aa 100644 --- a/src/tracks/model_definition_loader.hpp +++ b/src/tracks/model_definition_loader.hpp @@ -68,12 +68,13 @@ struct ModelDefinition } }; -/** Utility class to load level-of-detail nodes and instaincing nodes +/** Utility class to load level-of-detail nodes and library nodes * \ingroup tracks */ class ModelDefinitionLoader { private: + std::map m_library_nodes; std::map< std::string, std::vector< ModelDefinition > > m_lod_groups; std::map< std::string, STKInstancedSceneNode* > m_instancing_nodes; Track* m_track; @@ -86,8 +87,25 @@ public: void clear(); - scene::IMesh* getFirstMeshFor(const std::string& name); + + std::map& getLibraryNodes() + { + return m_library_nodes; + } + + void cleanLibraryNodesAfterLoad(); + + bool containsLibraryNode(const std::string& name) const + { + return m_library_nodes.find(name) != m_library_nodes.end(); + } + + void addToLibrary(const std::string& name, XMLNode* xml) + { + assert(xml != NULL); + m_library_nodes[name] = xml; + } }; // ModelDefinitionLoader #endif // HEADER_LOD_NODE_LOADER_HPP diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 1319d4084..fe41c4c46 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1738,18 +1738,9 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) } } - std::map library_nodes; - loadObjects(root, path, model_def_loader, true, NULL, library_nodes); + loadObjects(root, path, model_def_loader, true, NULL); - // Cleanup library nodes - for (std::map::iterator it = library_nodes.begin(); - it != library_nodes.end(); it++) - { - delete it->second; - - file_manager->popTextureSearchPath(); - file_manager->popModelSearchPath(); - } + model_def_loader.cleanLibraryNodesAfterLoad(); // Init all track objects m_track_object_manager->init(); @@ -1914,8 +1905,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) //----------------------------------------------------------------------------- void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& model_def_loader, - bool create_lod_definitions, scene::ISceneNode* parent, - std::map& library_nodes) + bool create_lod_definitions, scene::ISceneNode* parent) { unsigned int start_position_counter = 0; @@ -1927,75 +1917,10 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin // The track object was already converted before the loop, and the // default start was already used, too - so ignore those. if (name == "track" || name == "default-start") continue; - if (name == "object") + if (name == "object" || name == "library") { m_track_object_manager->add(*node, parent, model_def_loader); } - else if (name == "library") - { - std::string name; - node->get("name", &name); - - core::vector3df xyz; - node->get("xyz", &xyz); - - core::vector3df hpr; - node->get("hpr", &hpr); - - core::vector3df scale; - node->get("scale", &scale); - - XMLNode* libroot; - std::string lib_path = - file_manager->getAsset(FileManager::LIBRARY, name)+"/"; - bool create_lod_definitions = true; - - if (library_nodes.find(name) == library_nodes.end()) - { - std::string lib_node_path = lib_path+"node.xml"; - libroot = file_manager->createXMLTree(lib_node_path); - if (libroot == NULL) - { - Log::error("Track", "Cannot find library '%s'", lib_node_path.c_str()); - continue; - } - - file_manager->pushTextureSearchPath(lib_path + "/"); - file_manager->pushModelSearchPath (lib_path); - material_manager->pushTempMaterial(lib_path + "/materials.xml"); - library_nodes[name] = libroot; - - // Load LOD groups - const XMLNode *lod_xml_node = libroot->getNode("lod"); - if (lod_xml_node != NULL) - { - for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++) - { - const XMLNode* lod_group_xml = lod_xml_node->getNode(i); - for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) - { - model_def_loader.addModelDefinition(lod_group_xml->getNode(j)); - } - } - } - } - else - { - libroot = library_nodes[name]; - create_lod_definitions = false; // LOD definitions are already created, don't create them again - } - - scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode(); -#ifdef DEBUG - parent->setName(("libnode_" + name).c_str()); -#endif - parent->setPosition(xyz); - parent->setRotation(hpr); - parent->setScale(scale); - parent->updateAbsolutePosition(); - loadObjects(libroot, lib_path, model_def_loader, create_lod_definitions, parent, library_nodes); - //m_all_nodes.push_back(parent); - } else if (name == "water") { createWater(*node); diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index d5eadd80b..10f2ff18e 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -412,9 +412,6 @@ private: std::vector& m_music ); void loadCurves(const XMLNode &node); void handleSky(const XMLNode &root, const std::string &filename); - void loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& lod_loader, - bool create_lod_definitions, scene::ISceneNode* parent, - std::map& library_nodes); public: @@ -472,6 +469,9 @@ public: /** Returns true if this track has easter eggs. */ bool hasEasterEggs() const { return m_has_easter_eggs; } // ------------------------------------------------------------------------ + void loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& lod_loader, + bool create_lod_definitions, scene::ISceneNode* parent); + // ------------------------------------------------------------------------ bool isSoccer () const { return m_is_soccer; } // ------------------------------------------------------------------------ void loadTrackModel (World* parent, diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 12ecc3679..369628bee 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -132,6 +132,10 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, m_type = "light"; m_presentation = new TrackObjectPresentationLight(xml_node, parent); } + else if (xml_node.getName() == "library") + { + m_presentation = new TrackObjectPresentationLibraryNode(xml_node, model_def_loader); + } else if (type == "sfx-emitter") { // FIXME: at this time sound emitters are just disabled in multiplayer diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index f8367f233..083ab3621 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -148,6 +148,77 @@ TrackObjectPresentationEmpty::~TrackObjectPresentationEmpty() // ---------------------------------------------------------------------------- +TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode( + const XMLNode& xml_node, + ModelDefinitionLoader& model_def_loader) : +TrackObjectPresentationSceneNode(xml_node) +{ + std::string name; + xml_node.get("name", &name); + + m_node = irr_driver->getSceneManager()->addEmptySceneNode(); +#ifdef DEBUG + m_node->setName(("libnode_" + name).c_str()); +#endif + + XMLNode* libroot; + std::string lib_path = + file_manager->getAsset(FileManager::LIBRARY, name) + "/"; + bool create_lod_definitions = true; + + if (!model_def_loader.containsLibraryNode(name)) + { + std::string lib_node_path = lib_path + "node.xml"; + libroot = file_manager->createXMLTree(lib_node_path); + if (libroot == NULL) + { + Log::error("TrackObjectPresentationLibraryNode", "Cannot find library '%s'", lib_node_path.c_str()); + return; + } + + file_manager->pushTextureSearchPath(lib_path + "/"); + file_manager->pushModelSearchPath(lib_path); + material_manager->pushTempMaterial(lib_path + "/materials.xml"); + model_def_loader.addToLibrary(name, libroot); + + // Load LOD groups + const XMLNode *lod_xml_node = libroot->getNode("lod"); + if (lod_xml_node != NULL) + { + for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++) + { + const XMLNode* lod_group_xml = lod_xml_node->getNode(i); + for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) + { + model_def_loader.addModelDefinition(lod_group_xml->getNode(j)); + } + } + } + } + else + { + libroot = model_def_loader.getLibraryNodes()[name]; + assert(libroot != NULL); + create_lod_definitions = false; // LOD definitions are already created, don't create them again + } + + m_node->setPosition(m_init_xyz); + m_node->setRotation(m_init_hpr); + m_node->setScale(m_init_scale); + m_node->updateAbsolutePosition(); + + assert(libroot != NULL); + World::getWorld()->getTrack()->loadObjects(libroot, lib_path, model_def_loader, + create_lod_definitions, m_node); +} + +TrackObjectPresentationLibraryNode::~TrackObjectPresentationLibraryNode() +{ + irr_driver->removeNode(m_node); +} + +// ---------------------------------------------------------------------------- + TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, scene::ISceneNode* parent, ModelDefinitionLoader& model_def_loader) : TrackObjectPresentationSceneNode(xml_node) diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index 219c98c5e..c951fcfe4 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -152,6 +152,18 @@ public: virtual ~TrackObjectPresentationEmpty(); }; +/** +* \ingroup tracks +* A track object representation that is a library node +*/ +class TrackObjectPresentationLibraryNode : public TrackObjectPresentationSceneNode +{ +public: + + TrackObjectPresentationLibraryNode(const XMLNode& xml_node, + ModelDefinitionLoader& model_def_loader); + virtual ~TrackObjectPresentationLibraryNode(); +}; /** * \ingroup tracks From 11dbb6f06253a701682bdebf5ef8b12d523d1514 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 00:05:48 +1100 Subject: [PATCH 105/112] Fixed some warnings printed when sfx are disabled. --- src/audio/sfx_openal.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 97f33b6a4..0cb3fb062 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -244,11 +244,14 @@ void SFXOpenAL::stop() */ void SFXOpenAL::reallyStopNow() { - m_status = SFX_STOPPED; - m_loop = false; - alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); - alSourceStop(m_sound_source); - SFXManager::checkError("stoping"); + if(m_status==SFX_PLAYING || m_status==SFX_PAUSED) + { + m_status = SFX_STOPPED; + m_loop = false; + alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); + alSourceStop(m_sound_source); + SFXManager::checkError("stoping"); + } } // reallyStopNow //----------------------------------------------------------------------------- From 3ea954cc73eceb58d558c1e62ecb70267e8491eb Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 00:48:15 +1100 Subject: [PATCH 106/112] Try to fix travis build. --- src/graphics/shaders_util.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 9631a2cd2..92d2bd1e0 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -1,6 +1,7 @@ #ifndef SHADERS_UTIL_HPP #define SHADERS_UTIL_HPP +#include "graphics/irr_driver.hpp" #include "utils/singleton.hpp" #include #include From b13e6931cecdc2f4344342afe5b4fe714347a5c9 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Oct 2014 16:39:39 +0200 Subject: [PATCH 107/112] Revert "Try to fix travis build." This reverts commit 3ea954cc73eceb58d558c1e62ecb70267e8491eb. --- src/graphics/shaders_util.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 92d2bd1e0..9631a2cd2 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -1,7 +1,6 @@ #ifndef SHADERS_UTIL_HPP #define SHADERS_UTIL_HPP -#include "graphics/irr_driver.hpp" #include "utils/singleton.hpp" #include #include From 4ee0e24ff7581aba2c13953d05a577c24355e0a0 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Oct 2014 16:40:27 +0200 Subject: [PATCH 108/112] Try to fix travis build. --- src/graphics/shaders_util.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/shaders_util.hpp b/src/graphics/shaders_util.hpp index 9631a2cd2..497491d55 100644 --- a/src/graphics/shaders_util.hpp +++ b/src/graphics/shaders_util.hpp @@ -57,7 +57,7 @@ GLint LoadProgram(AttributeType Tp, Types ... args) { GLint ProgramID = glCreateProgram(); loadAndAttach(ProgramID, args...); - if (irr_driver->getGLSLVersion() < 330) + if (getGLSLVersion() < 330) setAttribute(Tp, ProgramID); glLinkProgram(ProgramID); From f3dd0093766fc29b1abbaa4c746d87f502a16250 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Oct 2014 18:44:08 +0200 Subject: [PATCH 109/112] Try to fix model loader hpp --- src/tracks/model_definition_loader.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tracks/model_definition_loader.hpp b/src/tracks/model_definition_loader.hpp index 5cfb3a7aa..f7c669362 100644 --- a/src/tracks/model_definition_loader.hpp +++ b/src/tracks/model_definition_loader.hpp @@ -23,6 +23,7 @@ class LODNode; class Track; class STKInstancedSceneNode; +#include #include #include #include From 36ea7f30bf3b48a90bc12893e982c538071b9a7b Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 09:43:05 +1100 Subject: [PATCH 110/112] Only restart sfx if they were really paused. --- src/audio/sfx_openal.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 0cb3fb062..a84c0fd7f 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -259,7 +259,6 @@ void SFXOpenAL::reallyStopNow() */ void SFXOpenAL::pause() { - if (m_status != SFX_PLAYING || !SFXManager::get()->sfxAllowed()) return; SFXManager::get()->queue(SFXManager::SFX_PAUSE, this); } // pause @@ -269,6 +268,9 @@ void SFXOpenAL::pause() */ void SFXOpenAL::reallyPauseNow() { + // Need to be tested again here, since this function can be called + // from pauseAll, and we have to make sure to only pause playing sfx. + if (m_status != SFX_PLAYING || !SFXManager::get()->sfxAllowed()) return; m_status = SFX_PAUSED; alSourcePause(m_sound_source); SFXManager::checkError("pausing"); From 8b7bf28e0f0fc148b53abd21cbe3804e9dd85d67 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 22:37:19 +1100 Subject: [PATCH 111/112] Fixed #1147 - sounds should stopped when they are disabled in option screen. Fixed by explicitely stopping all non-looped sfx. --- src/audio/dummy_sfx.hpp | 6 ++-- src/audio/sfx_base.hpp | 4 ++- src/audio/sfx_manager.cpp | 13 ++++++-- src/audio/sfx_openal.cpp | 63 ++++++++++++++++++++++++++++----------- src/audio/sfx_openal.hpp | 7 ++++- 5 files changed, 70 insertions(+), 23 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index b7448d49d..765912902 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -30,11 +30,13 @@ class DummySFX : public SFXBase { public: - DummySFX(SFXBuffer* buffer, bool positional, float gain) {} + DummySFX(SFXBuffer* buffer, bool positional, + float gain) {} virtual ~DummySFX() {} /** Late creation, if SFX was initially disabled */ - virtual bool init() { return true; } + virtual bool init() { return true; } + virtual bool isLooped() { return false; } virtual void updatePlayingSFX(float dt) {} virtual void setLoop(bool status) {} virtual void reallySetLoop(bool status) {} diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index d8e7785ec..4e647b87c 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -45,13 +45,15 @@ public: /** Status of a sound effect. */ enum SFXStatus { - SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2 + SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2, + SFX_NOT_INITIALISED = 3 }; virtual ~SFXBase() {} /** Late creation, if SFX was initially disabled */ virtual bool init() = 0; + virtual bool isLooped() = 0; virtual void updatePlayingSFX(float dt) = 0; virtual void setPosition(const Vec3 &p) = 0; virtual void reallySetPosition(const Vec3 &p) = 0; diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 0eb286bee..1b45a8a5c 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -106,8 +106,6 @@ SFXManager::SFXManager() } pthread_attr_destroy(&attr); - if (!sfxAllowed()) return; - setMasterSFXVolume( UserConfigParams::m_sfx_volume ); m_sfx_commands.lock(); m_sfx_commands.getData().clear(); @@ -343,6 +341,17 @@ void SFXManager::soundToggled(const bool on) } else { + // First stop all sfx that are not looped + const int sfx_amount = (int)m_all_sfx.getData().size(); + m_all_sfx.lock(); + for (int i=0; iisLooped()) + { + m_all_sfx.getData()[i]->reallyStopNow(); + } + } + m_all_sfx.unlock(); pauseAll(); } } // soundToggled diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index a84c0fd7f..dafd3ce1f 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -44,7 +44,7 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, { m_sound_buffer = buffer; m_sound_source = 0; - m_status = SFX_UNKNOWN; + m_status = SFX_NOT_INITIALISED; m_positional = positional; m_default_gain = gain; m_loop = false; @@ -84,8 +84,11 @@ SFXOpenAL::~SFXOpenAL() */ bool SFXOpenAL::init() { + m_status = SFX_UNKNOWN; + alGenSources(1, &m_sound_source ); - if (!SFXManager::checkError("generating a source")) return false; + if (!SFXManager::checkError("generating a source")) + return false; assert( alIsBuffer(m_sound_buffer->getBufferID()) ); assert( alIsSource(m_sound_source) ); @@ -137,13 +140,6 @@ void SFXOpenAL::updatePlayingSFX(float dt) m_status = SFX_STOPPED; } // updatePlayingSFX -// ------------------------------------------------------------------------ -/** Returns the status of this sfx. */ -SFXBase::SFXStatus SFXOpenAL::getStatus() -{ - return m_status; -} // getStatus; - //----------------------------------------------------------------------------- /** Queues up a change of the pitch of a sound effect to the sfx manager. * \param factor Speedup/slowdown between 0.5 and 2.0 @@ -161,6 +157,13 @@ void SFXOpenAL::setSpeed(float factor) */ void SFXOpenAL::reallySetSpeed(float factor) { + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } + //OpenAL only accepts pitches in the range of 0.5 to 2.0 if(factor > 2.0f) { @@ -194,6 +197,13 @@ void SFXOpenAL::reallySetVolume(float gain) if(m_status==SFX_UNKNOWN) return; + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } + alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain); } // reallySetVolume @@ -204,6 +214,13 @@ void SFXOpenAL::setMasterVolume(float gain) m_master_gain = gain; if(m_status==SFX_UNKNOWN) return; + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } + alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain); @@ -224,6 +241,12 @@ void SFXOpenAL::setLoop(bool status) */ void SFXOpenAL::reallySetLoop(bool status) { + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } m_loop = status; alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE); @@ -290,6 +313,13 @@ void SFXOpenAL::resume() */ void SFXOpenAL::reallyResumeNow() { + if(m_status==SFX_NOT_INITIALISED) + { + init(); + if(m_status==SFX_UNKNOWN) + return; + } + if(m_status==SFX_PAUSED) { alSourcePlay(m_sound_source); @@ -324,7 +354,7 @@ void SFXOpenAL::play() void SFXOpenAL::reallyPlayNow() { if (!SFXManager::get()->sfxAllowed()) return; - if (m_status==SFX_UNKNOWN) + if (m_status==SFX_NOT_INITIALISED) { // lazily create OpenAL source when needed init(); @@ -354,14 +384,13 @@ void SFXOpenAL::setPosition(const Vec3 &position) */ void SFXOpenAL::reallySetPosition(const Vec3 &position) { - if(!UserConfigParams::m_sfx) - return; - if (m_status==SFX_UNKNOWN) + if(m_status==SFX_NOT_INITIALISED) { - Log::warn("SFX", "Position called on non-ok SFX <%s>", - m_sound_buffer->getFileName().c_str()); - return; + init(); + if(m_status==SFX_UNKNOWN) + return; } + if (!m_positional) { // in multiplayer, all sounds are positional, so in this case don't @@ -407,7 +436,7 @@ void SFXOpenAL::onSoundEnabledBack() { if (m_loop) { - if (m_status==SFX_UNKNOWN) init(); + if (m_status==SFX_NOT_INITIALISED) init(); if (m_status!=SFX_UNKNOWN) { alSourcef(m_sound_source, AL_GAIN, 0); diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 23321f3e9..f417fedbb 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -102,7 +102,12 @@ public: virtual void setMasterVolume(float gain); virtual void onSoundEnabledBack(); virtual void setRolloff(float rolloff); - virtual SFXStatus getStatus(); + // ------------------------------------------------------------------------ + /** Returns if this sfx is looped or not. */ + virtual bool isLooped() { return m_loop; } + // ------------------------------------------------------------------------ + /** Returns the status of this sfx. */ + virtual SFXStatus getStatus() { return m_status; } // ------------------------------------------------------------------------ /** Returns the buffer associated with this sfx. */ From 9dff5a79907141c5cb1639fbf07976ee6db928c3 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Oct 2014 23:01:31 +1100 Subject: [PATCH 112/112] Fix potential memory overwrite in soccer mode when using one player only (artist debug mode). --- src/modes/soccer_world.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 022ffc9f0..4e4fc754c 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -436,6 +436,11 @@ void SoccerWorld::initKartList() for(unsigned int n=0; ngetLocalKartInfo(n).getSoccerTeam(); +#ifdef DEBUG + // In debug mode it's possible to play soccer with a single player + // (in artist debug mode). Avoid overwriting memory in this case. + if(team==SOCCER_TEAM_NONE) team=SOCCER_TEAM_RED; +#endif m_karts[n]->setPosition(team_cur_position[team]); team_cur_position[team]++; } // next kart