diff --git a/demo/box/Makefile b/demo/box/Makefile index 240b0bd..3cd1431 100644 --- a/demo/box/Makefile +++ b/demo/box/Makefile @@ -58,9 +58,7 @@ $(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h $(SB_SRC_DIR)extension.o: $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp Log.hpp) $(SB_SRC_DIR)Node.o: $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp Log.hpp) -$(SB_SRC_DIR)Sprite.o: $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp Log.hpp) -$(SB_SRC_DIR)Game.o: $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \ - Delegate.hpp Audio.hpp Log.hpp) +$(SB_SRC_DIR)Game.o: $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Recorder.hpp Input.hpp Configuration.hpp Delegate.hpp Audio.hpp Log.hpp) $(SB_SRC_DIR)Animation.o: $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp) $(SB_SRC_DIR)Recorder.o: $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp) $(SB_SRC_DIR)Input.o: $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp) diff --git a/demo/browser_webcam_test/Makefile b/demo/browser_webcam_test/Makefile index 81e3797..166d7a6 100644 --- a/demo/browser_webcam_test/Makefile +++ b/demo/browser_webcam_test/Makefile @@ -56,9 +56,7 @@ $(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h $(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp Log.hpp) $(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp Log.hpp) -$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp Log.hpp) -$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \ - Delegate.hpp Audio.hpp Log.hpp) +$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Recorder.hpp Input.hpp Configuration.hpp Delegate.hpp Audio.hpp Log.hpp) $(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp) $(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp) $(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp) diff --git a/demo/camera/Makefile b/demo/camera/Makefile index 269f2f9..cb9532d 100644 --- a/demo/camera/Makefile +++ b/demo/camera/Makefile @@ -64,9 +64,7 @@ $(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h $(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp Log.hpp) $(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp Log.hpp) -$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp Log.hpp) -$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \ - Delegate.hpp Audio.hpp Log.hpp) +$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Recorder.hpp Input.hpp Configuration.hpp Delegate.hpp Audio.hpp Log.hpp) $(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp) $(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp) $(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp) diff --git a/demo/fill_screen/Makefile b/demo/fill_screen/Makefile index 6b4c418..5881c7f 100644 --- a/demo/fill_screen/Makefile +++ b/demo/fill_screen/Makefile @@ -56,8 +56,7 @@ $(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h $(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp Log.hpp) $(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp Log.hpp) -$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp Log.hpp) -$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp Delegate.hpp Audio.hpp Log.hpp) +$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Recorder.hpp Input.hpp Configuration.hpp Delegate.hpp Audio.hpp Log.hpp) $(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp) $(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp) $(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp) diff --git a/demo/squircle/Makefile b/demo/squircle/Makefile index abd114a..541d445 100644 --- a/demo/squircle/Makefile +++ b/demo/squircle/Makefile @@ -64,9 +64,7 @@ $(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h $(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp) $(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp) -$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp) -$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \ - Delegate.hpp Audio.hpp) +$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Recorder.hpp Input.hpp Configuration.hpp Delegate.hpp Audio.hpp) $(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp) $(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp) $(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp) diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 44c2a32..7ae4f3a 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -79,7 +79,7 @@ void Configuration::set_defaults() {"mp4-pixel-format", "yuv444p"} }; config["animation"] = { - {"all-frames-frameset-name", "all"} + {"all frames frameset name", "all"} }; config["log"] = { {"enabled", false}, diff --git a/src/Configuration.hpp b/src/Configuration.hpp index 399cc01..a11cf92 100644 --- a/src/Configuration.hpp +++ b/src/Configuration.hpp @@ -81,13 +81,10 @@ public: nlohmann::json& operator[](const std::string& key); /*! - * Get a read-only JSON object corresponding to a key in configuration. + * Get a read-only JSON object reference to the specified keys, each given as a separate argument. If no keys are given, + * a reference to the entire configuration JSON object is returned. * - * The JSON object's value can be used directly if it can be implictly type-cast. Otherwise, use the JSON object's - * get method with a template parameter. See https://nlohmann.github.io/json/api/basic_json/ for further information. - * - * @param key Top level key corresponding to a section of the SPACEBOX configuration JSON - * @return Read-only JSON object + * @return read-only JSON object reference */ const nlohmann::json& operator[](const std::string& key) const; @@ -114,8 +111,8 @@ public: * @param keys hierarchy of keys used to look up a specific value in the config JSON * @return read-only reference to value specified by keys */ - template - const ReturnType& operator()(const Key&... keys) const + template + const nlohmann::json& operator()(const Key&... keys) const { return access(config, keys...); } @@ -212,7 +209,7 @@ namespace std::filesystem namespace std { /*! - * Add the entire JSON when the stream operator is called. + * Stream the entire JSON when the stream operator is called. * * @param out Output stream * @param configuration Configuration object being output to the stream @@ -220,3 +217,10 @@ namespace std */ std::ostream& operator<<(std::ostream& out, const Configuration& configuration); } + +/* Add Configuration class to the sb namespace. This should be the default location, but Configuration is left in the global namespace + * for backward compatibility. */ +namespace sb +{ + using ::Configuration; +} diff --git a/src/Game.hpp b/src/Game.hpp index 88ef77c..c924365 100644 --- a/src/Game.hpp +++ b/src/Game.hpp @@ -46,7 +46,6 @@ #include "Configuration.hpp" #include "Delegate.hpp" #include "Recorder.hpp" -#include "Sprite.hpp" #include "Audio.hpp" #include "Log.hpp" #include "filesystem.hpp" diff --git a/src/Pixels.hpp b/src/Pixels.hpp index bd463ea..96dbb53 100644 --- a/src/Pixels.hpp +++ b/src/Pixels.hpp @@ -22,8 +22,6 @@ #include "extension.hpp" #include "math.hpp" -class Sprite; - struct Pixels { @@ -39,8 +37,6 @@ struct Pixels Pixels(SDL_Renderer*, SDL_Texture* texture, const Box&); Pixels(SDL_Renderer*, SDL_Texture* texture); Pixels(SDL_Renderer*); - Pixels(Sprite&); - Pixels(Sprite&, const Box&); int get_bytes_per_row() const; Color get(int x, int y); void set(const SDL_Color&, int x, int y); diff --git a/src/Recorder.hpp b/src/Recorder.hpp index 4f984a5..7238ba5 100644 --- a/src/Recorder.hpp +++ b/src/Recorder.hpp @@ -26,6 +26,7 @@ #include "json/json.hpp" #include "filesystem.hpp" #include "Node.hpp" +#include "Configuration.hpp" #include "Animation.hpp" #include "Log.hpp" diff --git a/src/Segment.hpp b/src/Segment.hpp index ab1f785..cb0db92 100644 --- a/src/Segment.hpp +++ b/src/Segment.hpp @@ -18,7 +18,6 @@ #include "glm/vec2.hpp" class Box; -class Sprite; class Segment { @@ -33,7 +32,6 @@ public: Segment(); Segment(const glm::vec2&); Segment(const Box&, const Box&); - Segment(const Sprite&, const Sprite&); glm::vec2 start() const; void start(const glm::vec2&); glm::vec2 end() const; diff --git a/src/Sprite.cpp b/src/Sprite.cpp deleted file mode 100644 index c4cbcdd..0000000 --- a/src/Sprite.cpp +++ /dev/null @@ -1,1049 +0,0 @@ -#include "Game.hpp" -#include "Sprite.hpp" - -Sprite::Sprite() : Sprite(nullptr) {} - -Sprite::Sprite(Node* parent) : - Node(parent), current_frameset_name(configuration()["animation"]["all-frames-frameset-name"]) -{ - add_frameset(current_frameset_name); - frame_animation.play(); -} - -Sprite::Sprite(Node* parent, std::string path) : Sprite(parent) -{ - associate(path); -} - -void Sprite::reset() -{ - Node::reset(); - activate(); - wipe_animation.reset(); - unhide(); -} - -void Sprite::associate(std::string path) -{ - if (fs::is_regular_file(path)) - { - frame_paths.push_back(fs::path(path)); - } - else if (fs::is_directory(path)) - { - fs::directory_iterator directory(path); - std::vector paths; - std::copy(directory, fs::directory_iterator(), std::back_inserter(paths)); - std::sort(paths.begin(), paths.end()); - for (const fs::path& name : paths) - { - frame_paths.push_back(name); - } - } - else - { - std::ostringstream message; - message << "invalid path " << path; - sb::Log::log(message, sb::Log::Level::ERROR); - } -} - -void Sprite::load() -{ - for (const fs::path &path : frame_paths) - { - load_file(path); - } - for (Child& child : children) - { - child.sprite.load(); - } -} - -void Sprite::load_file(fs::path path) -{ - Game *game = get_root(); - const char* previous_scale_quality = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, scale_quality.c_str()); - SDL_Texture *base = IMG_LoadTexture(game->renderer, path.string().c_str()), *texture; - if (texture_access == SDL_TEXTUREACCESS_TARGET) - { - texture = sb::duplicate_texture(get_renderer(), base); - SDL_DestroyTexture(base); - } - else - { - texture = base; - } - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, previous_scale_quality); - if (not texture) - { - sb::Log::sdl_error("Could not load image"); - } - else - { - add_frames(texture); - } -} - -void Sprite::add_frames(SDL_Texture* frame) -{ - bool preserve_center = frames.size() > 0; - frames.push_back(frame); - Frameset& all_frames_frameset = get_all_frames_frameset(); - all_frames_frameset.clear(); - for (std::size_t ii = 0; ii < frames.size(); ii++) - { - all_frames_frameset.add_frame_indicies(ii); - } - for (auto& [name, frameset] : framesets) - { - frameset.set_size(); - } - update_size(preserve_center); -} - -void Sprite::add_frames(const std::vector& frames) -{ - for (SDL_Texture* frame : frames) - { - add_frames(frame); - } -} - -const std::vector& Sprite::get_frames() const -{ - return frames; -} - -Sprite::Frameset& Sprite::get_all_frames_frameset() -{ - return framesets[configuration()["animation"]["all-frames-frameset-name"]]; -} - -Sprite::Frameset& Sprite::add_frameset(std::string name) -{ - if (framesets.find(name) == framesets.end()) - { - framesets[name] = Frameset(this); - } - return framesets[name]; -} - -Sprite::Frameset& Sprite::set_frameset(std::string name) -{ - current_frameset_name = name; - frame_animation.set_frame_length(get_current_frameset().get_frame_length()); - if (is_loaded()) - { - update_size(true); - } - return get_current_frameset(); -} - -Sprite::Frameset& Sprite::get_current_frameset() -{ - return framesets.at(current_frameset_name); -} - -const Sprite::Frameset& Sprite::get_current_frameset() const -{ - return framesets.at(current_frameset_name); -} - -void Sprite::set_frame_length(float length) -{ - get_current_frameset().set_frame_length(length); -} - -SDL_Texture* Sprite::get_current_frame() const -{ - if (frames.size() == 0) - { - return nullptr; - } - else - { - return frames[get_current_frameset().get_current_frame_index()]; - } -} - -const Box& Sprite::get_box(int index) const -{ - return get_boxes()[index]; -} - -const std::vector& Sprite::get_boxes() const -{ - return boxes; -} - -void Sprite::add_box(glm::vec2 position, bool absolute) -{ - if (!absolute) - { - position += get_nw(); - } - boxes.emplace_back(glm::vec2(position.x, position.y), glm::vec2(get_w(), get_h())); -} - -void Sprite::update_size(bool preserve_center) -{ - for (std::size_t ii = 0; ii < boxes.size(); ii++) - { - boxes[ii].size(get_current_frameset().get_size(), preserve_center); - if (scale != 1) - { - boxes[ii].scale(scale, preserve_center); - } - } -} - -void Sprite::set_scale(float s) -{ - scale = s; - update_size(true); -} - -void Sprite::set_scale_quality(const std::string& quality) -{ - scale_quality = quality; -} - -float Sprite::get_scale() const -{ - return scale; -} - -bool Sprite::is_loaded() const -{ - return !frames.empty(); -} - -void Sprite::unload() -{ - while (!frames.empty()) - { - if (!leave_memory_allocated) - { - SDL_DestroyTexture(frames.back()); - } - frames.pop_back(); - } - boxes = {{{0, 0}, {0, 0}}}; -} - -void Sprite::advance_frame() -{ - get_current_frameset().step(); -} - -void Sprite::hide() -{ - hidden = true; - for (Child& child : children) - { - child.sprite.hide(); - } -} - -void Sprite::unhide() -{ - hidden = false; - for (Child& child : children) - { - child.sprite.unhide(); - } -} - -void Sprite::toggle_hidden() -{ - if (is_hidden()) - { - unhide(); - } - else - { - hide(); - } -} - -bool Sprite::is_hidden() const -{ - return hidden; -} - -void Sprite::set_step(glm::vec2 s) -{ - step.x = s.x; - step.y = s.y; -} - -void Sprite::set_alpha_mod(Uint8 mod) -{ - alpha_mod = mod; -} - -Uint8 Sprite::get_alpha_mod() const -{ - return alpha_mod; -} - -void Sprite::set_color_mod(const SDL_Color& color) -{ - color_mod = color; -} - -const SDL_Color& Sprite::get_color_mod() const -{ - return color_mod; -} - -float Sprite::get_w() const -{ - return get_box().width(); -} - -float Sprite::get_h() const -{ - return get_box().height(); -} - -glm::vec2 Sprite::get_size() const -{ - return get_box().size(); -} - -float Sprite::get_top(int index) const -{ - return get_box(index).top(); -} - -float Sprite::get_right(int index) const -{ - return get_box(index).right(); -} - -float Sprite::get_bottom(int index) const -{ - return get_box(index).bottom(); -} - -float Sprite::get_left(int index) const -{ - return get_box(index).left(); -} - -float Sprite::get_center_x(int index) const -{ - return get_box(index).cx(); -} - -float Sprite::get_center_y(int index) const -{ - return get_box(index).cy(); -} - -glm::vec2 Sprite::get_nw(int index) const -{ - return get_box(index).nw(); -} - -glm::vec2 Sprite::get_north(int index) const -{ - return get_box(index).north(); -} - -glm::vec2 Sprite::get_ne(int index) const -{ - return get_box(index).ne(); -} - -glm::vec2 Sprite::get_east(int index) const -{ - return get_box(index).east(); -} - -glm::vec2 Sprite::get_se(int index) const -{ - return get_box(index).se(); -} - -glm::vec2 Sprite::get_south(int index) const -{ - return get_box(index).south(); -} - -glm::vec2 Sprite::get_sw(int index) const -{ - return get_box(index).sw(); -} - -glm::vec2 Sprite::get_west(int index) const -{ - return get_box(index).west(); -} - -glm::vec2 Sprite::get_center(int index) const -{ - return get_box(index).center(); -} - -void Sprite::set_top(float top) -{ - move({0, top - get_top()}); -} - -void Sprite::set_right(float right) -{ - move({right - get_right(), 0}); -} - -void Sprite::set_bottom(float bottom) -{ - move({0, bottom - get_bottom()}); -} - -void Sprite::set_left(float left) -{ - move({left - get_left(), 0}); -} - -void Sprite::set_center_x(float x) -{ - move({x - get_center_x(), 0}); -} - -void Sprite::set_center_y(float y) -{ - move({0, y - get_center_y()}); -} - -void Sprite::set_nw(const glm::vec2& nw) -{ - move(nw - get_nw()); -} - -void Sprite::set_north(const glm::vec2& north) -{ - move(north - get_north()); -} - -void Sprite::set_ne(const glm::vec2& ne) -{ - move(ne - get_ne()); -} - -void Sprite::set_se(const glm::vec2& se) -{ - move(se - get_se()); -} - -void Sprite::set_south(const glm::vec2& south) -{ - move(south - get_south()); -} - -void Sprite::set_sw(const glm::vec2& sw) -{ - move(sw - get_sw()); -} - -void Sprite::set_west(const glm::vec2& west) -{ - move(west - get_west()); -} - -void Sprite::set_center(const glm::vec2& center) -{ - move(center - get_center()); -} - -void Sprite::add_wrap(bool x, bool y) -{ - add_wrap(x, y, get_display().window_box()); -} - -void Sprite::add_wrap(bool x, bool y, Box frame) -{ - wrap = {x, y}; - int original_box_count = boxes.size(); - for (int ii = 0; ii < original_box_count; ii++) - { - if (x) - { - add_box({frame.width(), 0}); - } - if (y) - { - add_box({0, frame.height()}); - } - if (x && y) - { - add_box({frame.width(), frame.height()}); - } - } - wrap_frame = frame; -} - -void Sprite::add_hue_shift_frames(int count) -{ - float step = 360 / (count + 1); - SDL_Texture* base = get_current_frame(); - for (float offset = step; offset <= 359.9; offset += step) - { - add_frames(sb::get_hue_shifted_texture(get_renderer(), base, offset)); - } -} - -glm::vec2 Sprite::move(const glm::vec2& delta) -{ - for (Box& box : boxes) - { - box.move(delta); - } - if (wrap.x) - { - if (get_right() > wrap_frame.right()) - { - move({-wrap_frame.width(), 0}); - } - else if (get_right() < wrap_frame.left()) - { - move({wrap_frame.width(), 0}); - } - } - if (wrap.y) - { - if (get_bottom() > wrap_frame.bottom()) - { - move({0, -wrap_frame.height()}); - } - else if (get_bottom() < wrap_frame.top()) - { - move({0, wrap_frame.height()}); - } - } - return delta; -} - -glm::vec2 Sprite::move_weighted(const glm::vec2& delta) -{ - glm::vec2 delta_weighted = get_root()->weight(delta); - move(delta_weighted); - return delta_weighted; -} - -bool Sprite::collide(const glm::vec2& point, bool all) const -{ - if (!all) - { - return get_box().collide(point); - } - else - { - for (const Box& box : boxes) - { - if (box.collide(point)) - { - return true; - } - } - return false; - } -} - -bool Sprite::collide(const Segment& segment, glm::vec2* intersection, bool all) const -{ - if (!all) - { - return get_box().collide(segment, intersection); - } - else - { - for (const Box& box : boxes) - { - if (box.collide(segment, intersection)) - { - return true; - } - } - return false; - } -} - -bool Sprite::collide(const Segment& segment, glm::vec2& intersection, bool all) const -{ - return collide(segment, &intersection, all); -} - -bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_Texture* other_texture) const -{ - Box o; - if (precise) - { - int texture_access; - SDL_QueryTexture(get_current_frame(), nullptr, &texture_access, nullptr, nullptr); - if (texture_access != SDL_TEXTUREACCESS_TARGET) - { - SDL_LogWarn(SDL_LOG_CATEGORY_ERROR, - "can't do precise collision detection on texture without target access"); - precise = false; - } - else if (other_texture != nullptr) - { - SDL_QueryTexture(other_texture, nullptr, &texture_access, nullptr, nullptr); - if (texture_access != SDL_TEXTUREACCESS_TARGET) - { - SDL_LogWarn(SDL_LOG_CATEGORY_ERROR, - "can't use other texture in precise collision detection without target access"); - other_texture = nullptr; - } - } - if (precise && overlap == nullptr) - { - overlap = &o; - } - } - for (auto ii = 0; ii < static_cast(get_boxes().size()); ii++) - { - if (get_box(ii).collide(box, overlap)) - { - if (precise) - { - bool collision_detected = false; - SDL_Texture* collision_check_frame; - if (get_scale() == 1) - { - collision_check_frame = get_current_frame(); - } - else - { - collision_check_frame = sb::duplicate_texture( - const_cast(get_renderer()), get_current_frame(), get_box(ii).size()); - } - Pixels region_pixels = Pixels( - const_cast(get_renderer()), collision_check_frame, overlap->stamp(-get_nw(ii))); - if (other_texture == nullptr) - { - for (int x = 0; x < region_pixels.rect.w; x++) - { - for (int y = 0; y < region_pixels.rect.h; y++) - { - if (region_pixels.get(x, y).a > 0) - { - collision_detected = true; - break; - } - } - } - } - else - { - Pixels other_region_pixels = Pixels( - const_cast(get_renderer()), other_texture, overlap->stamp(-box.nw())); - for (int x = 0; x < region_pixels.rect.w && x < other_region_pixels.rect.w; x++) - { - for (int y = 0; y < region_pixels.rect.h && y < other_region_pixels.rect.h; y++) - { - if (region_pixels.get(x, y).a > 0 && other_region_pixels.get(x, y).a > 0) - { - collision_detected = true; - break; - } - } - } - } - if (get_scale() != 1) - { - SDL_DestroyTexture(collision_check_frame); - } - if (collision_detected) - { - return true; - } - } - else - { - return true; - } - } - if (!all) - { - break; - } - } - return false; -} - -bool Sprite::collide(const Box& box, Box& overlap, bool precise, bool all) const -{ - return collide(box, precise, &overlap, all); -} - -bool Sprite::collide(const Sprite& sprite, bool precise, Box* overlap, bool all, bool all_other) const -{ - SDL_Texture* other_sprite_collision_check_texture = nullptr; - int limit; - bool collision = false; - if (all_other) - { - limit = sprite.get_boxes().size(); - } - else - { - limit = 1; - } - for (int ii = 0; ii < limit; ii++) - { - if (precise) - { - if (sprite.get_scale() == 1) - { - other_sprite_collision_check_texture = sprite.get_current_frame(); - } - else - { - other_sprite_collision_check_texture = sb::duplicate_texture( - const_cast(get_renderer()), sprite.get_current_frame(), sprite.get_box(ii).size()); - } - } - if (collide(sprite.get_box(ii), precise, overlap, all, other_sprite_collision_check_texture)) - { - collision = true; - break; - } - } - if (sprite.get_scale() != 1) - { - SDL_DestroyTexture(other_sprite_collision_check_texture); - } - return collision; -} - -bool Sprite::collide(const Sprite& sprite, Box& overlap, bool precise, bool all, bool all_other) const -{ - return collide(sprite, precise, &overlap, all, all_other); -} - -void Sprite::wipe(float delay) -{ - wipe_blinds = sb::get_blinds_boxes(get_size()); - if (wipe_increment < 0) - { - wipe_index = static_cast(wipe_blinds.size() - 1); - } - else - { - wipe_index = 0; - } - wipe_animation.play(delay); - for (Child& child : children) - { - child.sprite.wipe(delay); - } -} - -void Sprite::advance_wipe_frame() -{ - wipe_index += wipe_increment; - if (wipe_index < 0 || wipe_index >= static_cast(wipe_blinds.size())) - { - if (wipe_index < 0) - { - wipe_index = static_cast(wipe_blinds.size() - 1); - hide(); - } - else - { - wipe_index = 0; - } - wipe_animation.reset(); - } -} - -const std::vector& Sprite::get_current_wipe_blinds() const -{ - return wipe_blinds[wipe_index]; -} - -void Sprite::reverse_wipe_direction() -{ - wipe_increment *= -1; -} - -Sprite& Sprite::insert_child(std::string name, std::list::iterator position) -{ - children.emplace(position, name, this); - return get_child(name); -} - -Sprite& Sprite::insert_child(std::string name, std::string before) -{ - return insert_child(name, std::find(children.begin(), children.end(), before)); -} - -Sprite& Sprite::insert_child(std::string name, int index) -{ - auto position = children.begin(); - for (int ii = 0; position != children.end(); ii++, position++) - { - if (ii == index) - { - break; - } - } - return insert_child(name, position); -} - -Sprite& Sprite::insert_child(std::string name) -{ - return insert_child(name, children.size()); -} - -Sprite& Sprite::get_child(std::string name) -{ - auto position = std::find(children.begin(), children.end(), name); - if (position == children.end()) - { - throw std::runtime_error("child not found"); - } - return position->sprite; -} - -bool Sprite::has_child(std::string name) const -{ - return std::find(children.begin(), children.end(), name) != children.end(); -} - -void Sprite::remove_child(std::string name) -{ - auto position = std::find(children.begin(), children.end(), name); - if (position != children.end()) - { - children.erase(position); - } -} - -void Sprite::set_draw_children_on_frame(bool on_frame) -{ - draw_children_on_frame = on_frame; -} - -void Sprite::update(float timestamp, const std::vector& subsections) -{ - if (is_active()) - { - if (step != glm::vec2(0, 0)) - { - move_weighted(step); - } - frame_animation.update(timestamp); - blink_animation.update(timestamp); - wipe_animation.update(timestamp); - toggle_hidden_animation.update(timestamp); - SDL_Texture* texture = get_current_frame(); - if (is_loaded() && !is_hidden() && get_current_frameset().get_frame_count()) - { - SDL_Renderer* renderer = get_root()->renderer; - SDL_SetTextureAlphaMod(texture, alpha_mod); - SDL_SetTextureColorMod(texture, color_mod.r, color_mod.g, color_mod.b); - SDL_SetRenderTarget(renderer, get_canvas()); - if (wrap.x || wrap.y) - { - SDL_Rect wrap_frame_rect = wrap_frame; - SDL_RenderSetClipRect(renderer, &wrap_frame_rect); - } - for (std::size_t box_ii = 0; box_ii < boxes.size(); box_ii++) - { - if (subsections.size() == 0 && !wipe_animation.playing(false)) - { - SDL_RenderCopyF(renderer, texture, nullptr, &boxes[box_ii]); - } - else - { - if (wipe_animation.playing(false)) - { - for (const Box& blind : get_current_wipe_blinds()) - { - render_subsection(renderer, texture, blind, get_box(box_ii)); - } - } - for (const Box& subsection : subsections) - { - render_subsection(renderer, texture, subsection, get_box(box_ii)); - } - } - } - if (wrap.x || wrap.y) - { - SDL_RenderSetClipRect(renderer, nullptr); - } - } - for (Child& child : children) - { - if (draw_children_on_frame) - { - child.sprite.set_canvas(texture); - } - else - { - child.sprite.set_canvas(get_canvas()); - child_relative_position = child.sprite.get_nw(); - child.sprite.move(get_nw()); - } - child.sprite.update(timestamp); - if (!draw_children_on_frame) - { - child.sprite.set_nw(child_relative_position); - } - } - } -} - -void Sprite::update(float timestamp) -{ - update(timestamp, {}); -} - -void Sprite::render_subsection(SDL_Renderer* renderer, SDL_Texture* texture, const Box& subsection, const Box& box) -{ - bottom_save = std::round(subsection.bottom()); - subsection_int_rect = SDL_Rect(subsection); - subsection_int_rect.y += bottom_save - (subsection_int_rect.y + subsection_int_rect.h); - subsection_destination = subsection_int_rect; - subsection_destination.x += box.left(); - subsection_destination.y += box.top(); - if (get_scale() != 1) - { - unscaled_subsection = subsection; - unscaled_subsection.nw(unscaled_subsection.nw() / get_scale()); - unscaled_subsection.size(unscaled_subsection.size() / get_scale()); - subsection_int_rect = unscaled_subsection; - } - SDL_RenderCopy(renderer, texture, &subsection_int_rect, &subsection_destination); -} - -void Sprite::set_to_leave_memory_allocated() -{ - leave_memory_allocated = true; -} - -void Sprite::set_to_deallocate_memory() -{ - leave_memory_allocated = false; -} - -Sprite::Frameset::Frameset() : Frameset(NULL) {} - -Sprite::Frameset::Frameset(Sprite* sprite) : sprite(sprite) {} - -void Sprite::Frameset::add_frame_indicies(int index) -{ - order.push_back(index); - set_size(); -} - -void Sprite::Frameset::set_frame_length(float length) -{ - frame_length = length; - if (&sprite->get_current_frameset() == this) - { - sprite->frame_animation.set_frame_length(length); - } -} - -float Sprite::Frameset::get_frame_length() const -{ - return frame_length; -} - -void Sprite::Frameset::reset() -{ - set_order_index(0); -} - -void Sprite::Frameset::clear() -{ - order.clear(); - reset(); -} - -int Sprite::Frameset::get_order_index() const -{ - return order_index; -} - -void Sprite::Frameset::set_order_index(int index) -{ - order_index = index; -} - -int Sprite::Frameset::get_current_frame_index() const -{ - return order[get_order_index()]; -} - -glm::vec2 Sprite::Frameset::measure() const -{ - glm::vec2 s(0, 0); - int w, h; - for (std::size_t index : order) - { - if (index < sprite->get_frames().size()) - { - SDL_QueryTexture(sprite->get_frames()[index], nullptr, nullptr, &w, &h); - s.x = std::max(static_cast(w * sprite->get_scale()), s.x); - s.y = std::max(static_cast(h * sprite->get_scale()), s.y); - } - } - return s; -} - -void Sprite::Frameset::set_size() -{ - set_size(measure()); -} - -void Sprite::Frameset::set_size(const glm::vec2& s) -{ - size = s; -} - -const glm::vec2& Sprite::Frameset::get_size() const -{ - return size; -} - -void Sprite::Frameset::step() -{ - if (order.size() > 0) - { - increment_index(); - } -} - -void Sprite::Frameset::increment_index() -{ - increment_index(reversed ? -1 : 1); -} - -void Sprite::Frameset::increment_index(int increment) -{ - set_order_index((order_index + increment) % order.size()); -} - -int Sprite::Frameset::get_frame_count() const -{ - return order.size(); -} - -void Sprite::Frameset::reverse() -{ - reversed = !reversed; -} - -Pixels::Pixels(Sprite& sprite) : Pixels(sprite.get_renderer(), sprite.get_current_frame()) {} -Pixels::Pixels(Sprite& sprite, const Box& box) : Pixels(sprite.get_renderer(), sprite.get_current_frame(), box) {} - -Segment::Segment(const Sprite& start, const Sprite& end) : Segment(start.get_center(), end.get_center()) {} diff --git a/src/Sprite.hpp b/src/Sprite.hpp deleted file mode 100644 index e82e86b..0000000 --- a/src/Sprite.hpp +++ /dev/null @@ -1,213 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include "SDL.h" -#include "SDL_image.h" -#include "Node.hpp" -#include "Box.hpp" -#include "Animation.hpp" -#include "Color.hpp" -#include "Log.hpp" - -class Game; - -class Sprite : public Node -{ - -public: - - class Frameset; - class Child; - - std::vector frames; - std::vector frame_paths; - std::vector boxes = {{{0, 0}, {0, 0}}}; - Animation frame_animation = Animation(&Sprite::advance_frame, this), - blink_animation = Animation(&Sprite::toggle_hidden, this, 500), - wipe_animation = Animation(&Sprite::advance_wipe_frame, this, 40), - toggle_hidden_animation = Animation(&Sprite::toggle_hidden, this); - glm::vec2 step = {0, 0}, child_relative_position; - float scale = 1.0f, bottom_save; - std::string scale_quality = "nearest"; - std::uint8_t alpha_mod = 255; - SDL_Color color_mod = {255, 255, 255, 255}; - std::map framesets; - std::string current_frameset_name; - glm::bvec2 wrap = {false, false}; - int texture_access = SDL_TEXTUREACCESS_TARGET, wipe_index = 0, wipe_increment = -1; - Box wrap_frame, unscaled_subsection; - bool leave_memory_allocated = false, hidden = false, draw_children_on_frame = true, draw_floating = true; - std::vector> wipe_blinds; - SDL_Rect subsection_int_rect, subsection_destination; - std::list children = {}; - - Sprite(); - Sprite(Node*); - Sprite(Node*, std::string); - virtual void reset(); - virtual void associate(std::string); - virtual void load(); - void load_file(fs::path); - void add_frames(SDL_Texture*); - void add_frames(const std::vector&); - const std::vector& get_frames() const; - Frameset& get_all_frames_frameset(); - Frameset& add_frameset(std::string); - virtual Frameset& set_frameset(std::string); - Frameset& get_current_frameset(); - void set_frame_length(float); - const Frameset& get_current_frameset() const; - SDL_Texture* get_current_frame() const; - const Box& get_box(int = 0) const; - const std::vector& get_boxes() const; - void add_box(glm::vec2, bool = false); - void update_size(bool = false); - void set_scale(float); - void set_scale_quality(const std::string&); - float get_scale() const; - bool is_loaded() const; - virtual void unload(); - void advance_frame(); - void hide(); - void unhide(); - void toggle_hidden(); - bool is_hidden() const; - void set_step(glm::vec2); - void set_alpha_mod(Uint8); - Uint8 get_alpha_mod() const; - void set_color_mod(const SDL_Color&); - const SDL_Color& get_color_mod() const; - float get_w() const; - float get_h() const; - glm::vec2 get_size() const; - float get_top(int = 0) const; - float get_right(int = 0) const; - float get_bottom(int = 0) const; - float get_left(int = 0) const; - float get_center_x(int = 0) const; - float get_center_y(int = 0) const; - glm::vec2 get_nw(int = 0) const; - glm::vec2 get_north(int = 0) const; - glm::vec2 get_ne(int = 0) const; - glm::vec2 get_east(int = 0) const; - glm::vec2 get_se(int = 0) const; - glm::vec2 get_south(int = 0) const; - glm::vec2 get_sw(int = 0) const; - glm::vec2 get_west(int = 0) const; - glm::vec2 get_center(int = 0) const; - void set_top(float); - void set_right(float); - void set_bottom(float); - void set_left(float); - void set_center_x(float); - void set_center_y(float); - void set_nw(const glm::vec2&); - void set_north(const glm::vec2&); - void set_ne(const glm::vec2&); - void set_se(const glm::vec2&); - void set_south(const glm::vec2&); - void set_sw(const glm::vec2&); - void set_west(const glm::vec2&); - void set_center(const glm::vec2&); - void add_wrap(bool, bool); - void add_wrap(bool, bool, Box); - void add_hue_shift_frames(int); - virtual glm::vec2 move(const glm::vec2&); - virtual glm::vec2 move_weighted(const glm::vec2&); - bool collide(const glm::vec2&, bool = false) const; - bool collide(const Segment&, glm::vec2* = NULL, bool = false) const; - bool collide(const Segment&, glm::vec2&, bool = false) const; - bool collide(const Box&, bool = false, Box* = NULL, bool = false, SDL_Texture* = NULL) const; - bool collide(const Box&, Box&, bool = false, bool = false) const; - bool collide(const Sprite&, bool = false, Box* = NULL, bool = false, bool = false) const; - bool collide(const Sprite&, Box&, bool = false, bool = false, bool = false) const; - void wipe(float = 0.0f); - void advance_wipe_frame(); - const std::vector& get_current_wipe_blinds() const; - void reverse_wipe_direction(); - Sprite& insert_child(std::string, std::list::iterator); - Sprite& insert_child(std::string, std::string); - Sprite& insert_child(std::string, int); - Sprite& insert_child(std::string); - Sprite& get_child(std::string); - bool has_child(std::string) const; - void remove_child(std::string); - void set_draw_children_on_frame(bool); - virtual void update(float timestamp, const std::vector&); - virtual void update(float timestamp); - void render_subsection(SDL_Renderer*, SDL_Texture*, const Box&, const Box&); - void set_to_leave_memory_allocated(); - void set_to_deallocate_memory(); - virtual std::string class_name() const { return "Sprite"; } - -}; - -class Sprite::Child -{ - -public: - - std::string name; - Sprite sprite; - - Child(std::string name, Node* parent) : name(name), sprite(Sprite(parent)) {} - - inline bool operator==(const std::string& name) const - { - return this->name == name; - } - -}; - -class Sprite::Frameset -{ - -public: - - Sprite* sprite; - std::vector order; - int order_index = 0; - float frame_length = 0; - bool reversed = false; - glm::vec2 size = {0, 0}; - - Frameset(); - Frameset(Sprite*); - void add_frame_indicies(int); - void set_frame_length(float); - float get_frame_length() const; - void reset(); - void clear(); - int get_order_index() const; - void set_order_index(int); - int get_current_frame_index() const; - glm::vec2 measure() const; - void set_size(); - void set_size(const glm::vec2&); - const glm::vec2& get_size() const; - void step(); - void increment_index(); - void increment_index(int); - int get_frame_count() const; - void reverse(); - - template - void add_frame_indicies(const std::vector& indicies) - { - for (const N& index : indicies) - { - add_frame_indicies(index); - } - } - -}; - -#include "Pixels.hpp" -#include "extension.hpp"