- optionally preserve center when modifying box size

- sprite scale modifier and scale quality setting
- get filled texture method
- get map keys utility method
This commit is contained in:
Frank DeMarco 2020-07-31 12:10:21 -04:00
parent 16e1cc19d0
commit 555c1e51a3
10 changed files with 114 additions and 26 deletions

View File

@ -10,7 +10,8 @@
config parameters on command line, effects chain, asset dict with metadata, config parameters on command line, effects chain, asset dict with metadata,
move added sprite locations by offset when location is changed, gradients, move added sprite locations by offset when location is changed, gradients,
level select code input, logging, variable screen resolution, debug display, level select code input, logging, variable screen resolution, debug display,
loading wheel animation, shadowed sprite, separate update and draw loading wheel animation, shadowed sprite, separate update and draw, sprite
movement cage
:) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :) :) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :)

View File

@ -47,10 +47,15 @@ glm::vec2 Box::get_size() const
return glm::vec2(get_w(), get_h()); return glm::vec2(get_w(), get_h());
} }
void Box::set_size(const glm::vec2& size) void Box::set_size(const glm::vec2& size, bool preserve_center)
{ {
glm::vec2 center = get_center();
set_w(size.x); set_w(size.x);
set_h(size.y); set_h(size.y);
if (preserve_center)
{
set_center(center);
}
} }
float Box::get_top() const float Box::get_top() const
@ -179,10 +184,15 @@ void Box::clear()
set_size(glm::vec2(0, 0)); set_size(glm::vec2(0, 0));
} }
void Box::scale(float amount) void Box::scale(float amount, bool preserve_center)
{ {
glm::vec2 center = get_center();
set_w(get_w() * amount); set_w(get_w() * amount);
set_h(get_h() * amount); set_h(get_h() * amount);
if (preserve_center)
{
set_center(center);
}
} }
void Box::move(const glm::vec2& delta) void Box::move(const glm::vec2& delta)

View File

@ -23,7 +23,7 @@ struct Box
void set_w(float); void set_w(float);
void set_h(float); void set_h(float);
glm::vec2 get_size() const; glm::vec2 get_size() const;
void set_size(const glm::vec2&); void set_size(const glm::vec2&, bool = false);
float get_top() const; float get_top() const;
float get_right() const; float get_right() const;
float get_bottom() const; float get_bottom() const;
@ -49,7 +49,7 @@ struct Box
SDL_FRect* get_rect(); SDL_FRect* get_rect();
SDL_Rect get_int_rect(); SDL_Rect get_int_rect();
void clear(); void clear();
void scale(float); void scale(float, bool = false);
void move(const glm::vec2&); void move(const glm::vec2&);
std::string get_class_name() { return "Box"; } std::string get_class_name() { return "Box"; }
std::ostream& to_string (std::ostream&) const; std::ostream& to_string (std::ostream&) const;

View File

@ -58,8 +58,8 @@ bool Delegate::compare(SDL_Event& event, const std::vector<std::string>& command
bool Delegate::compare(SDL_Event& event, const std::string& command, bool neutral, bool cancel) bool Delegate::compare(SDL_Event& event, const std::string& command, bool neutral, bool cancel)
{ {
return event.type == command_event_type && return event.type == command_event_type &&
(command == "" || command == *static_cast<std::string*>(event.user.data1)) && (command == "" || command == get_event_command(event)) &&
(neutral || (cancel == *static_cast<bool*>(event.user.data2))); (neutral || (cancel == get_event_cancel_state(event)));
} }
bool Delegate::compare_cancel(SDL_Event& event, const std::string& command) bool Delegate::compare_cancel(SDL_Event& event, const std::string& command)
@ -76,3 +76,13 @@ void Delegate::cancel_propagation()
{ {
cancelling_propagation = true; cancelling_propagation = true;
} }
const std::string& Delegate::get_event_command(SDL_Event& event) const
{
return *static_cast<std::string*>(event.user.data1);
}
bool Delegate::get_event_cancel_state(SDL_Event& event) const
{
return *static_cast<bool*>(event.user.data2);
}

View File

@ -33,6 +33,8 @@ struct Delegate : Node
bool compare_cancel(SDL_Event&, const std::string& = ""); bool compare_cancel(SDL_Event&, const std::string& = "");
bool compare_neutral(SDL_Event&, const std::string& = ""); bool compare_neutral(SDL_Event&, const std::string& = "");
void cancel_propagation(); void cancel_propagation();
const std::string& get_event_command(SDL_Event&) const;
bool get_event_cancel_state(SDL_Event&) const;
template<typename T> template<typename T>
void subscribe(void(T::*f)(SDL_Event&), T* o, int type = command_event_type) void subscribe(void(T::*f)(SDL_Event&), T* o, int type = command_event_type)

View File

@ -23,6 +23,7 @@ struct Node
void set_parent(Node*); void set_parent(Node*);
void activate(); void activate();
void deactivate(); void deactivate();
virtual void reset() { deactivate(); };
bool is_active() const; bool is_active() const;
nlohmann::json& get_configuration(); nlohmann::json& get_configuration();
Delegate& get_delegate(); Delegate& get_delegate();

View File

@ -51,7 +51,10 @@ void Sprite::load()
void Sprite::load_file(fs::path path) void Sprite::load_file(fs::path path)
{ {
Game *game = get_root(); 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 *texture = IMG_LoadTexture(game->renderer, path.string().c_str()); SDL_Texture *texture = IMG_LoadTexture(game->renderer, path.string().c_str());
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, previous_scale_quality);
if (not texture) if (not texture)
{ {
game->print_sdl_error("Could not load image"); game->print_sdl_error("Could not load image");
@ -64,6 +67,7 @@ void Sprite::load_file(fs::path path)
void Sprite::add_frame(SDL_Texture* texture) void Sprite::add_frame(SDL_Texture* texture)
{ {
bool preserve_center = frames.size() > 0;
frames.push_back(texture); frames.push_back(texture);
Frameset& all_frames_frameset = get_all_frames_frameset(); Frameset& all_frames_frameset = get_all_frames_frameset();
all_frames_frameset.clear(); all_frames_frameset.clear();
@ -75,7 +79,7 @@ void Sprite::add_frame(SDL_Texture* texture)
{ {
member.second.set_size(); member.second.set_size();
} }
update_size(); update_size(preserve_center);
} }
Frameset& Sprite::get_all_frames_frameset() Frameset& Sprite::get_all_frames_frameset()
@ -96,7 +100,7 @@ Frameset& Sprite::set_frameset(std::string name)
{ {
current_frameset_name = name; current_frameset_name = name;
frame_animation.set_frame_length(get_current_frameset().get_frame_length()); frame_animation.set_frame_length(get_current_frameset().get_frame_length());
update_size(); update_size(true);
return get_current_frameset(); return get_current_frameset();
} }
@ -119,22 +123,27 @@ void Sprite::add_box(glm::vec2 position, bool absolute)
boxes.emplace_back(glm::vec2(position.x, position.y), glm::vec2(get_w(), get_h())); boxes.emplace_back(glm::vec2(position.x, position.y), glm::vec2(get_w(), get_h()));
} }
void Sprite::update_size() void Sprite::update_size(bool preserve_center)
{ {
for (Box& box : boxes) for (int ii = 0; ii < boxes.size(); ii++)
{ {
box.set_size(get_current_frameset().get_size()); get_box(ii).set_size(get_current_frameset().get_size(), preserve_center);
if (scale != 1)
{
get_box(ii).scale(scale, preserve_center);
}
} }
} }
void Sprite::set_scale(float s) void Sprite::set_scale(float s)
{ {
scale = s; scale = s;
for (auto& member : framesets) update_size(true);
{ }
member.second.set_size(member.second.get_size() * s);
} void Sprite::set_scale_quality(const std::string& quality)
update_size(); {
scale_quality = quality;
} }
float Sprite::get_scale() const float Sprite::get_scale() const
@ -256,6 +265,11 @@ glm::vec2 Sprite::get_east(int index)
return get_box(index).get_east(); return get_box(index).get_east();
} }
glm::vec2 Sprite::get_south(int index)
{
return get_box(index).get_south();
}
glm::vec2 Sprite::get_west(int index) glm::vec2 Sprite::get_west(int index)
{ {
return get_box(index).get_west(); return get_box(index).get_west();
@ -266,6 +280,11 @@ glm::vec2 Sprite::get_center(int index)
return get_box(index).get_center(); return get_box(index).get_center();
} }
void Sprite::set_south(const glm::vec2& south)
{
move(south - get_south(), false);
}
void Sprite::set_nw(const glm::vec2& nw) void Sprite::set_nw(const glm::vec2& nw)
{ {
move(nw - get_nw(), false); move(nw - get_nw(), false);
@ -362,9 +381,9 @@ void Sprite::update()
SDL_Rect wrap_frame_rect = wrap_frame.get_int_rect(); SDL_Rect wrap_frame_rect = wrap_frame.get_int_rect();
SDL_RenderSetClipRect(renderer, &wrap_frame_rect); SDL_RenderSetClipRect(renderer, &wrap_frame_rect);
} }
for (Box& box : boxes) for (int ii = 0; ii < boxes.size(); ii++)
{ {
SDL_RenderCopyF(renderer, texture, NULL, box.get_rect()); SDL_RenderCopyF(renderer, texture, NULL, get_box(ii).get_rect());
} }
if (wrap.x || wrap.y) if (wrap.x || wrap.y)
{ {
@ -400,7 +419,7 @@ float Frameset::get_frame_length() const
void Frameset::reset() void Frameset::reset()
{ {
current_index = 0; set_order_index(0);
} }
void Frameset::clear() void Frameset::clear()
@ -409,9 +428,19 @@ void Frameset::clear()
reset(); reset();
} }
int Frameset::get_order_index() const
{
return order_index;
}
void Frameset::set_order_index(int index)
{
order_index = index;
}
int Frameset::get_current_frame_index() const int Frameset::get_current_frame_index() const
{ {
return order[current_index]; return order[get_order_index()];
} }
glm::vec2 Frameset::measure() const glm::vec2 Frameset::measure() const
@ -469,7 +498,7 @@ void Frameset::increment_index()
void Frameset::increment_index(int increment) void Frameset::increment_index(int increment)
{ {
current_index = (current_index + increment) % order.size(); set_order_index((order_index + increment) % order.size());
} }
int Frameset::get_frame_count() const int Frameset::get_frame_count() const

View File

@ -29,6 +29,7 @@ struct Sprite : Node
bool hidden = false; bool hidden = false;
glm::vec2 step = {0, 0}; glm::vec2 step = {0, 0};
float scale = 1; float scale = 1;
std::string scale_quality = "nearest";
Uint8 alpha_mod = 255; Uint8 alpha_mod = 255;
std::map<std::string, Frameset> framesets; std::map<std::string, Frameset> framesets;
std::string current_frameset_name; std::string current_frameset_name;
@ -48,8 +49,9 @@ struct Sprite : Node
Frameset& get_current_frameset(); Frameset& get_current_frameset();
Box& get_box(int = 0); Box& get_box(int = 0);
void add_box(glm::vec2, bool = false); void add_box(glm::vec2, bool = false);
void update_size(); void update_size(bool = false);
void set_scale(float); void set_scale(float);
void set_scale_quality(const std::string&);
float get_scale() const; float get_scale() const;
bool is_loaded() const; bool is_loaded() const;
void unload(); void unload();
@ -72,10 +74,12 @@ struct Sprite : Node
glm::vec2 get_north(int = 0); glm::vec2 get_north(int = 0);
glm::vec2 get_ne(int = 0); glm::vec2 get_ne(int = 0);
glm::vec2 get_east(int = 0); glm::vec2 get_east(int = 0);
glm::vec2 get_south(int = 0);
glm::vec2 get_west(int = 0); glm::vec2 get_west(int = 0);
glm::vec2 get_center(int = 0); glm::vec2 get_center(int = 0);
void set_nw(const glm::vec2&); void set_nw(const glm::vec2&);
void set_ne(const glm::vec2&); void set_ne(const glm::vec2&);
void set_south(const glm::vec2&);
void set_center(const glm::vec2&); void set_center(const glm::vec2&);
void add_wrap(bool, bool); void add_wrap(bool, bool);
void add_wrap(bool, bool, Box); void add_wrap(bool, bool, Box);
@ -91,7 +95,7 @@ struct Frameset
Sprite* sprite; Sprite* sprite;
std::vector<int> order; std::vector<int> order;
int current_index = 0; int order_index = 0;
float frame_length = 0; float frame_length = 0;
bool reversed = false; bool reversed = false;
glm::vec2 size; glm::vec2 size;
@ -104,6 +108,8 @@ struct Frameset
float get_frame_length() const; float get_frame_length() const;
void reset(); void reset();
void clear(); void clear();
int get_order_index() const;
void set_order_index(int);
int get_current_frame_index() const; int get_current_frame_index() const;
glm::vec2 measure() const; glm::vec2 measure() const;
void set_size(); void set_size();

View File

@ -18,9 +18,10 @@ Box sfw::get_texture_box(SDL_Texture* texture)
return Box(glm::vec2(0, 0), glm::vec2(w, h)); return Box(glm::vec2(0, 0), glm::vec2(w, h));
} }
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, int r, int g, int b, int a) void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{ {
SDL_SetRenderTarget(renderer, texture); SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(renderer, r, g, b, a); SDL_SetRenderDrawColor(renderer, r, g, b, a);
SDL_RenderFillRect(renderer, NULL); SDL_RenderFillRect(renderer, NULL);
} }
@ -40,6 +41,20 @@ void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Texture
} }
} }
SDL_Texture* sfw::get_filled_texture(SDL_Renderer* renderer, glm::vec2 size, const SDL_Color& color, Uint32 format)
{
SDL_Texture* texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
sfw::fill_texture(renderer, texture, color.r, color.g, color.b, color.a);
return texture;
}
SDL_Texture* sfw::get_filled_texture(SDL_Renderer* renderer, glm::vec2 size, SDL_Texture* tile, Uint32 format)
{
SDL_Texture* texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
sfw::fill_texture(renderer, texture, tile);
return texture;
}
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, Uint32 format) SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, Uint32 format)
{ {
Box box = get_texture_box(base); Box box = get_texture_box(base);

View File

@ -28,8 +28,10 @@ namespace sfw
glm::vec2 get_step(glm::vec2, glm::vec2, float); glm::vec2 get_step(glm::vec2, glm::vec2, float);
void set_magnitude(glm::vec2&, float); void set_magnitude(glm::vec2&, float);
Box get_texture_box(SDL_Texture*); Box get_texture_box(SDL_Texture*);
void fill_texture(SDL_Renderer*, SDL_Texture*, int, int, int, int = 0xff); void fill_texture(SDL_Renderer*, SDL_Texture*, Uint8, Uint8, Uint8, Uint8 = 0xff);
void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*); void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*);
SDL_Texture* get_filled_texture(SDL_Renderer*, glm::vec2, const SDL_Color&, Uint32 = SDL_PIXELFORMAT_RGBA32);
SDL_Texture* get_filled_texture(SDL_Renderer*, glm::vec2, SDL_Texture*, Uint32 = SDL_PIXELFORMAT_RGBA32);
SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*, Uint32 = SDL_PIXELFORMAT_RGBA32); SDL_Texture* duplicate_texture(SDL_Renderer*, SDL_Texture*, Uint32 = SDL_PIXELFORMAT_RGBA32);
SDL_Texture* get_remapped_texture( SDL_Texture* get_remapped_texture(
SDL_Renderer*, SDL_Texture*, const std::map<SDL_Color, SDL_Color>&, Uint32 = SDL_PIXELFORMAT_RGBA32); SDL_Renderer*, SDL_Texture*, const std::map<SDL_Color, SDL_Color>&, Uint32 = SDL_PIXELFORMAT_RGBA32);
@ -43,6 +45,18 @@ namespace sfw
void print_error(const std::string&); void print_error(const std::string&);
void print_sdl_error(const std::string&); void print_sdl_error(const std::string&);
template<typename Key, typename Value, template <typename...> class Map>
std::vector<Key> get_keys(const Map<Key, Value>& map)
{
std::vector<Key> keys;
keys.reserve(map.size());
for (auto& member : map)
{
keys.push_back(member.first);
}
return keys;
}
template<typename T1, typename T2> template<typename T1, typename T2>
bool is_in_container(T1& container, T2& member) bool is_in_container(T1& container, T2& member)
{ {