From 88f5e6dad98cf8cb887f136a9a9e889d62a3c0e6 Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:40:51 +0200 Subject: [PATCH 1/5] Background ".sprite" support Backgrounds can now load ".sprite" files for top, middle and bottom images. The current action for any or all of those images can be set via scripting. Backgrounds are not animated in the editor to prevent inconvenience. Closes #1089. --- src/object/background.cpp | 83 ++++++++++++++++---- src/object/background.hpp | 16 ++-- src/scripting/background.cpp | 28 +++++++ src/scripting/background.hpp | 21 +++++ src/scripting/wrapper.cpp | 148 +++++++++++++++++++++++++++++++++++ src/sprite/sprite.cpp | 27 ++++++- src/sprite/sprite.hpp | 5 ++ 7 files changed, 303 insertions(+), 25 deletions(-) diff --git a/src/object/background.cpp b/src/object/background.cpp index a2b189195b1..7aabebd0f5e 100644 --- a/src/object/background.cpp +++ b/src/object/background.cpp @@ -20,6 +20,8 @@ #include #include "editor/editor.hpp" +#include "sprite/sprite.hpp" +#include "sprite/sprite_manager.hpp" #include "supertux/d_scope.hpp" #include "supertux/flip_level_transformer.hpp" #include "supertux/gameconfig.hpp" @@ -28,7 +30,6 @@ #include "util/reader_mapping.hpp" #include "util/writer.hpp" #include "video/drawing_context.hpp" -#include "video/surface.hpp" Background::Background() : ExposedObject(this), @@ -192,9 +193,9 @@ Background::get_settings() result.add_float(_("Scroll speed y"), &m_scroll_speed.y, "scroll-speed-y", 0.0f); result.add_float(_("Parallax Speed x"), &m_parallax_speed.x, "speed", std::nullopt); result.add_float(_("Parallax Speed y"), &m_parallax_speed.y, "speed-y", m_parallax_speed.x); - result.add_surface(_("Top image"), &m_imagefile_top, "image-top", ""); - result.add_surface(_("Image"), &m_imagefile, "image"); - result.add_surface(_("Bottom image"), &m_imagefile_bottom, "image-bottom", ""); + result.add_sprite(_("Top image"), &m_imagefile_top, "image-top", ""); + result.add_sprite(_("Image"), &m_imagefile, "image"); + result.add_sprite(_("Bottom image"), &m_imagefile_bottom, "image-bottom", ""); result.add_rgba(_("Colour"), &m_color, "color"); result.add_enum(_("Draw target"), reinterpret_cast(&m_target), {_("Normal"), _("Lightmap")}, @@ -299,13 +300,16 @@ Background::draw_image(DrawingContext& context, const Vector& pos_) Canvas& canvas = context.get_canvas(m_target); context.set_flip(context.get_flip() ^ m_flip); + m_image->set_color(m_color); + m_image->set_blend(m_blend); + if (m_fill) { Rectf dstrect(Vector(pos_.x - context.get_width() / 2.0f, pos_.y - context.get_height() / 2.0f), Sizef(context.get_width(), context.get_height())); - canvas.draw_surface_scaled(m_image, dstrect, m_layer); + m_image->draw_scaled(canvas, dstrect, m_layer); } else { @@ -316,7 +320,7 @@ Background::draw_image(DrawingContext& context, const Vector& pos_) { Vector p(pos_.x - parallax_image_size.width / 2.0f, pos_.y + static_cast(y) * img_h - img_h_2); - canvas.draw_surface(m_image, p, 0.f, m_color, m_blend, m_layer); + m_image->draw(canvas, p, m_layer); } break; @@ -325,7 +329,7 @@ Background::draw_image(DrawingContext& context, const Vector& pos_) { Vector p(pos_.x + parallax_image_size.width / 2.0f - img_w, pos_.y + static_cast(y) * img_h - img_h_2); - canvas.draw_surface(m_image, p, 0.f, m_color, m_blend, m_layer); + m_image->draw(canvas, p, m_layer); } break; @@ -334,7 +338,7 @@ Background::draw_image(DrawingContext& context, const Vector& pos_) { Vector p(pos_.x + static_cast(x) * img_w - img_w_2, pos_.y - parallax_image_size.height / 2.0f); - canvas.draw_surface(m_image, p, 0.f, m_color, m_blend, m_layer); + m_image->draw(canvas, p, m_layer); } break; @@ -343,7 +347,7 @@ Background::draw_image(DrawingContext& context, const Vector& pos_) { Vector p(pos_.x + static_cast(x) * img_w - img_w_2, pos_.y - img_h + parallax_image_size.height / 2.0f); - canvas.draw_surface(m_image, p, 0.f, m_color, m_blend, m_layer); + m_image->draw(canvas, p, m_layer); } break; @@ -356,15 +360,21 @@ Background::draw_image(DrawingContext& context, const Vector& pos_) if (m_image_top && (y < 0)) { - canvas.draw_surface(m_image_top, p, 0.f, m_color, m_blend, m_layer); + m_image_top->set_color(m_color); + m_image_top->set_blend(m_blend); + + m_image_top->draw(canvas, p, m_layer); } else if (m_image_bottom && (y > 0)) { - canvas.draw_surface(m_image_bottom, p, 0.f, m_color, m_blend, m_layer); + m_image_bottom->set_color(m_color); + m_image_bottom->set_blend(m_blend); + + m_image_bottom->draw(canvas, p, m_layer); } else { - canvas.draw_surface(m_image, p, 0.f, m_color, m_blend, m_layer); + m_image->draw(canvas, p, m_layer); } } break; @@ -459,15 +469,25 @@ std::unordered_map fallback_paths = { } // namespace -SurfacePtr +SpritePtr Background::load_background(const std::string& image_path) +{ + SpritePtr sprite = load_background_sprite(image_path); + if (!sprite) return nullptr; + + sprite->set_animation_enabled(!Editor::is_active()); + return sprite; +} + +SpritePtr +Background::load_background_sprite(const std::string& image_path) { if (image_path.empty()) return nullptr; if (PHYSFS_exists(image_path.c_str())) // No need to search fallback paths. - return Surface::from_file(image_path); + return SpriteManager::current()->create(image_path); // Search for a fallback image in fallback_paths. const std::string& default_dir = "images/background/"; @@ -477,13 +497,42 @@ Background::load_background(const std::string& image_path) new_path.erase(0, default_dir.length()); else if (image_path.substr(0, default_dir2.length()) == default_dir2) new_path.erase(0, default_dir2.length()); + auto it = fallback_paths.find(new_path); if (it == fallback_paths.end()) - // Unknown image, let the texture manager select the dummy texture. - return Surface::from_file(image_path); + // Unknown image, try checking for a ".deprecated" version, or use the dummy texture. + return SpriteManager::current()->create(image_path); new_path = default_dir + it->second; - return Surface::from_file(new_path); + return SpriteManager::current()->create(new_path); +} + +void +Background::set_top_image_action(const std::string& action) +{ + if (m_image_top) + m_image_top->set_action(action); +} + +void +Background::set_image_action(const std::string& action) +{ + m_image->set_action(action); +} + +void +Background::set_bottom_image_action(const std::string& action) +{ + if (m_image_bottom) + m_image_bottom->set_action(action); +} + +void +Background::set_image_actions(const std::string& action) +{ + set_top_image_action(action); + set_image_action(action); + set_bottom_image_action(action); } void diff --git a/src/object/background.hpp b/src/object/background.hpp index 1c18c5924da..72b2b4898d0 100644 --- a/src/object/background.hpp +++ b/src/object/background.hpp @@ -19,13 +19,13 @@ #include "math/vector.hpp" #include "scripting/background.hpp" +#include "sprite/sprite_ptr.hpp" #include "squirrel/exposed_object.hpp" #include "supertux/game_object.hpp" #include "supertux/timer.hpp" #include "video/blend.hpp" #include "video/drawing_context.hpp" #include "video/flip.hpp" -#include "video/surface_ptr.hpp" class ReaderMapping; @@ -68,6 +68,11 @@ class Background final : public GameObject, void set_color(Color color) { m_color = color; } void fade_color(Color color, float time); + void set_top_image_action(const std::string& action); + void set_image_action(const std::string& action); + void set_bottom_image_action(const std::string& action); + void set_image_actions(const std::string& action); + private: enum Alignment { NO_ALIGNMENT, @@ -78,7 +83,8 @@ class Background final : public GameObject, }; private: - SurfacePtr load_background(const std::string& image_path); + SpritePtr load_background(const std::string& image_path); + SpritePtr load_background_sprite(const std::string& image_path); private: /** Backgrounds with NO_ALIGNMENT are repeated over the whole @@ -99,9 +105,9 @@ class Background final : public GameObject, Vector m_parallax_speed; Vector m_scroll_speed; Vector m_scroll_offset; - SurfacePtr m_image_top; /**< image to draw above pos */ - SurfacePtr m_image; /**< image to draw, anchored at pos */ - SurfacePtr m_image_bottom; /**< image to draw below pos+screenheight */ + SpritePtr m_image_top; /**< image to draw above pos */ + SpritePtr m_image; /**< image to draw, anchored at pos */ + SpritePtr m_image_bottom; /**< image to draw below pos+screenheight */ Blend m_blend; Color m_color; diff --git a/src/scripting/background.cpp b/src/scripting/background.cpp index 62b89f9206c..850ad98130e 100644 --- a/src/scripting/background.cpp +++ b/src/scripting/background.cpp @@ -120,6 +120,34 @@ Background::fade_color(float red, float green, float blue, float alpha, float ti object.fade_color(Color(red, green, blue, alpha), time); } +void +Background::set_top_image_action(const std::string& action) +{ + SCRIPT_GUARD_VOID; + object.set_top_image_action(action); +} + +void +Background::set_image_action(const std::string& action) +{ + SCRIPT_GUARD_VOID; + object.set_image_action(action); +} + +void +Background::set_bottom_image_action(const std::string& action) +{ + SCRIPT_GUARD_VOID; + object.set_bottom_image_action(action); +} + +void +Background::set_image_actions(const std::string& action) +{ + SCRIPT_GUARD_VOID; + object.set_image_actions(action); +} + } // namespace scripting /* EOF */ diff --git a/src/scripting/background.hpp b/src/scripting/background.hpp index b1c868c415a..66609b27f53 100644 --- a/src/scripting/background.hpp +++ b/src/scripting/background.hpp @@ -98,6 +98,27 @@ class Background final * @param float $time */ void fade_color(float red, float green, float blue, float alpha, float time); + + /** + * Sets the sprite action for the top image. + * @param string $action + */ + void set_top_image_action(const std::string& action); + /** + * Sets the sprite action for the main (middle) image. + * @param string $action + */ + void set_image_action(const std::string& action); + /** + * Sets the sprite action for the bottom image. + * @param string $action + */ + void set_bottom_image_action(const std::string& action); + /** + * Sets the sprite action for all images (top, middle and bottom). + * @param string $action + */ + void set_image_actions(const std::string& action); }; } // namespace scripting diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index 281a3b78a3d..41f6b54a911 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -418,6 +418,126 @@ static SQInteger Background_fade_color_wrapper(HSQUIRRELVM vm) } +static SQInteger Background_set_top_image_action_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, nullptr, SQTrue)) || !data) { + sq_throwerror(vm, _SC("'set_top_image_action' called without instance")); + return SQ_ERROR; + } + scripting::Background* _this = reinterpret_cast (data); + + const SQChar* arg0; + if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a string")); + return SQ_ERROR; + } + + try { + _this->set_top_image_action(arg0); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_top_image_action'")); + return SQ_ERROR; + } + +} + +static SQInteger Background_set_image_action_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, nullptr, SQTrue)) || !data) { + sq_throwerror(vm, _SC("'set_image_action' called without instance")); + return SQ_ERROR; + } + scripting::Background* _this = reinterpret_cast (data); + + const SQChar* arg0; + if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a string")); + return SQ_ERROR; + } + + try { + _this->set_image_action(arg0); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_image_action'")); + return SQ_ERROR; + } + +} + +static SQInteger Background_set_bottom_image_action_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, nullptr, SQTrue)) || !data) { + sq_throwerror(vm, _SC("'set_bottom_image_action' called without instance")); + return SQ_ERROR; + } + scripting::Background* _this = reinterpret_cast (data); + + const SQChar* arg0; + if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a string")); + return SQ_ERROR; + } + + try { + _this->set_bottom_image_action(arg0); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_bottom_image_action'")); + return SQ_ERROR; + } + +} + +static SQInteger Background_set_image_actions_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, nullptr, SQTrue)) || !data) { + sq_throwerror(vm, _SC("'set_image_actions' called without instance")); + return SQ_ERROR; + } + scripting::Background* _this = reinterpret_cast (data); + + const SQChar* arg0; + if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a string")); + return SQ_ERROR; + } + + try { + _this->set_image_actions(arg0); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_image_actions'")); + return SQ_ERROR; + } + +} + static SQInteger BadGuy_release_hook(SQUserPointer ptr, SQInteger ) { scripting::BadGuy* _this = reinterpret_cast (ptr); @@ -14566,6 +14686,34 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, "Couldn't register function 'fade_color'"); } + sq_pushstring(v, "set_top_image_action", -1); + sq_newclosure(v, &Background_set_top_image_action_wrapper, 0); + sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, ".s"); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'set_top_image_action'"); + } + + sq_pushstring(v, "set_image_action", -1); + sq_newclosure(v, &Background_set_image_action_wrapper, 0); + sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, ".s"); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'set_image_action'"); + } + + sq_pushstring(v, "set_bottom_image_action", -1); + sq_newclosure(v, &Background_set_bottom_image_action_wrapper, 0); + sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, ".s"); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'set_bottom_image_action'"); + } + + sq_pushstring(v, "set_image_actions", -1); + sq_newclosure(v, &Background_set_image_actions_wrapper, 0); + sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, ".s"); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'set_image_actions'"); + } + if(SQ_FAILED(sq_createslot(v, -3))) { throw SquirrelError(v, "Couldn't register class 'Background'"); } diff --git a/src/sprite/sprite.cpp b/src/sprite/sprite.cpp index cdaa68548f5..03791371308 100644 --- a/src/sprite/sprite.cpp +++ b/src/sprite/sprite.cpp @@ -28,6 +28,7 @@ Sprite::Sprite(SpriteData& newdata) : m_frame(0), m_frameidx(0), m_animation_loops(-1), + m_animation_enabled(true), m_last_ticks(), m_angle(0.0f), m_alpha(1.0f), @@ -45,6 +46,7 @@ Sprite::Sprite(const Sprite& other) : m_frame(other.m_frame), m_frameidx(other.m_frameidx), m_animation_loops(other.m_animation_loops), + m_animation_enabled(other.m_animation_enabled), m_last_ticks(g_game_time), m_angle(0.0f), // FIXME: this can't be right m_alpha(1.0f), @@ -96,7 +98,7 @@ Sprite::set_action(const std::string& name, int loops) const SpriteData::Action* newaction = m_data.get_action(name); if (!newaction) { - log_debug << "Action '" << name << "' not found." << std::endl; + log_warning << "Action '" << name << "' not found." << std::endl; return; } @@ -133,6 +135,8 @@ Sprite::update() float frame_inc = m_action->fps * (g_game_time - m_last_ticks); m_last_ticks = g_game_time; + if (!m_animation_enabled) return; + m_frame += frame_inc; while (m_frame >= 1.0f) { @@ -158,10 +162,9 @@ void Sprite::draw(Canvas& canvas, const Vector& pos, int layer, Flip flip) { - assert(m_action != nullptr); + assert(m_action); update(); - DrawingContext& context = canvas.get_context(); context.push_transform(); @@ -178,6 +181,24 @@ Sprite::draw(Canvas& canvas, const Vector& pos, int layer, context.pop_transform(); } +void +Sprite::draw_scaled(Canvas& canvas, const Rectf& dest_rect, int layer, + Flip flip) +{ + assert(m_action); + update(); + + DrawingContext& context = canvas.get_context(); + context.push_transform(); + + context.set_flip(context.get_flip() ^ flip); + context.set_alpha(context.get_alpha() * m_alpha); + + canvas.draw_surface_scaled(m_action->surfaces[m_frameidx], dest_rect, layer); + + context.pop_transform(); +} + int Sprite::get_width() const { diff --git a/src/sprite/sprite.hpp b/src/sprite/sprite.hpp index cb7b05c2757..0b4cf4d5b5a 100644 --- a/src/sprite/sprite.hpp +++ b/src/sprite/sprite.hpp @@ -39,6 +39,8 @@ class Sprite final /** Draw sprite, automatically calculates next frame */ void draw(Canvas& canvas, const Vector& pos, int layer, Flip flip = NO_FLIP); + void draw_scaled(Canvas& canvas, const Rectf& dest_rect, int layer, + Flip flip = NO_FLIP); /** Set action (or state) */ void set_action(const std::string& name, int loops = -1); @@ -68,6 +70,8 @@ class Sprite final /* Stop animation */ void stop_animation() { m_animation_loops = 0; } + void set_animation_enabled(bool enabled) { m_animation_enabled = enabled; } + /** Check if animation is stopped or not */ bool animation_done() const; @@ -129,6 +133,7 @@ class Sprite final // between 0 and get_frames() int m_frameidx; int m_animation_loops; + bool m_animation_enabled; float m_last_ticks; float m_angle; float m_alpha; From 4738076c2b27198a96a1bdcf2166c5d5de5c54d9 Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Mon, 20 May 2024 17:25:47 +0300 Subject: [PATCH 2/5] Remove `load_background` methods from `Background` --- src/object/background.cpp | 198 +++++++++++++++++++------------------- src/object/background.hpp | 4 - 2 files changed, 97 insertions(+), 105 deletions(-) diff --git a/src/object/background.cpp b/src/object/background.cpp index 8ce01c65c38..9ba7813fab8 100644 --- a/src/object/background.cpp +++ b/src/object/background.cpp @@ -31,6 +31,103 @@ #include "util/writer.hpp" #include "video/drawing_context.hpp" +static const std::unordered_map fallback_paths = { + {"arctis2.png", "antarctic/arctis2.png"}, + {"misty_snowhills_small.png", "antarctic/misty_snowhills_small.png"}, + {"semi_arctic.jpg", "antarctic/semi_arctic.jpg"}, + {"bridgecloud-dark.png", "arctic_bridge/bridgecloud-dark.png"}, + {"bridgecloud-light.png", "arctic_bridge/bridgecloud-light.png"}, + {"bridgeocean-fade.png", "arctic_bridge/bridgeocean-fade.png"}, + {"bridgeocean-nofade.png", "arctic_bridge/bridgeocean-nofade.png"}, + {"bridgeocean-original.png", "arctic_bridge/bridgeocean-original.png"}, + {"arcticskies1.png", "arcticskies/arcticskies1.png"}, + {"arcticskies2.png", "arcticskies/arcticskies2.png"}, + {"arcticskies3.png", "arcticskies/arcticskies3.png"}, + {"arcticskies35.png", "arcticskies/arcticskies35.png"}, + {"arcticskies4.png", "arcticskies/arcticskies4.png"}, + {"block-snow-background.png", "block_snow/block-snow-background.png"}, + {"block-snow-midground.png", "block_snow/block-snow-midground.png"}, + {"block-snow-top.png", "block_snow/block-snow-top.png"}, + {"bluemountain-bottom.png", "bluemountain/bluemountain-bottom.png"}, + {"bluemountain-middle.png", "bluemountain/bluemountain-middle.png"}, + {"bluemountain-top.png", "bluemountain/bluemountain-top.png"}, + {"bluemountain2.png", "bluemountain/bluemountain2.png"}, + {"castle_foreground.png", "castle/castle_foreground.png"}, + {"snowcastle.png", "castle/snowcastle.png"}, + {"cloud-mountains-background.png", "cloud_mountains/cloud-mountains-background.png"}, + {"cloud-mountains-bottom.png", "cloud_mountains/cloud-mountains-bottom.png"}, + {"cloud-mountains-forground.png", "cloud_mountains/cloud-mountains-forground.png"}, + {"cloud-mountains-midground.png", "cloud_mountains/cloud-mountains-midground.png"}, + {"dawn_hill_para_blur.png", "forest/dawn_hill_para_blur.png"}, + {"forest2_para.png", "forest/forest2_para.png"}, + {"forest_para2.png", "forest/forest_para2.png"}, + {"forest_para3.png", "forest/forest_para3.png"}, + {"forest_para3_bottom.png", "forest/forest_para3_bottom.png"}, + {"nighthills.png", "forest/nighthills.png"}, + {"ghostforest.jpg", "ghostforest/ghostforest.jpg"}, + {"ghostforest_grave.png", "ghostforest/ghostforest_grave.png"}, + {"ghostforest_para.png", "ghostforest/ghostforest_para.png"}, + {"cave2.jpg", "ice_cave/cave2.jpg"}, + {"darkcave-background.png", "ice_cave/darkcave-background.png"}, + {"darkcave-middle.png", "ice_cave/darkcave-middle.png"}, + {"darkcave-preview.png", "ice_cave/darkcave-preview.png"}, + {"darkcave-top_and_bottom.png", "ice_cave/darkcave-top_and_bottom.png"}, + {"darkcavemidground-middle.png", "ice_cave/darkcavemidground-middle.png"}, + {"darkcavemidground-top_and_bottom.png", "ice_cave/darkcavemidground-top_and_bottom.png"}, + {"black_800px.png", "misc/black_800px.png"}, + {"fog.png", "misc/fog.png"}, + {"grid.png", "misc/grid.png"}, + {"grid.surface", "misc/grid.surface"}, + {"heatshimmer-displacement.png", "misc/heatshimmer-displacement.png"}, + {"heatshimmer.png", "misc/heatshimmer.png"}, + {"heatshimmer.surface", "misc/heatshimmer.surface"}, + {"leaves.png", "misc/leaves.png"}, + {"oiltux.jpg", "misc/oiltux.jpg"}, + {"transparent_up.png", "misc/transparent_up.png"}, + {"nightsky.png", "nightsky/nightsky.png"}, + {"nightsky_bottom.png", "nightsky/nightsky_bottom.png"}, + {"nightsky_middle.png", "nightsky/nightsky_middle.png"}, + {"nightsky_para.png", "nightsky/nightsky_para.png"}, + {"nightsky_top.png", "nightsky/nightsky_top.png"}, +}; + +static SpritePtr load_background_sprite(const std::string& image_path) +{ + if (image_path.empty()) + return nullptr; + + if (PHYSFS_exists(image_path.c_str())) + // No need to search fallback paths. + return SpriteManager::current()->create(image_path); + + // Search for a fallback image in fallback_paths. + const std::string& default_dir = "images/background/"; + const std::string& default_dir2 = "/images/background/"; + std::string new_path = image_path; + if (image_path.substr(0, default_dir.length()) == default_dir) + new_path.erase(0, default_dir.length()); + else if (image_path.substr(0, default_dir2.length()) == default_dir2) + new_path.erase(0, default_dir2.length()); + + auto it = fallback_paths.find(new_path); + if (it == fallback_paths.end()) + // Unknown image, try checking for a ".deprecated" version, or use the dummy texture. + return SpriteManager::current()->create(image_path); + + new_path = default_dir + it->second; + return SpriteManager::current()->create(new_path); +} + +static SpritePtr load_background(const std::string& image_path) +{ + SpritePtr sprite = load_background_sprite(image_path); + if (!sprite) return nullptr; + + sprite->set_animation_enabled(!Editor::is_active()); + return sprite; +} + + Background::Background() : ExposedObject(this), m_alignment(NO_ALIGNMENT), @@ -406,107 +503,6 @@ Background::draw(DrawingContext& context) center_offset.y * (1.0f - m_parallax_speed.y))); } -namespace { -std::unordered_map fallback_paths = { - {"arctis2.png", "antarctic/arctis2.png"}, - {"misty_snowhills_small.png", "antarctic/misty_snowhills_small.png"}, - {"semi_arctic.jpg", "antarctic/semi_arctic.jpg"}, - {"bridgecloud-dark.png", "arctic_bridge/bridgecloud-dark.png"}, - {"bridgecloud-light.png", "arctic_bridge/bridgecloud-light.png"}, - {"bridgeocean-fade.png", "arctic_bridge/bridgeocean-fade.png"}, - {"bridgeocean-nofade.png", "arctic_bridge/bridgeocean-nofade.png"}, - {"bridgeocean-original.png", "arctic_bridge/bridgeocean-original.png"}, - {"arcticskies1.png", "arcticskies/arcticskies1.png"}, - {"arcticskies2.png", "arcticskies/arcticskies2.png"}, - {"arcticskies3.png", "arcticskies/arcticskies3.png"}, - {"arcticskies35.png", "arcticskies/arcticskies35.png"}, - {"arcticskies4.png", "arcticskies/arcticskies4.png"}, - {"block-snow-background.png", "block_snow/block-snow-background.png"}, - {"block-snow-midground.png", "block_snow/block-snow-midground.png"}, - {"block-snow-top.png", "block_snow/block-snow-top.png"}, - {"bluemountain-bottom.png", "bluemountain/bluemountain-bottom.png"}, - {"bluemountain-middle.png", "bluemountain/bluemountain-middle.png"}, - {"bluemountain-top.png", "bluemountain/bluemountain-top.png"}, - {"bluemountain2.png", "bluemountain/bluemountain2.png"}, - {"castle_foreground.png", "castle/castle_foreground.png"}, - {"snowcastle.png", "castle/snowcastle.png"}, - {"cloud-mountains-background.png", "cloud_mountains/cloud-mountains-background.png"}, - {"cloud-mountains-bottom.png", "cloud_mountains/cloud-mountains-bottom.png"}, - {"cloud-mountains-forground.png", "cloud_mountains/cloud-mountains-forground.png"}, - {"cloud-mountains-midground.png", "cloud_mountains/cloud-mountains-midground.png"}, - {"dawn_hill_para_blur.png", "forest/dawn_hill_para_blur.png"}, - {"forest2_para.png", "forest/forest2_para.png"}, - {"forest_para2.png", "forest/forest_para2.png"}, - {"forest_para3.png", "forest/forest_para3.png"}, - {"forest_para3_bottom.png", "forest/forest_para3_bottom.png"}, - {"nighthills.png", "forest/nighthills.png"}, - {"ghostforest.jpg", "ghostforest/ghostforest.jpg"}, - {"ghostforest_grave.png", "ghostforest/ghostforest_grave.png"}, - {"ghostforest_para.png", "ghostforest/ghostforest_para.png"}, - {"cave2.jpg", "ice_cave/cave2.jpg"}, - {"darkcave-background.png", "ice_cave/darkcave-background.png"}, - {"darkcave-middle.png", "ice_cave/darkcave-middle.png"}, - {"darkcave-preview.png", "ice_cave/darkcave-preview.png"}, - {"darkcave-top_and_bottom.png", "ice_cave/darkcave-top_and_bottom.png"}, - {"darkcavemidground-middle.png", "ice_cave/darkcavemidground-middle.png"}, - {"darkcavemidground-top_and_bottom.png", "ice_cave/darkcavemidground-top_and_bottom.png"}, - {"black_800px.png", "misc/black_800px.png"}, - {"fog.png", "misc/fog.png"}, - {"grid.png", "misc/grid.png"}, - {"grid.surface", "misc/grid.surface"}, - {"heatshimmer-displacement.png", "misc/heatshimmer-displacement.png"}, - {"heatshimmer.png", "misc/heatshimmer.png"}, - {"heatshimmer.surface", "misc/heatshimmer.surface"}, - {"leaves.png", "misc/leaves.png"}, - {"oiltux.jpg", "misc/oiltux.jpg"}, - {"transparent_up.png", "misc/transparent_up.png"}, - {"nightsky.png", "nightsky/nightsky.png"}, - {"nightsky_bottom.png", "nightsky/nightsky_bottom.png"}, - {"nightsky_middle.png", "nightsky/nightsky_middle.png"}, - {"nightsky_para.png", "nightsky/nightsky_para.png"}, - {"nightsky_top.png", "nightsky/nightsky_top.png"}, -}; - -} // namespace - -SpritePtr -Background::load_background(const std::string& image_path) -{ - SpritePtr sprite = load_background_sprite(image_path); - if (!sprite) return nullptr; - - sprite->set_animation_enabled(!Editor::is_active()); - return sprite; -} - -SpritePtr -Background::load_background_sprite(const std::string& image_path) -{ - if (image_path.empty()) - return nullptr; - - if (PHYSFS_exists(image_path.c_str())) - // No need to search fallback paths. - return SpriteManager::current()->create(image_path); - - // Search for a fallback image in fallback_paths. - const std::string& default_dir = "images/background/"; - const std::string& default_dir2 = "/images/background/"; - std::string new_path = image_path; - if (image_path.substr(0, default_dir.length()) == default_dir) - new_path.erase(0, default_dir.length()); - else if (image_path.substr(0, default_dir2.length()) == default_dir2) - new_path.erase(0, default_dir2.length()); - - auto it = fallback_paths.find(new_path); - if (it == fallback_paths.end()) - // Unknown image, try checking for a ".deprecated" version, or use the dummy texture. - return SpriteManager::current()->create(image_path); - - new_path = default_dir + it->second; - return SpriteManager::current()->create(new_path); -} - void Background::set_top_image_action(const std::string& action) { diff --git a/src/object/background.hpp b/src/object/background.hpp index 72b2b4898d0..2a881ccf830 100644 --- a/src/object/background.hpp +++ b/src/object/background.hpp @@ -82,10 +82,6 @@ class Background final : public GameObject, BOTTOM_ALIGNMENT }; -private: - SpritePtr load_background(const std::string& image_path); - SpritePtr load_background_sprite(const std::string& image_path); - private: /** Backgrounds with NO_ALIGNMENT are repeated over the whole screen, backgrounds with left, right, top, bottom alignment are From bc40214a41051eea7f94b4a3e55d7e7b0d489d05 Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Mon, 20 May 2024 17:47:21 +0300 Subject: [PATCH 3/5] Remove unneeded `m_animation_enabled` `Sprite` member variable [ci skip] --- src/object/background.cpp | 4 +++- src/sprite/sprite.cpp | 4 +--- src/sprite/sprite.hpp | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/object/background.cpp b/src/object/background.cpp index 9ba7813fab8..a3accf618d5 100644 --- a/src/object/background.cpp +++ b/src/object/background.cpp @@ -123,7 +123,9 @@ static SpritePtr load_background(const std::string& image_path) SpritePtr sprite = load_background_sprite(image_path); if (!sprite) return nullptr; - sprite->set_animation_enabled(!Editor::is_active()); + if (Editor::is_active()) + sprite->pause_animation(); + return sprite; } diff --git a/src/sprite/sprite.cpp b/src/sprite/sprite.cpp index a324e3c9d0e..a2cf5ceadc3 100644 --- a/src/sprite/sprite.cpp +++ b/src/sprite/sprite.cpp @@ -28,7 +28,6 @@ Sprite::Sprite(SpriteData& newdata) : m_frame(0), m_frameidx(0), m_animation_loops(-1), - m_animation_enabled(true), m_last_ticks(), m_angle(0.0f), m_alpha(1.0f), @@ -47,7 +46,6 @@ Sprite::Sprite(const Sprite& other) : m_frame(other.m_frame), m_frameidx(other.m_frameidx), m_animation_loops(other.m_animation_loops), - m_animation_enabled(other.m_animation_enabled), m_last_ticks(g_game_time), m_angle(0.0f), // FIXME: this can't be right m_alpha(1.0f), @@ -140,7 +138,7 @@ Sprite::update() float frame_inc = m_action->fps * (g_game_time - m_last_ticks); m_last_ticks = g_game_time; - if (!m_animation_enabled || m_is_paused) return; + if (m_is_paused) return; m_frame += frame_inc; diff --git a/src/sprite/sprite.hpp b/src/sprite/sprite.hpp index dcc70a4a0e3..7c9c21b99a7 100644 --- a/src/sprite/sprite.hpp +++ b/src/sprite/sprite.hpp @@ -70,8 +70,6 @@ class Sprite final /* Stop animation */ void stop_animation() { m_animation_loops = 0; } - void set_animation_enabled(bool enabled) { m_animation_enabled = enabled; } - void pause_animation() { m_is_paused = true; } void resume_animation() { m_is_paused = false; } @@ -139,7 +137,6 @@ class Sprite final // between 0 and get_frames() int m_frameidx; int m_animation_loops; - bool m_animation_enabled; float m_last_ticks; float m_angle; float m_alpha; From 160ecfee60793c0224d64f85d4b7d1c6cd552593 Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Mon, 29 Jul 2024 18:37:52 +0300 Subject: [PATCH 4/5] Fix remaining conflict --- src/object/background.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/object/background.hpp b/src/object/background.hpp index 5e1d3b705e7..8c7a9273cc5 100644 --- a/src/object/background.hpp +++ b/src/object/background.hpp @@ -18,12 +18,7 @@ #define HEADER_SUPERTUX_OBJECT_BACKGROUND_HPP #include "math/vector.hpp" -<<<<<<< HEAD -#include "scripting/background.hpp" #include "sprite/sprite_ptr.hpp" -#include "squirrel/exposed_object.hpp" -======= ->>>>>>> supertux/master #include "supertux/game_object.hpp" #include "supertux/timer.hpp" #include "video/blend.hpp" From 5510f118f9630fc7ce09479b4363336f1f5a6420 Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Wed, 31 Jul 2024 03:14:18 +0300 Subject: [PATCH 5/5] Code fixes --- src/object/background.cpp | 6 +++--- src/object/background.hpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/object/background.cpp b/src/object/background.cpp index 30baa0fb6b6..4a94a075127 100644 --- a/src/object/background.cpp +++ b/src/object/background.cpp @@ -104,8 +104,8 @@ static SpritePtr load_background_sprite(const std::string& image_path) return SpriteManager::current()->create(image_path); // Search for a fallback image in fallback_paths. - const std::string& default_dir = "images/background/"; - const std::string& default_dir2 = "/images/background/"; + static const std::string default_dir = "images/background/"; + static const std::string default_dir2 = "/images/background/"; std::string new_path = image_path; if (image_path.substr(0, default_dir.length()) == default_dir) new_path.erase(0, default_dir.length()); @@ -568,7 +568,7 @@ Background::set_bottom_image_action(const std::string& action) } void -Background::set_image_actions(const std::string& action) +Background::set_all_image_actions(const std::string& action) { set_top_image_action(action); set_image_action(action); diff --git a/src/object/background.hpp b/src/object/background.hpp index 8c7a9273cc5..1f3ce4480c5 100644 --- a/src/object/background.hpp +++ b/src/object/background.hpp @@ -150,7 +150,7 @@ class Background final : public GameObject * Sets the sprite action for all images (top, middle and bottom). * @param string $action */ - void set_image_actions(const std::string& action); + void set_all_image_actions(const std::string& action); private: enum Alignment {