box documentation, remove get/set prefixes from Box and Segment
This commit is contained in:
parent
fe3e0bf27f
commit
ba44b8e8d5
|
@ -143,8 +143,8 @@ Mushroom::Mushroom(Node *parent) : Sprite(parent, "resource/shrooms")
|
||||||
void Mushroom::update()
|
void Mushroom::update()
|
||||||
{
|
{
|
||||||
move(direction);
|
move(direction);
|
||||||
int x = box.get_x();
|
int x = box.left();
|
||||||
glm::ivec2 resolution = get_display().get_window_size();
|
glm::ivec2 resolution = get_display().window_size();
|
||||||
if (x > resolution.x or x < 0)
|
if (x > resolution.x or x < 0)
|
||||||
{
|
{
|
||||||
direction = -direction;
|
direction = -direction;
|
||||||
|
@ -234,7 +234,7 @@ void Demo::load_gl_context()
|
||||||
vertices.insert(vertices.end(), background_vertices.begin(), background_vertices.end());
|
vertices.insert(vertices.end(), background_vertices.begin(), background_vertices.end());
|
||||||
vertices.insert(vertices.end(), framerate_indicator_vertices.begin(),
|
vertices.insert(vertices.end(), framerate_indicator_vertices.begin(),
|
||||||
framerate_indicator_vertices.end());
|
framerate_indicator_vertices.end());
|
||||||
glm::ivec2 resolution = get_display().get_window_size();
|
glm::ivec2 resolution = get_display().window_size();
|
||||||
projection = glm::perspective(
|
projection = glm::perspective(
|
||||||
glm::radians(45.0f), resolution.x / (float) resolution.y, 0.1f,
|
glm::radians(45.0f), resolution.x / (float) resolution.y, 0.1f,
|
||||||
100.0f);
|
100.0f);
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct Mushroom : Sprite
|
||||||
|
|
||||||
Mushroom(Node*);
|
Mushroom(Node*);
|
||||||
void update();
|
void update();
|
||||||
virtual std::string get_class_name() const { return "Mushroom"; }
|
virtual std::string class_name() const { return "Mushroom"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,6 +71,6 @@ struct Demo : Game
|
||||||
void load_gl_context();
|
void load_gl_context();
|
||||||
void respond(SDL_Event&);
|
void respond(SDL_Event&);
|
||||||
void update();
|
void update();
|
||||||
virtual std::string get_class_name() const { return "Demo"; }
|
virtual std::string class_name() const { return "Demo"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,9 +57,9 @@ void SoundEffect::load_chunk(const fs::path& path)
|
||||||
void SoundEffect::play(float location)
|
void SoundEffect::play(float location)
|
||||||
{
|
{
|
||||||
play();
|
play();
|
||||||
Box window_box = get_window_box();
|
Box window = window_box();
|
||||||
location = std::clamp(location, window_box.get_left(), window_box.get_right());
|
location = std::clamp(location, window.left(), window.right());
|
||||||
float location_relative = (location - window_box.get_left()) / window_box.get_w();
|
float location_relative = (location - window.left()) / window.width();
|
||||||
int angle = 270 - location_relative * 180;
|
int angle = 270 - location_relative * 180;
|
||||||
Mix_SetPosition(channel, angle, 0);
|
Mix_SetPosition(channel, angle, 0);
|
||||||
}
|
}
|
||||||
|
|
567
src/Box.cpp
567
src/Box.cpp
|
@ -2,6 +2,7 @@
|
||||||
#include "Segment.hpp"
|
#include "Segment.hpp"
|
||||||
#include "Box.hpp"
|
#include "Box.hpp"
|
||||||
|
|
||||||
|
/* Construct a Box by giving the (x, y) coordinate of the NW point and the size as a 2D vector (width, height) */
|
||||||
Box::Box(const glm::vec2& nw, const glm::vec2& size)
|
Box::Box(const glm::vec2& nw, const glm::vec2& size)
|
||||||
{
|
{
|
||||||
x = nw.x;
|
x = nw.x;
|
||||||
|
@ -10,127 +11,138 @@ Box::Box(const glm::vec2& nw, const glm::vec2& size)
|
||||||
h = size.y;
|
h = size.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Construct a Box by passing an SDL_Rect struct, which is of the form {x, y, w, h} and limited to int arguments */
|
||||||
Box::Box(const SDL_Rect& rect) : Box({rect.x, rect.y}, {rect.w, rect.h}) {}
|
Box::Box(const SDL_Rect& rect) : Box({rect.x, rect.y}, {rect.w, rect.h}) {}
|
||||||
|
|
||||||
float Box::get_x() const
|
/* Return the width */
|
||||||
{
|
float Box::width() const
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Box::get_y() const
|
|
||||||
{
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Box::get_w() const
|
|
||||||
{
|
{
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Box::get_h() const
|
/* Set the width. Negative values will be clamped to zero. */
|
||||||
|
void Box::width(float width)
|
||||||
|
{
|
||||||
|
w = std::max(width, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the height */
|
||||||
|
float Box::height() const
|
||||||
{
|
{
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Box::set_x(float x)
|
/* Set the height. Negative values will be clamped to zero. */
|
||||||
|
void Box::height(float height)
|
||||||
{
|
{
|
||||||
this->x = x;
|
h = std::max(height, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Box::set_y(float y)
|
/* Return the size as a vector {width, height} */
|
||||||
|
glm::vec2 Box::size() const
|
||||||
{
|
{
|
||||||
this->y = y;
|
return glm::vec2(width(), height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Box::set_w(float width)
|
/* Set the size. Negative values will be clamped to zero. */
|
||||||
|
void Box::size(const glm::vec2& size, bool preserve_center)
|
||||||
{
|
{
|
||||||
w = width;
|
glm::vec2 center = this->center();
|
||||||
}
|
width(size.x);
|
||||||
|
height(size.y);
|
||||||
void Box::set_h(float height)
|
|
||||||
{
|
|
||||||
h = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_size() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_w(), get_h());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_size(const glm::vec2& size, bool preserve_center)
|
|
||||||
{
|
|
||||||
glm::vec2 center = get_center();
|
|
||||||
set_w(size.x);
|
|
||||||
set_h(size.y);
|
|
||||||
if (preserve_center)
|
if (preserve_center)
|
||||||
{
|
{
|
||||||
set_center(center);
|
this->center(center);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns width divided by height regardless of which side is longer */
|
/* Returns width divided by height. Returns a value regardless of which side is longer, so it can return values
|
||||||
|
* greater or less than 0. */
|
||||||
float Box::aspect() const
|
float Box::aspect() const
|
||||||
{
|
{
|
||||||
return get_w() / get_h();
|
return width() / height();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Box::get_area() const
|
/* Return the area of the box (width * height) */
|
||||||
|
float Box::area() const
|
||||||
{
|
{
|
||||||
return get_w() * get_h();
|
return width() * height();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Box::get_top() const
|
/* Return the y coordinate representing the top of the box */
|
||||||
|
float Box::top() const
|
||||||
{
|
{
|
||||||
return get_y();
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Box::get_right() const
|
/* Return the x coordinate representing the right side of the box */
|
||||||
|
float Box::right() const
|
||||||
{
|
{
|
||||||
return get_x() + get_w();
|
return left() + width();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Box::get_bottom() const
|
/* Return the y coordinate representing the bottom of the box */
|
||||||
|
float Box::bottom() const
|
||||||
{
|
{
|
||||||
return get_y() + get_h();
|
return top() + height();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Box::get_left() const
|
/* Return the x coordinate representing the left side of the box */
|
||||||
|
float Box::left() const
|
||||||
{
|
{
|
||||||
return get_x();
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Box::get_center_x() const
|
/* Return the x component of the center coordinates */
|
||||||
|
float Box::cx() const
|
||||||
{
|
{
|
||||||
return get_left() + get_w() / 2;
|
return left() + width() / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Box::get_center_y() const
|
/* Return the y component of the center coordinates */
|
||||||
|
float Box::cy() const
|
||||||
{
|
{
|
||||||
return get_top() + get_h() / 2;
|
return top() + height() / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Box::set_top(float top, bool drag)
|
/* Set the y coordinate of the top of the box. If drag is set, the other sides of the box will remain in the
|
||||||
|
* same position, and the top will be moved, altering the size of the box. Otherwise, the box will remain the
|
||||||
|
* same size, and the bottom location will change, moving the box but preserving the size. */
|
||||||
|
void Box::top(float top, bool drag)
|
||||||
{
|
{
|
||||||
if (!drag)
|
if (!drag)
|
||||||
{
|
{
|
||||||
set_y(top);
|
y = top;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
drag_top(top - get_top());
|
drag_top(top - this->top());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Drag the top delta amount, leaving the bottom in the same position and altering the size of the box. The top
|
||||||
|
* can be dragged past the bottom, in which case the current bottom will become the new top value. */
|
||||||
void Box::drag_top(float delta)
|
void Box::drag_top(float delta)
|
||||||
{
|
{
|
||||||
float previous_top = get_top();
|
float new_location = top() + delta;
|
||||||
set_top(get_top() + delta);
|
if (new_location > bottom())
|
||||||
set_h(get_h() + previous_top - get_top());
|
{
|
||||||
|
top(bottom());
|
||||||
|
height(new_location - top());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
height(bottom() - new_location);
|
||||||
|
top(new_location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Box::set_right(float right, bool drag)
|
/* Set the x coordinate of the right side of the box. If drag is set, the other sides of the box will remain in the
|
||||||
|
* same position, and the right will be moved, altering the size of the box. Otherwise, the box will remain the
|
||||||
|
* same size, and the left location will change, moving the box but preserving the size. */
|
||||||
|
void Box::right(float right, bool drag)
|
||||||
{
|
{
|
||||||
float delta = right - get_right();
|
float delta = right - this->right();
|
||||||
if (!drag)
|
if (!drag)
|
||||||
{
|
{
|
||||||
move({delta, 0});
|
move({delta, 0});
|
||||||
|
@ -141,17 +153,24 @@ void Box::set_right(float right, bool drag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Drag the right side delta amount, leaving the left in the same position and altering the size of the box. The right
|
||||||
|
* side can be dragged past the left, in which case the current left will become the new right value. */
|
||||||
void Box::drag_right(float delta)
|
void Box::drag_right(float delta)
|
||||||
{
|
{
|
||||||
float previous_right = get_right();
|
float new_location = right() + delta;
|
||||||
float new_right = get_right() + delta;
|
width(std::abs(left() - new_location));
|
||||||
set_w(get_w() + new_right - previous_right);
|
if (new_location < left())
|
||||||
set_right(new_right);
|
{
|
||||||
|
left(new_location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Box::set_bottom(float bottom, bool drag)
|
/* Set the y coordinate of the bottom of the box. If drag is set, the other sides of the box will remain in the
|
||||||
|
* same position, and the bottom will be moved, altering the size of the box. Otherwise, the box will remain the
|
||||||
|
* same size, and the top location will change, moving the box but preserving the size. */
|
||||||
|
void Box::bottom(float bottom, bool drag)
|
||||||
{
|
{
|
||||||
float delta = bottom - get_bottom();
|
float delta = bottom - this->bottom();
|
||||||
if (!drag)
|
if (!drag)
|
||||||
{
|
{
|
||||||
move({0, delta});
|
move({0, delta});
|
||||||
|
@ -162,180 +181,230 @@ void Box::set_bottom(float bottom, bool drag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Drag the bottom delta amount, leaving the top in the same position and altering the size of the box. The bottom
|
||||||
|
* can be dragged past the top, in which case the current top will become the new bottom value. */
|
||||||
void Box::drag_bottom(float delta)
|
void Box::drag_bottom(float delta)
|
||||||
{
|
{
|
||||||
float previous_bottom = get_bottom();
|
float new_location = bottom() + delta;
|
||||||
float new_bottom = get_bottom() + delta;
|
height(std::abs(top() - new_location));
|
||||||
set_h(get_h() + new_bottom - previous_bottom);
|
if (new_location < top())
|
||||||
set_bottom(new_bottom);
|
{
|
||||||
|
top(new_location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Box::set_left(float left, bool drag)
|
/* Set the x coordinate of the left side of the box. If drag is set, the other sides of the box will remain in the
|
||||||
|
* same position, and the left will be moved, altering the size of the box. Otherwise, the box will remain the
|
||||||
|
* same size, and the right location will change, moving the box but preserving the size. */
|
||||||
|
void Box::left(float left, bool drag)
|
||||||
{
|
{
|
||||||
if (!drag)
|
if (!drag)
|
||||||
{
|
{
|
||||||
set_x(left);
|
x = left;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
drag_left(left - get_left());
|
drag_left(left - this->left());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Drag the left side delta amount, leaving the right side in the same position and altering the size of the box.
|
||||||
|
* The left side can be dragged past the right, in which case the current right will become the new left value. */
|
||||||
void Box::drag_left(float delta)
|
void Box::drag_left(float delta)
|
||||||
{
|
{
|
||||||
float previous_left = get_left();
|
float new_location = left() + delta;
|
||||||
set_left(get_left() + delta);
|
if (new_location > right())
|
||||||
set_w(get_w() + previous_left - get_left());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_center_x(float x)
|
|
||||||
{
|
|
||||||
move({x - get_center_x(), 0});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_center_y(float y)
|
|
||||||
{
|
|
||||||
move({0, y - get_center_y()});
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_nw() const
|
|
||||||
{
|
|
||||||
return {get_x(), get_y()};
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_north() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_x() + get_w() / 2, get_y());
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_ne() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_right(), get_y());
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_east() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_right(), get_top() + get_h() / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_se() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_right(), get_bottom());
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_south() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_left() + get_w() / 2, get_bottom());
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_sw() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_left(), get_bottom());
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_west() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_x(), get_y() + get_h() / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec2 Box::get_center() const
|
|
||||||
{
|
|
||||||
return glm::vec2(get_x() + get_w() / 2, get_y() + get_h() / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_nw(const glm::vec2& nw)
|
|
||||||
{
|
|
||||||
move(nw - get_nw());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_north(const glm::vec2& n)
|
|
||||||
{
|
|
||||||
move(n - get_north());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_ne(const glm::vec2& ne)
|
|
||||||
{
|
|
||||||
move(ne - get_ne());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_east(const glm::vec2& e)
|
|
||||||
{
|
|
||||||
move(e - get_east());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_se(const glm::vec2& se)
|
|
||||||
{
|
|
||||||
move(se - get_se());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_south(const glm::vec2& s)
|
|
||||||
{
|
|
||||||
move(s - get_south());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_sw(const glm::vec2& sw)
|
|
||||||
{
|
|
||||||
move(sw - get_sw());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_west(const glm::vec2& w)
|
|
||||||
{
|
|
||||||
move(w - get_west());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::set_center(const glm::vec2& center)
|
|
||||||
{
|
|
||||||
move(center - get_center());
|
|
||||||
}
|
|
||||||
|
|
||||||
Box::operator SDL_Rect() const
|
|
||||||
{
|
|
||||||
return {static_cast<int>(get_x()), static_cast<int>(get_y()), static_cast<int>(get_w()), static_cast<int>(get_h())};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::clear()
|
|
||||||
{
|
|
||||||
set_nw(glm::vec2(0, 0));
|
|
||||||
set_size(glm::vec2(0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box::scale(glm::vec2 delta, bool preserve_center)
|
|
||||||
{
|
|
||||||
glm::vec2 center = get_center();
|
|
||||||
set_size(get_size() * delta);
|
|
||||||
if (preserve_center)
|
|
||||||
{
|
{
|
||||||
set_center(center);
|
left(right());
|
||||||
|
width(new_location - left());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width(right() - new_location);
|
||||||
|
left(new_location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the center x component */
|
||||||
|
void Box::cx(float x)
|
||||||
|
{
|
||||||
|
move({x - cx(), 0.0f});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the center y component */
|
||||||
|
void Box::cy(float y)
|
||||||
|
{
|
||||||
|
move({0.0f, y - cy()});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the coordinates of the top left corner */
|
||||||
|
glm::vec2 Box::nw() const
|
||||||
|
{
|
||||||
|
return {left(), top()};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the coordinates of the center of the top edge */
|
||||||
|
glm::vec2 Box::north() const
|
||||||
|
{
|
||||||
|
return glm::vec2(left() + width() / 2.0f, top());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the coordinates of the top right corner */
|
||||||
|
glm::vec2 Box::ne() const
|
||||||
|
{
|
||||||
|
return glm::vec2(right(), top());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the coordinates of the center of the right edge */
|
||||||
|
glm::vec2 Box::east() const
|
||||||
|
{
|
||||||
|
return glm::vec2(right(), top() + height() / 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the coordinates of the bottom right corner */
|
||||||
|
glm::vec2 Box::se() const
|
||||||
|
{
|
||||||
|
return glm::vec2(right(), bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the coordinates of the center of the bottom edge */
|
||||||
|
glm::vec2 Box::south() const
|
||||||
|
{
|
||||||
|
return glm::vec2(left() + width() / 2, bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the coordinates of the bottom left edge */
|
||||||
|
glm::vec2 Box::sw() const
|
||||||
|
{
|
||||||
|
return glm::vec2(left(), bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the coordinates of the center of the left edge */
|
||||||
|
glm::vec2 Box::west() const
|
||||||
|
{
|
||||||
|
return glm::vec2(left(), top() + height() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the center coordinates */
|
||||||
|
glm::vec2 Box::center() const
|
||||||
|
{
|
||||||
|
return glm::vec2(left() + width() / 2, top() + height() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the top left corner coordinates */
|
||||||
|
void Box::nw(const glm::vec2& nw)
|
||||||
|
{
|
||||||
|
move(nw - this->nw());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the center of the top edge */
|
||||||
|
void Box::north(const glm::vec2& north)
|
||||||
|
{
|
||||||
|
move(north - this->north());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the top right corner coordinates */
|
||||||
|
void Box::ne(const glm::vec2& ne)
|
||||||
|
{
|
||||||
|
move(ne - this->ne());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the center of the right edge */
|
||||||
|
void Box::east(const glm::vec2& east)
|
||||||
|
{
|
||||||
|
move(east - this->east());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the bottom right corner coordinates */
|
||||||
|
void Box::se(const glm::vec2& se)
|
||||||
|
{
|
||||||
|
move(se - this->se());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the center of the bottom edge */
|
||||||
|
void Box::south(const glm::vec2& south)
|
||||||
|
{
|
||||||
|
move(south - this->south());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the bottom left corner coordinates */
|
||||||
|
void Box::sw(const glm::vec2& sw)
|
||||||
|
{
|
||||||
|
move(sw - this->sw());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the center of the left edge */
|
||||||
|
void Box::west(const glm::vec2& west)
|
||||||
|
{
|
||||||
|
move(west - this->west());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the box by specifying the center coordinates */
|
||||||
|
void Box::center(const glm::vec2& center)
|
||||||
|
{
|
||||||
|
move(center - this->center());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when a Box instance is converted into an SDL_Rect. Allows passing Box to SDL functions that
|
||||||
|
* expect an SDL_Rect instead of an SDL_FRect */
|
||||||
|
Box::operator SDL_Rect() const
|
||||||
|
{
|
||||||
|
return {static_cast<int>(left()), static_cast<int>(top()), static_cast<int>(width()), static_cast<int>(height())};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero out the values of the box coordinates and size */
|
||||||
|
void Box::clear()
|
||||||
|
{
|
||||||
|
nw(glm::vec2(0, 0));
|
||||||
|
size(glm::vec2(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale the box by multiplying size by {delta.x, delta.y}. If preserve center is set, the box will be scaled
|
||||||
|
* around the center, otherwise the top left corner will remain in place. */
|
||||||
|
void Box::scale(glm::vec2 delta, bool preserve_center)
|
||||||
|
{
|
||||||
|
glm::vec2 center = this->center();
|
||||||
|
size(this->size() * delta);
|
||||||
|
if (preserve_center)
|
||||||
|
{
|
||||||
|
this->center(center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale the box by multiplying both width and height by delta. If preserve center is set, the box will be scaled
|
||||||
|
* around the center, otherwise the top left corner will remain in place. */
|
||||||
void Box::scale(float delta, bool preserve_center)
|
void Box::scale(float delta, bool preserve_center)
|
||||||
{
|
{
|
||||||
scale({delta, delta}, preserve_center);
|
scale({delta, delta}, preserve_center);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Expand (or shrink by passing negative values) the box size by adding delta to the current size. If preserve center
|
||||||
|
* is set, the box will expand around the center, otherwise the top left corner will remain in place. */
|
||||||
void Box::expand(glm::vec2 delta, bool preserve_center)
|
void Box::expand(glm::vec2 delta, bool preserve_center)
|
||||||
{
|
{
|
||||||
glm::vec2 center = get_center();
|
glm::vec2 center = this->center();
|
||||||
set_size(get_size() + delta);
|
size(size() + delta);
|
||||||
if (preserve_center)
|
if (preserve_center)
|
||||||
{
|
{
|
||||||
set_center(center);
|
this->center(center);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Expand (or shrink by passing negative values) the box size by adding delta to both width and height. If preserve
|
||||||
|
* center is set, the box will expand around the center, otherwise the top left corner will remain in place. */
|
||||||
void Box::expand(float delta, bool preserve_center)
|
void Box::expand(float delta, bool preserve_center)
|
||||||
{
|
{
|
||||||
expand({delta, delta}, preserve_center);
|
expand({delta, delta}, preserve_center);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Move the box in the x and y plane by delta amount */
|
||||||
void Box::move(const glm::vec2& delta)
|
void Box::move(const glm::vec2& delta)
|
||||||
{
|
{
|
||||||
set_x(get_x() + delta.x);
|
left(left() + delta.x);
|
||||||
set_y(get_y() + delta.y);
|
top(top() + delta.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return a copy of the original box, moved by delta amount in the x and y plane */
|
||||||
Box Box::stamp(const glm::vec2& delta) const
|
Box Box::stamp(const glm::vec2& delta) const
|
||||||
{
|
{
|
||||||
Box clone = *this;
|
Box clone = *this;
|
||||||
|
@ -343,45 +412,69 @@ Box Box::stamp(const glm::vec2& delta) const
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if box fits completely inside container, false otherwise. Includes the sides
|
||||||
|
* of the box, so if the sides are equal, it is considered inside. */
|
||||||
bool Box::fits(const Box& container) const
|
bool Box::fits(const Box& container) const
|
||||||
{
|
{
|
||||||
return !(get_top() < container.get_top() || get_right() > container.get_right() ||
|
return !(top() < container.top() || right() > container.right() ||
|
||||||
get_bottom() > container.get_bottom() || get_left() < container.get_left());
|
bottom() > container.bottom() || left() < container.left());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Removes any part of the box that is not inside the passed crop area box */
|
||||||
void Box::crop(const Box& area)
|
void Box::crop(const Box& area)
|
||||||
{
|
{
|
||||||
if (get_top() < area.get_top())
|
if (top() < area.top())
|
||||||
{
|
{
|
||||||
set_top(area.get_top(), true);
|
top(area.top(), true);
|
||||||
}
|
}
|
||||||
if (get_right() > area.get_right())
|
if (right() > area.right())
|
||||||
{
|
{
|
||||||
set_right(area.get_right(), true);
|
right(area.right(), true);
|
||||||
}
|
}
|
||||||
if (get_bottom() > area.get_bottom())
|
if (bottom() > area.bottom())
|
||||||
{
|
{
|
||||||
set_bottom(area.get_bottom(), true);
|
bottom(area.bottom(), true);
|
||||||
}
|
}
|
||||||
if (get_left() < area.get_left())
|
if (left() < area.left())
|
||||||
{
|
{
|
||||||
set_left(area.get_left(), true);
|
left(area.left(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if point is inside the box, false otherwise. Includes the edges, so points equal to the edges
|
||||||
|
* will return true. */
|
||||||
bool Box::collide(const glm::vec2& point) const
|
bool Box::collide(const glm::vec2& point) const
|
||||||
{
|
{
|
||||||
return point.x >= get_left() && point.x <= get_right() && point.y >= get_top() && point.y <= get_bottom();
|
return point.x >= left() && point.x <= right() && point.y >= top() && point.y <= bottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if the line segment intersects the box, false otherwise. If intersection is passed and there is a
|
||||||
|
* collision, intersection will be filled with the coordinates of the first intersection found unless the segment
|
||||||
|
* is fully within the box not touching any edges. */
|
||||||
bool Box::collide(const Segment& segment, glm::vec2* intersection) const
|
bool Box::collide(const Segment& segment, glm::vec2* intersection) const
|
||||||
{
|
{
|
||||||
if (collide(segment.get_box()))
|
/* do the faster check of whether the square represented by the segment diagonal collides to determine
|
||||||
|
* if we should look more closely */
|
||||||
|
if (collide(segment.box()))
|
||||||
{
|
{
|
||||||
return segment.intersect({get_nw(), get_ne()}, intersection) ||
|
/* check if segment intersects any edges, storing the intersection point if so */
|
||||||
segment.intersect({get_ne(), get_se()}, intersection) ||
|
if (segment.intersect({nw(), ne()}, intersection) ||
|
||||||
segment.intersect({get_sw(), get_se()}, intersection) ||
|
segment.intersect({ne(), se()}, intersection) ||
|
||||||
segment.intersect({get_nw(), get_sw()}, intersection);
|
segment.intersect({sw(), se()}, intersection) ||
|
||||||
|
segment.intersect({nw(), sw()}, intersection))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/* check if segment is fully inside the box */
|
||||||
|
else if (collide(segment.start()) && collide(segment.end()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/* otherwise, segment must be outside the box even though its box has collided */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -389,42 +482,58 @@ bool Box::collide(const Segment& segment, glm::vec2* intersection) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do segment collision with intersection specified by reference rather than pointer */
|
||||||
bool Box::collide(const Segment& segment, glm::vec2& intersection) const
|
bool Box::collide(const Segment& segment, glm::vec2& intersection) const
|
||||||
{
|
{
|
||||||
return collide(segment, &intersection);
|
return collide(segment, &intersection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if box collides with the passed box, false otherwise. If overlap is passed, it is set to
|
||||||
|
* the box representing the area where the two boxes overlap. */
|
||||||
bool Box::collide(const Box& box, Box* overlap) const
|
bool Box::collide(const Box& box, Box* overlap) const
|
||||||
{
|
{
|
||||||
float top = std::max(get_top(), box.get_top());
|
float top = std::max(this->top(), box.top());
|
||||||
float right = std::min(get_right(), box.get_right());
|
float right = std::min(this->right(), box.right());
|
||||||
float bottom = std::min(get_bottom(), box.get_bottom());
|
float bottom = std::min(this->bottom(), box.bottom());
|
||||||
float left = std::max(get_left(), box.get_left());
|
float left = std::max(this->left(), box.left());
|
||||||
float w = right - left;
|
float w = right - left;
|
||||||
float h = bottom - top;
|
float h = bottom - top;
|
||||||
bool collide = w > 0 && h > 0;
|
bool collide = w > 0 && h > 0;
|
||||||
if (collide && overlap != NULL)
|
if (collide && overlap != nullptr)
|
||||||
{
|
{
|
||||||
overlap->set_x(left);
|
overlap->left(left);
|
||||||
overlap->set_y(top);
|
overlap->top(top);
|
||||||
overlap->set_w(w);
|
overlap->width(w);
|
||||||
overlap->set_h(h);
|
overlap->height(h);
|
||||||
}
|
}
|
||||||
return collide;
|
return collide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do a box to box collision test with overlap passed by reference instead of pointer */
|
||||||
bool Box::collide(const Box& box, Box& overlap) const
|
bool Box::collide(const Box& box, Box& overlap) const
|
||||||
{
|
{
|
||||||
return collide(box, &overlap);
|
return collide(box, &overlap);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& Box::to_string (std::ostream& out) const
|
/* Map any point in the bounds of a square with x and y between [-, radius] to a circle with specified radius. If
|
||||||
|
* center is specified, both the square and circle are centered at specified point. The default radius is 1, and the
|
||||||
|
* default center is (0, 0). Formula taken from http://squircular.blogspot.com/2015/09/mapping-circle-to-square.html */
|
||||||
|
glm::vec2 Box::map_point_to_circle(const glm::vec2& point, float radius, const glm::vec2& center) const
|
||||||
{
|
{
|
||||||
out << "{(" << get_x() << ", " << get_y() << "), (" << get_w() << ", " << get_h() << ")}";
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the string representation of a Box "{left, top, width, height}" */
|
||||||
|
std::string Box::string() const
|
||||||
|
{
|
||||||
|
std::stringstream output;
|
||||||
|
output << "{(" << left() << ", " << top() << "), (" << width() << ", " << height() << ")}";
|
||||||
|
return output.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Feed a string representation of the box to the passed ostream */
|
||||||
std::ostream& operator<< (std::ostream& out, const Box& box)
|
std::ostream& operator<< (std::ostream& out, const Box& box)
|
||||||
{
|
{
|
||||||
return box.to_string(out);
|
out << box.string();
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
84
src/Box.hpp
84
src/Box.hpp
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
|
@ -19,52 +20,48 @@ public:
|
||||||
|
|
||||||
Box(const glm::vec2& = {0, 0}, const glm::vec2& = {0, 0});
|
Box(const glm::vec2& = {0, 0}, const glm::vec2& = {0, 0});
|
||||||
Box(const SDL_Rect&);
|
Box(const SDL_Rect&);
|
||||||
float get_x() const;
|
float width() const;
|
||||||
float get_y() const;
|
void width(float);
|
||||||
float get_w() const;
|
float height() const;
|
||||||
float get_h() const;
|
void height(float);
|
||||||
void set_x(float);
|
glm::vec2 size() const;
|
||||||
void set_y(float);
|
void size(const glm::vec2&, bool = false);
|
||||||
void set_w(float);
|
|
||||||
void set_h(float);
|
|
||||||
glm::vec2 get_size() const;
|
|
||||||
void set_size(const glm::vec2&, bool = false);
|
|
||||||
float aspect() const;
|
float aspect() const;
|
||||||
float get_area() const;
|
float area() const;
|
||||||
float get_top() const;
|
float top() const;
|
||||||
float get_right() const;
|
float right() const;
|
||||||
float get_bottom() const;
|
float bottom() const;
|
||||||
float get_left() const;
|
float left() const;
|
||||||
float get_center_x() const;
|
float cx() const;
|
||||||
float get_center_y() const;
|
float cy() const;
|
||||||
void set_top(float, bool=false);
|
void top(float, bool = false);
|
||||||
void drag_top(float);
|
void drag_top(float);
|
||||||
void set_right(float, bool=false);
|
void right(float, bool = false);
|
||||||
void drag_right(float);
|
void drag_right(float);
|
||||||
void set_bottom(float, bool=false);
|
void bottom(float, bool = false);
|
||||||
void drag_bottom(float);
|
void drag_bottom(float);
|
||||||
void set_left(float, bool=false);
|
void left(float, bool = false);
|
||||||
void drag_left(float);
|
void drag_left(float);
|
||||||
void set_center_x(float);
|
void cx(float);
|
||||||
void set_center_y(float);
|
void cy(float);
|
||||||
glm::vec2 get_nw() const;
|
glm::vec2 nw() const;
|
||||||
glm::vec2 get_north() const;
|
glm::vec2 north() const;
|
||||||
glm::vec2 get_ne() const;
|
glm::vec2 ne() const;
|
||||||
glm::vec2 get_east() const;
|
glm::vec2 east() const;
|
||||||
glm::vec2 get_se() const;
|
glm::vec2 se() const;
|
||||||
glm::vec2 get_south() const;
|
glm::vec2 south() const;
|
||||||
glm::vec2 get_sw() const;
|
glm::vec2 sw() const;
|
||||||
glm::vec2 get_west() const;
|
glm::vec2 west() const;
|
||||||
glm::vec2 get_center() const;
|
glm::vec2 center() const;
|
||||||
void set_nw(const glm::vec2&);
|
void nw(const glm::vec2&);
|
||||||
void set_north(const glm::vec2&);
|
void north(const glm::vec2&);
|
||||||
void set_ne(const glm::vec2&);
|
void ne(const glm::vec2&);
|
||||||
void set_east(const glm::vec2&);
|
void east(const glm::vec2&);
|
||||||
void set_se(const glm::vec2&);
|
void se(const glm::vec2&);
|
||||||
void set_south(const glm::vec2&);
|
void south(const glm::vec2&);
|
||||||
void set_sw(const glm::vec2&);
|
void sw(const glm::vec2&);
|
||||||
void set_west(const glm::vec2&);
|
void west(const glm::vec2&);
|
||||||
void set_center(const glm::vec2&);
|
void center(const glm::vec2&);
|
||||||
operator SDL_Rect() const;
|
operator SDL_Rect() const;
|
||||||
void clear();
|
void clear();
|
||||||
void scale(glm::vec2, bool = false);
|
void scale(glm::vec2, bool = false);
|
||||||
|
@ -80,8 +77,9 @@ public:
|
||||||
bool collide(const Segment&, glm::vec2&) const;
|
bool collide(const Segment&, glm::vec2&) const;
|
||||||
bool collide(const Box&, Box* = nullptr) const;
|
bool collide(const Box&, Box* = nullptr) const;
|
||||||
bool collide(const Box&, Box&) const;
|
bool collide(const Box&, Box&) const;
|
||||||
virtual std::string get_class_name() const { return "Box"; }
|
glm::vec2 map_point_to_circle(const glm::vec2&, float, const glm::vec2&) const;
|
||||||
std::ostream& to_string (std::ostream&) const;
|
virtual std::string class_name() const { return "Box"; }
|
||||||
|
std::string string() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct Configuration : Node
|
||||||
void merge();
|
void merge();
|
||||||
void write();
|
void write();
|
||||||
void write(fs::path path);
|
void write(fs::path path);
|
||||||
virtual std::string get_class_name() const { return "Configuration"; }
|
virtual std::string class_name() const { return "Configuration"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ Display::Display(Node* parent) : Node(parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the (x, y) size in pixels of the window as an integer vector */
|
/* Return the (x, y) size in pixels of the window as an integer vector */
|
||||||
glm::ivec2 Display::get_window_size() const
|
glm::ivec2 Display::window_size() const
|
||||||
{
|
{
|
||||||
glm::ivec2 size;
|
glm::ivec2 size;
|
||||||
SDL_GetWindowSize(const_cast<SDL_Window*>(get_window()), &size.x, &size.y);
|
SDL_GetWindowSize(const_cast<SDL_Window*>(get_window()), &size.x, &size.y);
|
||||||
|
@ -16,13 +16,13 @@ glm::ivec2 Display::get_window_size() const
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the window dimensions as a Box object */
|
/* Return the window dimensions as a Box object */
|
||||||
Box Display::get_window_box() const
|
Box Display::window_box() const
|
||||||
{
|
{
|
||||||
return Box(glm::vec2(0, 0), get_window_size());
|
return Box(glm::vec2(0, 0), window_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the pixel format of display at specified index (defaults to index 0) */
|
/* Get the pixel format of display at specified index (defaults to index 0) */
|
||||||
Uint32 Display::get_pixel_format(int display_index) const
|
Uint32 Display::pixel_format(int display_index) const
|
||||||
{
|
{
|
||||||
SDL_DisplayMode display_mode;
|
SDL_DisplayMode display_mode;
|
||||||
if (SDL_GetCurrentDisplayMode(display_index, &display_mode) != 0)
|
if (SDL_GetCurrentDisplayMode(display_index, &display_mode) != 0)
|
||||||
|
@ -38,7 +38,7 @@ Uint32 Display::get_pixel_format(int display_index) const
|
||||||
|
|
||||||
/* Fill the supplied, pre-allocated buffer with 32-bit pixels (8 bits per component) from the GL
|
/* Fill the supplied, pre-allocated buffer with 32-bit pixels (8 bits per component) from the GL
|
||||||
* read buffer if in GL context or from the SDL renderer if in SDL context */
|
* read buffer if in GL context or from the SDL renderer if in SDL context */
|
||||||
void Display::get_screen_pixels(unsigned char* pixels, int w, int h, int x, int y) const
|
void Display::screen_pixels(unsigned char* pixels, int w, int h, int x, int y) const
|
||||||
{
|
{
|
||||||
if (get_root()->is_gl_context)
|
if (get_root()->is_gl_context)
|
||||||
{
|
{
|
||||||
|
@ -65,19 +65,19 @@ void Display::get_screen_pixels(unsigned char* pixels, int w, int h, int x, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface* Display::get_screen_surface() const
|
SDL_Surface* Display::screen_surface() const
|
||||||
{
|
{
|
||||||
glm::ivec2 size = get_window_size();
|
glm::ivec2 size = window_size();
|
||||||
unsigned char* pixels = new unsigned char[bpp / 8 * size.x * size.y];
|
unsigned char* pixels = new unsigned char[bpp / 8 * size.x * size.y];
|
||||||
get_screen_pixels(pixels, size.x, size.y);
|
screen_pixels(pixels, size.x, size.y);
|
||||||
SDL_Surface* surface = get_screen_surface_from_pixels(pixels, get_root()->is_gl_context);
|
SDL_Surface* surface = screen_surface_from_pixels(pixels, get_root()->is_gl_context);
|
||||||
delete[] pixels;
|
delete[] pixels;
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface* Display::get_screen_surface_from_pixels(unsigned char* pixels, bool flip) const
|
SDL_Surface* Display::screen_surface_from_pixels(unsigned char* pixels, bool flip) const
|
||||||
{
|
{
|
||||||
glm::ivec2 size = get_window_size();
|
glm::ivec2 size = window_size();
|
||||||
SDL_Surface* surface;
|
SDL_Surface* surface;
|
||||||
Uint32 rmask, gmask, bmask, amask;
|
Uint32 rmask, gmask, bmask, amask;
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||||
|
|
|
@ -13,18 +13,20 @@
|
||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
#include "Box.hpp"
|
#include "Box.hpp"
|
||||||
|
|
||||||
struct Display : Node
|
class Display : public Node
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
const static int bpp = 32;
|
const static int bpp = 32;
|
||||||
|
|
||||||
Display(Node*);
|
Display(Node*);
|
||||||
glm::ivec2 get_window_size() const;
|
glm::ivec2 window_size() const;
|
||||||
Uint32 get_pixel_format(int = 0) const;
|
Uint32 pixel_format(int = 0) const;
|
||||||
Box get_window_box() const;
|
Box window_box() const;
|
||||||
void get_screen_pixels(unsigned char*, int, int, int = 0, int = 0) const;
|
void screen_pixels(unsigned char*, int, int, int = 0, int = 0) const;
|
||||||
SDL_Surface* get_screen_surface() const;
|
SDL_Surface* screen_surface() const;
|
||||||
SDL_Surface* get_screen_surface_from_pixels(unsigned char*, bool) const;
|
SDL_Surface* screen_surface_from_pixels(unsigned char*, bool) const;
|
||||||
void respond(SDL_Event&);
|
void respond(SDL_Event&);
|
||||||
void toggle_fullscreen() const;
|
void toggle_fullscreen() const;
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ void FramerateIndicator::refresh()
|
||||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(get_root()->get_renderer(), surface);
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(get_root()->get_renderer(), surface);
|
||||||
add_frames(texture);
|
add_frames(texture);
|
||||||
SDL_FreeSurface(surface);
|
SDL_FreeSurface(surface);
|
||||||
set_ne(get_display().get_window_box().get_ne());
|
set_ne(get_display().window_box().ne());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ public:
|
||||||
float get_frame_length() const;
|
float get_frame_length() const;
|
||||||
void handle_quit_event(SDL_Event&);
|
void handle_quit_event(SDL_Event&);
|
||||||
void quit();
|
void quit();
|
||||||
virtual std::string get_class_name() const { return "Game"; }
|
virtual std::string class_name() const { return "Game"; }
|
||||||
~Game();
|
~Game();
|
||||||
|
|
||||||
/* Applies delta timing to a value: returns the value as weighted by the amount of time passed since the
|
/* Applies delta timing to a value: returns the value as weighted by the amount of time passed since the
|
||||||
|
|
|
@ -60,7 +60,7 @@ struct Input : Node
|
||||||
void suppress();
|
void suppress();
|
||||||
void unsuppress();
|
void unsuppress();
|
||||||
bool is_suppressed();
|
bool is_suppressed();
|
||||||
virtual std::string get_class_name() const { return "Input"; }
|
virtual std::string class_name() const { return "Input"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -99,9 +99,9 @@ const Game* Node::get_root() const
|
||||||
return dynamic_cast<const Game*>(r);
|
return dynamic_cast<const Game*>(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
Box Node::get_window_box()
|
Box Node::window_box()
|
||||||
{
|
{
|
||||||
return get_display().get_window_box();
|
return get_display().window_box();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::suppress_input()
|
void Node::suppress_input()
|
||||||
|
@ -140,7 +140,7 @@ const std::string Node::get_branch_as_string() const
|
||||||
std::stringstream branch;
|
std::stringstream branch;
|
||||||
while (current != nullptr)
|
while (current != nullptr)
|
||||||
{
|
{
|
||||||
branch << current->get_class_name() << " @ " << current;
|
branch << current->class_name() << " @ " << current;
|
||||||
if (current->parent != nullptr)
|
if (current->parent != nullptr)
|
||||||
{
|
{
|
||||||
branch << " -> ";
|
branch << " -> ";
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
class Game;
|
class Game;
|
||||||
struct Delegate;
|
struct Delegate;
|
||||||
struct Display;
|
class Display;
|
||||||
struct Input;
|
struct Input;
|
||||||
class Box;
|
class Box;
|
||||||
struct Audio;
|
struct Audio;
|
||||||
|
@ -43,14 +43,14 @@ public:
|
||||||
Input& get_input();
|
Input& get_input();
|
||||||
Audio& get_audio();
|
Audio& get_audio();
|
||||||
const Game* get_root() const;
|
const Game* get_root() const;
|
||||||
Box get_window_box();
|
Box window_box();
|
||||||
void suppress_input();
|
void suppress_input();
|
||||||
void suppress_input_temporarily(int = 0);
|
void suppress_input_temporarily(int = 0);
|
||||||
void unsuppress_input();
|
void unsuppress_input();
|
||||||
void log(const std::string&) const;
|
void log(const std::string&) const;
|
||||||
void debug(const std::string&) const;
|
void debug(const std::string&) const;
|
||||||
const std::string get_branch_as_string() const;
|
const std::string get_branch_as_string() const;
|
||||||
virtual std::string get_class_name() const { return "Node"; };
|
virtual std::string class_name() const { return "Node"; };
|
||||||
virtual ~Node();
|
virtual ~Node();
|
||||||
|
|
||||||
template<typename T = Game>
|
template<typename T = Game>
|
||||||
|
|
|
@ -63,7 +63,7 @@ void Recorder::respond(SDL_Event& event)
|
||||||
void Recorder::capture_screen()
|
void Recorder::capture_screen()
|
||||||
{
|
{
|
||||||
nlohmann::json config = get_configuration();
|
nlohmann::json config = get_configuration();
|
||||||
SDL_Surface* surface = get_display().get_screen_surface();
|
SDL_Surface* surface = get_display().screen_surface();
|
||||||
fs::path directory = config["recording"]["screenshot-directory"];
|
fs::path directory = config["recording"]["screenshot-directory"];
|
||||||
fs::create_directories(directory);
|
fs::create_directories(directory);
|
||||||
std::string prefix = config["recording"]["screenshot-prefix"].get<std::string>();
|
std::string prefix = config["recording"]["screenshot-prefix"].get<std::string>();
|
||||||
|
@ -147,10 +147,10 @@ void Recorder::open_audio_file()
|
||||||
|
|
||||||
void Recorder::add_frame()
|
void Recorder::add_frame()
|
||||||
{
|
{
|
||||||
glm::ivec2 size = get_display().get_window_size();
|
glm::ivec2 size = get_display().window_size();
|
||||||
int bytes = Display::bpp / 8 * size.x * size.y;
|
int bytes = Display::bpp / 8 * size.x * size.y;
|
||||||
unsigned char* pixels = new unsigned char[bytes];
|
unsigned char* pixels = new unsigned char[bytes];
|
||||||
get_display().get_screen_pixels(pixels, size.x, size.y);
|
get_display().screen_pixels(pixels, size.x, size.y);
|
||||||
int max_length = get_configuration()["recording"]["max-stash-length"];
|
int max_length = get_configuration()["recording"]["max-stash-length"];
|
||||||
float length = frame_length() * current_stash.pixel_buffers.size();
|
float length = frame_length() * current_stash.pixel_buffers.size();
|
||||||
if (length > max_length)
|
if (length > max_length)
|
||||||
|
@ -177,7 +177,7 @@ void Recorder::add_frame()
|
||||||
// std::vector<bool> flipped = video_stashes.back().flipped;
|
// std::vector<bool> flipped = video_stashes.back().flipped;
|
||||||
// for (int ii = frame_offset; ii < pixel_buffers.size() + frame_offset; ii++)
|
// for (int ii = frame_offset; ii < pixel_buffers.size() + frame_offset; ii++)
|
||||||
// {
|
// {
|
||||||
// SDL_Surface* frame = get_display().get_screen_surface_from_pixels(
|
// SDL_Surface* frame = get_display().screen_surface_from_pixels(
|
||||||
// pixel_buffers[ii - frame_offset], flipped[ii - frame_offset]);
|
// pixel_buffers[ii - frame_offset], flipped[ii - frame_offset]);
|
||||||
// std::stringstream name;
|
// std::stringstream name;
|
||||||
// name << sfw::pad(ii, 5) << ".png";
|
// name << sfw::pad(ii, 5) << ".png";
|
||||||
|
@ -199,7 +199,7 @@ void Recorder::add_frame()
|
||||||
|
|
||||||
int Recorder::get_memory_size()
|
int Recorder::get_memory_size()
|
||||||
{
|
{
|
||||||
glm::ivec2 window = get_display().get_window_size();
|
glm::ivec2 window = get_display().window_size();
|
||||||
int bytes_per_frame = Display::bpp / 8 * window.x * window.y,
|
int bytes_per_frame = Display::bpp / 8 * window.x * window.y,
|
||||||
size_in_bytes = 0;
|
size_in_bytes = 0;
|
||||||
for (Stash& stash : in_game_stashes)
|
for (Stash& stash : in_game_stashes)
|
||||||
|
@ -248,7 +248,7 @@ void Recorder::write_stash_frames(Stash* stash)
|
||||||
float elapsed = 0, last_gif_write = 0, gif_write_overflow = 0;
|
float elapsed = 0, last_gif_write = 0, gif_write_overflow = 0;
|
||||||
for (int ii = stash->frame_offset; not stash->pixel_buffers.empty(); ii++)
|
for (int ii = stash->frame_offset; not stash->pixel_buffers.empty(); ii++)
|
||||||
{
|
{
|
||||||
frame = get_display().get_screen_surface_from_pixels(
|
frame = get_display().screen_surface_from_pixels(
|
||||||
stash->pixel_buffers.front(), stash->flipped.front());
|
stash->pixel_buffers.front(), stash->flipped.front());
|
||||||
std::stringstream name;
|
std::stringstream name;
|
||||||
name << sfw::pad(ii, 5) << ".png";
|
name << sfw::pad(ii, 5) << ".png";
|
||||||
|
@ -339,7 +339,7 @@ void Recorder::finish_writing_video()
|
||||||
* This requires ffmpeg to be installed on the user's system. Might only work on Linux (?) */
|
* This requires ffmpeg to be installed on the user's system. Might only work on Linux (?) */
|
||||||
void Recorder::write_mp4()
|
void Recorder::write_mp4()
|
||||||
{
|
{
|
||||||
glm::ivec2 size = get_display().get_window_size();
|
glm::ivec2 size = get_display().window_size();
|
||||||
std::ostringstream mp4_command;
|
std::ostringstream mp4_command;
|
||||||
std::string pixel_format = get_configuration()["recording"]["mp4-pixel-format"].get<std::string>();
|
std::string pixel_format = get_configuration()["recording"]["mp4-pixel-format"].get<std::string>();
|
||||||
fs::path images_match = current_video_directory / "%05d.png";
|
fs::path images_match = current_video_directory / "%05d.png";
|
||||||
|
|
|
@ -68,7 +68,7 @@ public:
|
||||||
void write_mp4();
|
void write_mp4();
|
||||||
void write_audio(Uint8*, int);
|
void write_audio(Uint8*, int);
|
||||||
void update();
|
void update();
|
||||||
virtual std::string get_class_name() const { return "Recorder"; }
|
virtual std::string class_name() const { return "Recorder"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,39 +3,43 @@
|
||||||
#include "Box.hpp"
|
#include "Box.hpp"
|
||||||
#include "Segment.hpp"
|
#include "Segment.hpp"
|
||||||
|
|
||||||
Segment::Segment(const glm::vec2& start, const glm::vec2& end) : start(start), end(end) {};
|
Segment::Segment(const glm::vec2& start, const glm::vec2& end)
|
||||||
|
{
|
||||||
|
this->start(start);
|
||||||
|
this->end(end);
|
||||||
|
}
|
||||||
|
|
||||||
Segment::Segment() : Segment({0, 0}, {0, 0}) {};
|
Segment::Segment() : Segment({0, 0}, {0, 0}) {};
|
||||||
|
|
||||||
Segment::Segment(const glm::vec2& location) : Segment(location, location) {};
|
Segment::Segment(const glm::vec2& location) : Segment(location, location) {};
|
||||||
|
|
||||||
Segment::Segment(const Box& start, const Box& end) : Segment(start.get_center(), end.get_center()) {};
|
Segment::Segment(const Box& start, const Box& end) : Segment(start.center(), end.center()) {};
|
||||||
|
|
||||||
glm::vec2 Segment::get_start() const
|
inline glm::vec2 Segment::start() const
|
||||||
{
|
{
|
||||||
return start;
|
return start_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::set_start(const glm::vec2& s)
|
void Segment::start(const glm::vec2& start)
|
||||||
{
|
{
|
||||||
start = s;
|
start_ = start;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Segment::get_end() const
|
glm::vec2 Segment::end() const
|
||||||
{
|
{
|
||||||
return end;
|
return end_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::set_end(const glm::vec2& e)
|
void Segment::end(const glm::vec2& end)
|
||||||
{
|
{
|
||||||
end = e;
|
end_ = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// taken from http://www.realtimerendering.com/resources/GraphicsGems/gemsii/xlines.c
|
// taken from http://www.realtimerendering.com/resources/GraphicsGems/gemsii/xlines.c
|
||||||
bool Segment::intersect(const Segment& segment, glm::vec2* intersection) const
|
bool Segment::intersect(const Segment& segment, glm::vec2* intersection) const
|
||||||
{
|
{
|
||||||
float x1 = start.x, y1 = start.y, x2 = end.x, y2 = end.y, x3 = segment.start.x,
|
float x1 = start_.x, y1 = start_.y, x2 = end_.x, y2 = end_.y, x3 = segment.start_.x,
|
||||||
y3 = segment.start.y, x4 = segment.end.x, y4 = segment.end.y;
|
y3 = segment.start_.y, x4 = segment.end_.x, y4 = segment.end_.y;
|
||||||
|
|
||||||
float a1, a2, b1, b2, c1, c2; // Coefficients of line eqns.
|
float a1, a2, b1, b2, c1, c2; // Coefficients of line eqns.
|
||||||
float r1, r2, r3, r4; // 'Sign' values
|
float r1, r2, r3, r4; // 'Sign' values
|
||||||
|
@ -99,58 +103,58 @@ bool Segment::intersect(const Segment& segment, glm::vec2& intersection) const
|
||||||
return intersect(segment, &intersection);
|
return intersect(segment, &intersection);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Segment::get_dx() const
|
float Segment::dx() const
|
||||||
{
|
{
|
||||||
return end.x - start.x;
|
return end_.x - start_.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Segment::get_dy() const
|
float Segment::dy() const
|
||||||
{
|
{
|
||||||
return end.y - start.y;
|
return end_.y - start_.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Segment::get_length() const
|
float Segment::length() const
|
||||||
{
|
{
|
||||||
return glm::distance(start, end);
|
return glm::distance(start_, end_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Box Segment::get_box() const
|
Box Segment::box() const
|
||||||
{
|
{
|
||||||
float x = std::min(start.x, end.x);
|
float x = std::min(start_.x, end_.x);
|
||||||
float y = std::min(start.y, end.y);
|
float y = std::min(start_.y, end_.y);
|
||||||
float w = std::abs(get_dx());
|
float w = std::abs(dx());
|
||||||
float h = std::abs(get_dy());
|
float h = std::abs(dy());
|
||||||
return Box({x, y}, {w, h});
|
return Box({x, y}, {w, h});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::move(const glm::vec2& delta)
|
void Segment::move(const glm::vec2& delta)
|
||||||
{
|
{
|
||||||
start += delta;
|
start_ += delta;
|
||||||
end += delta;
|
end_ += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Segment::get_center() const
|
glm::vec2 Segment::center() const
|
||||||
{
|
{
|
||||||
return get_subsegments(2)[0].end;
|
return subsegments(2)[0].end_;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Segment::get_step(float speed) const
|
glm::vec2 Segment::step(float speed) const
|
||||||
{
|
{
|
||||||
float angle = glm::atan(end.x - start.x, end.y - start.y);
|
float angle = glm::atan(end_.x - start_.x, end_.y - start_.y);
|
||||||
return glm::vec2(speed * glm::sin(angle), speed * glm::cos(angle));
|
return glm::vec2(speed * glm::sin(angle), speed * glm::cos(angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Segment::get_step_relative(float relative_length_per_step) const
|
glm::vec2 Segment::step_relative(float relative_length_per_step) const
|
||||||
{
|
{
|
||||||
return get_step(glm::distance(start, end) * relative_length_per_step);
|
return step(glm::distance(start_, end_) * relative_length_per_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Segment> Segment::get_subsegments(int count) const
|
std::vector<Segment> Segment::subsegments(int count) const
|
||||||
{
|
{
|
||||||
glm::vec2 step = get_step_relative(1.0f / count);
|
glm::vec2 step = step_relative(1.0f / count);
|
||||||
std::vector<Segment> subsegments;
|
std::vector<Segment> subsegments;
|
||||||
subsegments.reserve(count);
|
subsegments.reserve(count);
|
||||||
glm::vec2 subsegment_start = start, subsegment_end;
|
glm::vec2 subsegment_start = start_, subsegment_end;
|
||||||
for (int ii = 0; ii < count; ii++)
|
for (int ii = 0; ii < count; ii++)
|
||||||
{
|
{
|
||||||
subsegment_end = subsegment_start + step;
|
subsegment_end = subsegment_start + step;
|
||||||
|
@ -162,7 +166,7 @@ std::vector<Segment> Segment::get_subsegments(int count) const
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const Segment& segment)
|
std::ostream& operator<<(std::ostream& out, const Segment& segment)
|
||||||
{
|
{
|
||||||
out << "{(" << segment.start.x << ", " << segment.start.y << "), (" <<
|
out << "{(" << segment.start().x << ", " << segment.start().y << "), (" <<
|
||||||
segment.end.x << ", " << segment.end.y << ")}";
|
segment.end().x << ", " << segment.end().y << ")}";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,31 +13,33 @@ struct Sprite;
|
||||||
class Segment
|
class Segment
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
glm::vec2 start_, end_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
glm::vec2 start, end;
|
|
||||||
|
|
||||||
Segment(const glm::vec2&, const glm::vec2&);
|
Segment(const glm::vec2&, const glm::vec2&);
|
||||||
Segment();
|
Segment();
|
||||||
Segment(const glm::vec2&);
|
Segment(const glm::vec2&);
|
||||||
Segment(const Box&, const Box&);
|
Segment(const Box&, const Box&);
|
||||||
Segment(const Sprite&, const Sprite&);
|
Segment(const Sprite&, const Sprite&);
|
||||||
glm::vec2 get_start() const;
|
inline glm::vec2 start() const;
|
||||||
void set_start(const glm::vec2&);
|
void start(const glm::vec2&);
|
||||||
glm::vec2 get_end() const;
|
glm::vec2 end() const;
|
||||||
void set_end(const glm::vec2&);
|
void end(const glm::vec2&);
|
||||||
bool intersect(const Segment&, glm::vec2* = nullptr) const;
|
bool intersect(const Segment&, glm::vec2* = nullptr) const;
|
||||||
bool intersect(const Segment&, glm::vec2&) const;
|
bool intersect(const Segment&, glm::vec2&) const;
|
||||||
float get_dx() const;
|
float dx() const;
|
||||||
float get_dy() const;
|
float dy() const;
|
||||||
float get_length() const;
|
float length() const;
|
||||||
Box get_box() const;
|
Box box() const;
|
||||||
void move(const glm::vec2&);
|
void move(const glm::vec2&);
|
||||||
glm::vec2 get_center() const;
|
glm::vec2 center() const;
|
||||||
glm::vec2 get_step(float) const;
|
glm::vec2 step(float) const;
|
||||||
glm::vec2 get_step_relative(float) const;
|
glm::vec2 step_relative(float) const;
|
||||||
std::vector<Segment> get_subsegments(int) const;
|
std::vector<Segment> subsegments(int) const;
|
||||||
inline bool operator<(const Segment& segment) const { return operator<(segment.get_length()); }
|
inline bool operator<(const Segment& segment) const { return operator<(segment.length()); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
std::cout << (a < b) << (a > b) << (b < c) << (b <= c) << (c > b) << (c >= b) << (d < 1) << (d < 2) <<
|
std::cout << (a < b) << (a > b) << (b < c) << (b <= c) << (c > b) << (c >= b) << (d < 1) << (d < 2) <<
|
||||||
|
@ -47,10 +49,10 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename N>
|
template<typename N>
|
||||||
inline bool operator<(const N& other) const { return get_length() < other; }
|
inline bool operator<(const N& other) const { return length() < other; }
|
||||||
|
|
||||||
template<typename N>
|
template<typename N>
|
||||||
inline bool operator>(const N& other) const { return other < get_length(); }
|
inline bool operator>(const N& other) const { return other < length(); }
|
||||||
|
|
||||||
template<typename N>
|
template<typename N>
|
||||||
inline bool operator<=(const N& other) const { return !operator>(other); }
|
inline bool operator<=(const N& other) const { return !operator>(other); }
|
||||||
|
|
|
@ -197,7 +197,7 @@ void Sprite::update_size(bool preserve_center)
|
||||||
{
|
{
|
||||||
for (std::size_t ii = 0; ii < boxes.size(); ii++)
|
for (std::size_t ii = 0; ii < boxes.size(); ii++)
|
||||||
{
|
{
|
||||||
boxes[ii].set_size(get_current_frameset().get_size(), preserve_center);
|
boxes[ii].size(get_current_frameset().get_size(), preserve_center);
|
||||||
if (scale != 1)
|
if (scale != 1)
|
||||||
{
|
{
|
||||||
boxes[ii].scale(scale, preserve_center);
|
boxes[ii].scale(scale, preserve_center);
|
||||||
|
@ -307,92 +307,92 @@ const SDL_Color& Sprite::get_color_mod() const
|
||||||
|
|
||||||
float Sprite::get_w() const
|
float Sprite::get_w() const
|
||||||
{
|
{
|
||||||
return get_box().get_w();
|
return get_box().width();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Sprite::get_h() const
|
float Sprite::get_h() const
|
||||||
{
|
{
|
||||||
return get_box().get_h();
|
return get_box().height();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_size() const
|
glm::vec2 Sprite::get_size() const
|
||||||
{
|
{
|
||||||
return get_box().get_size();
|
return get_box().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Sprite::get_top(int index) const
|
float Sprite::get_top(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_top();
|
return get_box(index).top();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Sprite::get_right(int index) const
|
float Sprite::get_right(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_right();
|
return get_box(index).right();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Sprite::get_bottom(int index) const
|
float Sprite::get_bottom(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_bottom();
|
return get_box(index).bottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Sprite::get_left(int index) const
|
float Sprite::get_left(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_left();
|
return get_box(index).left();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Sprite::get_center_x(int index) const
|
float Sprite::get_center_x(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_center_x();
|
return get_box(index).cx();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Sprite::get_center_y(int index) const
|
float Sprite::get_center_y(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_center_y();
|
return get_box(index).cy();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_nw(int index) const
|
glm::vec2 Sprite::get_nw(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_nw();
|
return get_box(index).nw();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_north(int index) const
|
glm::vec2 Sprite::get_north(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_north();
|
return get_box(index).north();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_ne(int index) const
|
glm::vec2 Sprite::get_ne(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_ne();
|
return get_box(index).ne();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_east(int index) const
|
glm::vec2 Sprite::get_east(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_east();
|
return get_box(index).east();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_se(int index) const
|
glm::vec2 Sprite::get_se(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_se();
|
return get_box(index).se();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_south(int index) const
|
glm::vec2 Sprite::get_south(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_south();
|
return get_box(index).south();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_sw(int index) const
|
glm::vec2 Sprite::get_sw(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_sw();
|
return get_box(index).sw();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_west(int index) const
|
glm::vec2 Sprite::get_west(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_west();
|
return get_box(index).west();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 Sprite::get_center(int index) const
|
glm::vec2 Sprite::get_center(int index) const
|
||||||
{
|
{
|
||||||
return get_box(index).get_center();
|
return get_box(index).center();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::set_top(float top)
|
void Sprite::set_top(float top)
|
||||||
|
@ -467,7 +467,7 @@ void Sprite::set_center(const glm::vec2& center)
|
||||||
|
|
||||||
void Sprite::add_wrap(bool x, bool y)
|
void Sprite::add_wrap(bool x, bool y)
|
||||||
{
|
{
|
||||||
add_wrap(x, y, get_display().get_window_box());
|
add_wrap(x, y, get_display().window_box());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::add_wrap(bool x, bool y, Box frame)
|
void Sprite::add_wrap(bool x, bool y, Box frame)
|
||||||
|
@ -478,15 +478,15 @@ void Sprite::add_wrap(bool x, bool y, Box frame)
|
||||||
{
|
{
|
||||||
if (x)
|
if (x)
|
||||||
{
|
{
|
||||||
add_box({frame.get_w(), 0});
|
add_box({frame.width(), 0});
|
||||||
}
|
}
|
||||||
if (y)
|
if (y)
|
||||||
{
|
{
|
||||||
add_box({0, frame.get_h()});
|
add_box({0, frame.height()});
|
||||||
}
|
}
|
||||||
if (x && y)
|
if (x && y)
|
||||||
{
|
{
|
||||||
add_box({frame.get_w(), frame.get_h()});
|
add_box({frame.width(), frame.height()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wrap_frame = frame;
|
wrap_frame = frame;
|
||||||
|
@ -510,24 +510,24 @@ glm::vec2 Sprite::move(const glm::vec2& delta)
|
||||||
}
|
}
|
||||||
if (wrap.x)
|
if (wrap.x)
|
||||||
{
|
{
|
||||||
if (get_right() > wrap_frame.get_right())
|
if (get_right() > wrap_frame.right())
|
||||||
{
|
{
|
||||||
move({-wrap_frame.get_w(), 0});
|
move({-wrap_frame.width(), 0});
|
||||||
}
|
}
|
||||||
else if (get_right() < wrap_frame.get_left())
|
else if (get_right() < wrap_frame.left())
|
||||||
{
|
{
|
||||||
move({wrap_frame.get_w(), 0});
|
move({wrap_frame.width(), 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wrap.y)
|
if (wrap.y)
|
||||||
{
|
{
|
||||||
if (get_bottom() > wrap_frame.get_bottom())
|
if (get_bottom() > wrap_frame.bottom())
|
||||||
{
|
{
|
||||||
move({0, -wrap_frame.get_h()});
|
move({0, -wrap_frame.height()});
|
||||||
}
|
}
|
||||||
else if (get_bottom() < wrap_frame.get_top())
|
else if (get_bottom() < wrap_frame.top())
|
||||||
{
|
{
|
||||||
move({0, wrap_frame.get_h()});
|
move({0, wrap_frame.height()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return delta;
|
return delta;
|
||||||
|
@ -626,7 +626,7 @@ bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_T
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
collision_check_frame = sfw::duplicate_texture(
|
collision_check_frame = sfw::duplicate_texture(
|
||||||
const_cast<SDL_Renderer*>(get_renderer()), get_current_frame(), get_box(ii).get_size());
|
const_cast<SDL_Renderer*>(get_renderer()), get_current_frame(), get_box(ii).size());
|
||||||
}
|
}
|
||||||
Pixels region_pixels = Pixels(
|
Pixels region_pixels = Pixels(
|
||||||
const_cast<SDL_Renderer*>(get_renderer()), collision_check_frame, overlap->stamp(-get_nw(ii)));
|
const_cast<SDL_Renderer*>(get_renderer()), collision_check_frame, overlap->stamp(-get_nw(ii)));
|
||||||
|
@ -647,7 +647,7 @@ bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_T
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Pixels other_region_pixels = Pixels(
|
Pixels other_region_pixels = Pixels(
|
||||||
const_cast<SDL_Renderer*>(get_renderer()), other_texture, overlap->stamp(-box.get_nw()));
|
const_cast<SDL_Renderer*>(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 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++)
|
for (int y = 0; y < region_pixels.rect.h && y < other_region_pixels.rect.h; y++)
|
||||||
|
@ -711,7 +711,7 @@ bool Sprite::collide(const Sprite& sprite, bool precise, Box* overlap, bool all,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
other_sprite_collision_check_texture = sfw::duplicate_texture(
|
other_sprite_collision_check_texture = sfw::duplicate_texture(
|
||||||
const_cast<SDL_Renderer*>(get_renderer()), sprite.get_current_frame(), sprite.get_box(ii).get_size());
|
const_cast<SDL_Renderer*>(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))
|
if (collide(sprite.get_box(ii), precise, overlap, all, other_sprite_collision_check_texture))
|
||||||
|
@ -914,17 +914,17 @@ void Sprite::update()
|
||||||
|
|
||||||
void Sprite::render_subsection(SDL_Renderer* renderer, SDL_Texture* texture, const Box& subsection, const Box& box)
|
void Sprite::render_subsection(SDL_Renderer* renderer, SDL_Texture* texture, const Box& subsection, const Box& box)
|
||||||
{
|
{
|
||||||
bottom_save = std::round(subsection.get_bottom());
|
bottom_save = std::round(subsection.bottom());
|
||||||
subsection_int_rect = SDL_Rect(subsection);
|
subsection_int_rect = SDL_Rect(subsection);
|
||||||
subsection_int_rect.y += bottom_save - (subsection_int_rect.y + subsection_int_rect.h);
|
subsection_int_rect.y += bottom_save - (subsection_int_rect.y + subsection_int_rect.h);
|
||||||
subsection_destination = subsection_int_rect;
|
subsection_destination = subsection_int_rect;
|
||||||
subsection_destination.x += box.get_left();
|
subsection_destination.x += box.left();
|
||||||
subsection_destination.y += box.get_top();
|
subsection_destination.y += box.top();
|
||||||
if (get_scale() != 1)
|
if (get_scale() != 1)
|
||||||
{
|
{
|
||||||
unscaled_subsection = subsection;
|
unscaled_subsection = subsection;
|
||||||
unscaled_subsection.set_nw(unscaled_subsection.get_nw() / get_scale());
|
unscaled_subsection.nw(unscaled_subsection.nw() / get_scale());
|
||||||
unscaled_subsection.set_size(unscaled_subsection.get_size() / get_scale());
|
unscaled_subsection.size(unscaled_subsection.size() / get_scale());
|
||||||
subsection_int_rect = unscaled_subsection;
|
subsection_int_rect = unscaled_subsection;
|
||||||
}
|
}
|
||||||
SDL_RenderCopy(renderer, texture, &subsection_int_rect, &subsection_destination);
|
SDL_RenderCopy(renderer, texture, &subsection_int_rect, &subsection_destination);
|
||||||
|
|
|
@ -143,7 +143,7 @@ struct Sprite : Node
|
||||||
void render_subsection(SDL_Renderer*, SDL_Texture*, const Box&, const Box&);
|
void render_subsection(SDL_Renderer*, SDL_Texture*, const Box&, const Box&);
|
||||||
void set_to_leave_memory_allocated();
|
void set_to_leave_memory_allocated();
|
||||||
void set_to_deallocate_memory();
|
void set_to_deallocate_memory();
|
||||||
virtual std::string get_class_name() const { return "Sprite"; }
|
virtual std::string class_name() const { return "Sprite"; }
|
||||||
~Sprite() { unload(); }
|
~Sprite() { unload(); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,14 +73,14 @@ std::vector<std::vector<Box>> sfw::get_blinds_boxes(glm::vec2 size, float step,
|
||||||
float inflate_per_frame = blind_height * step;
|
float inflate_per_frame = blind_height * step;
|
||||||
std::vector<std::vector<Box>> frames;
|
std::vector<std::vector<Box>> frames;
|
||||||
float bottom_save;
|
float bottom_save;
|
||||||
while (blinds[0].get_h() < blind_height)
|
while (blinds[0].height() < blind_height)
|
||||||
{
|
{
|
||||||
frames.push_back({});
|
frames.push_back({});
|
||||||
for (Box& blind : blinds)
|
for (Box& blind : blinds)
|
||||||
{
|
{
|
||||||
bottom_save = blind.get_bottom();
|
bottom_save = blind.bottom();
|
||||||
blind.expand({0, inflate_per_frame});
|
blind.expand({0, inflate_per_frame});
|
||||||
blind.set_bottom(bottom_save);
|
blind.bottom(bottom_save);
|
||||||
frames.back().push_back(blind);
|
frames.back().push_back(blind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,8 +114,8 @@ void sfw::populate_pixel_2d_array(
|
||||||
{
|
{
|
||||||
Uint32 format = SDL_PIXELFORMAT_RGBA32;
|
Uint32 format = SDL_PIXELFORMAT_RGBA32;
|
||||||
int bytes_per_pixel = SDL_BYTESPERPIXEL(format);
|
int bytes_per_pixel = SDL_BYTESPERPIXEL(format);
|
||||||
int bytes_per_row = bytes_per_pixel * region.get_w();
|
int bytes_per_row = bytes_per_pixel * region.width();
|
||||||
int bytes_total = bytes_per_row * region.get_h();
|
int bytes_total = bytes_per_row * region.height();
|
||||||
Uint8* source = new Uint8[bytes_total];
|
Uint8* source = new Uint8[bytes_total];
|
||||||
SDL_Rect int_rect = region;
|
SDL_Rect int_rect = region;
|
||||||
if (SDL_RenderReadPixels(renderer, &int_rect, format, source, bytes_per_row) < 0)
|
if (SDL_RenderReadPixels(renderer, &int_rect, format, source, bytes_per_row) < 0)
|
||||||
|
@ -124,16 +124,16 @@ void sfw::populate_pixel_2d_array(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pixels.reserve(region.get_w());
|
pixels.reserve(region.width());
|
||||||
for (int x = 0; x < region.get_w(); x++)
|
for (int x = 0; x < region.width(); x++)
|
||||||
{
|
{
|
||||||
std::vector<SDL_Color> column;
|
std::vector<SDL_Color> column;
|
||||||
pixels.push_back(column);
|
pixels.push_back(column);
|
||||||
pixels[x].reserve(region.get_h());
|
pixels[x].reserve(region.height());
|
||||||
}
|
}
|
||||||
for (int y = 0, ii = 0; y < region.get_h(); y++)
|
for (int y = 0, ii = 0; y < region.height(); y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < region.get_w(); x++)
|
for (int x = 0; x < region.width(); x++)
|
||||||
{
|
{
|
||||||
pixels[x][y] = {source[ii++], source[ii++], source[ii++], source[ii++]};
|
pixels[x][y] = {source[ii++], source[ii++], source[ii++], source[ii++]};
|
||||||
}
|
}
|
||||||
|
@ -236,11 +236,11 @@ void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Texture
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int x = 0; x < texture_box.get_w(); x += tile_box.get_w())
|
for (int x = 0; x < texture_box.width(); x += tile_box.width())
|
||||||
{
|
{
|
||||||
for (int y = 0; y < texture_box.get_h(); y += tile_box.get_h())
|
for (int y = 0; y < texture_box.height(); y += tile_box.height())
|
||||||
{
|
{
|
||||||
draw_rect = {(float) x, (float) y, tile_box.get_w(), tile_box.get_h()};
|
draw_rect = {(float) x, (float) y, tile_box.width(), tile_box.height()};
|
||||||
SDL_RenderCopyF(renderer, tile, nullptr, &draw_rect);
|
SDL_RenderCopyF(renderer, tile, nullptr, &draw_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +328,7 @@ SDL_Texture* sfw::get_hue_shifted_texture(SDL_Renderer* renderer, SDL_Texture* b
|
||||||
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base)
|
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base)
|
||||||
{
|
{
|
||||||
Box box = get_texture_box(base);
|
Box box = get_texture_box(base);
|
||||||
return duplicate_texture(renderer, base, box.get_size());
|
return duplicate_texture(renderer, base, box.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, const glm::vec2& size)
|
SDL_Texture* sfw::duplicate_texture(SDL_Renderer* renderer, SDL_Texture* base, const glm::vec2& size)
|
||||||
|
@ -424,7 +424,7 @@ SDL_Texture* sfw::get_pixel_scaled_texture(SDL_Renderer* renderer, SDL_Texture*
|
||||||
print_sdl_error("could not set render target to remapped texture");
|
print_sdl_error("could not set render target to remapped texture");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
glm::ivec2 size = get_texture_box(base).get_size();
|
glm::ivec2 size = get_texture_box(base).size();
|
||||||
Uint32 format = SDL_PIXELFORMAT_RGBA32;
|
Uint32 format = SDL_PIXELFORMAT_RGBA32;
|
||||||
int bytes_per_pixel, bytes_per_row, bytes_total;
|
int bytes_per_pixel, bytes_per_row, bytes_total;
|
||||||
Uint32 *src, *dst, *src_begin, *dst_begin;
|
Uint32 *src, *dst, *src_begin, *dst_begin;
|
||||||
|
@ -516,11 +516,11 @@ SDL_Texture* sfw::get_pixel_scaled_texture(SDL_Renderer* renderer, SDL_Texture*
|
||||||
delete[] src_begin;
|
delete[] src_begin;
|
||||||
}
|
}
|
||||||
SDL_Texture* scaled = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
|
SDL_Texture* scaled = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, size.x, size.y);
|
||||||
if (scaled == NULL)
|
if (scaled == nullptr)
|
||||||
{
|
{
|
||||||
print_sdl_error("could not create scaled texture");
|
print_sdl_error("could not create scaled texture");
|
||||||
}
|
}
|
||||||
if (SDL_UpdateTexture(scaled, NULL, dst_begin, bytes_per_row * 2) < 0)
|
if (SDL_UpdateTexture(scaled, nullptr, dst_begin, bytes_per_row * 2) < 0)
|
||||||
{
|
{
|
||||||
print_sdl_error("could not copy pixels to scaled texture");
|
print_sdl_error("could not copy pixels to scaled texture");
|
||||||
}
|
}
|
||||||
|
@ -565,8 +565,7 @@ SDL_Surface* sfw::get_surface_from_pixels(Pixels& pixels)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path sfw::get_next_file_name(
|
fs::path sfw::get_next_file_name(fs::path directory, int zfill, std::string prefix, std::string extension)
|
||||||
fs::path directory, int zfill, std::string prefix, std::string extension)
|
|
||||||
{
|
{
|
||||||
std::stringstream file_pattern;
|
std::stringstream file_pattern;
|
||||||
file_pattern << prefix << "([0-9]+)" << extension;
|
file_pattern << prefix << "([0-9]+)" << extension;
|
||||||
|
@ -649,11 +648,11 @@ int lineColor(SDL_Renderer* renderer, const Segment& segment, const Color& color
|
||||||
{
|
{
|
||||||
if (thickness == 1)
|
if (thickness == 1)
|
||||||
{
|
{
|
||||||
return lineColor(renderer, segment.start.x, segment.start.y, segment.end.x, segment.end.y, color);
|
return lineColor(renderer, segment.start().x, segment.start().y, segment.end().x, segment.end().y, color);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return thickLineColor(renderer, segment.start.x, segment.start.y, segment.end.x, segment.end.y, thickness, color);
|
return thickLineColor(renderer, segment.start().x, segment.start().y, segment.end().x, segment.end().y, thickness, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace sfw
|
||||||
glm::vec2 point_on_circle(float, float = 1.0f);
|
glm::vec2 point_on_circle(float, float = 1.0f);
|
||||||
void points_on_circle(std::vector<glm::vec2>&, int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
|
void points_on_circle(std::vector<glm::vec2>&, int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
|
||||||
std::vector<glm::vec2> points_on_circle(int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
|
std::vector<glm::vec2> points_on_circle(int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
|
||||||
|
glm::vec2 map_rectangle_xy_to_circle(const glm::vec2&, float = 1.0f, const glm::vec2& = {0, 0});
|
||||||
Box get_texture_box(SDL_Texture*);
|
Box get_texture_box(SDL_Texture*);
|
||||||
glm::vec2 fit_and_preserve_aspect(const glm::vec2&, const glm::vec2&);
|
glm::vec2 fit_and_preserve_aspect(const glm::vec2&, const glm::vec2&);
|
||||||
std::vector<std::vector<Box>> get_blinds_boxes(glm::vec2, float = 0.05f, int = 4);
|
std::vector<std::vector<Box>> get_blinds_boxes(glm::vec2, float = 0.05f, int = 4);
|
||||||
|
|
Loading…
Reference in New Issue