Split sdlpp into smaller files
This commit is contained in:
parent
9890da4e06
commit
633502b189
27
sdlpp/Makefile
Normal file
27
sdlpp/Makefile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
CXX ?= g++
|
||||||
|
CPPFLAGS = -std=c++14 -Wall -Wextra -pedantic
|
||||||
|
LIBRARYFLAGS = -fPIC
|
||||||
|
|
||||||
|
MAJOR ?= 1
|
||||||
|
MINOR ?= 0
|
||||||
|
RELEASE ?= 0
|
||||||
|
|
||||||
|
SDLPPLIBRARY = libsdlpp.so.${MAJOR}.${MINOR}.${RELEASE}
|
||||||
|
|
||||||
|
OBJECTFILES = sdlpp_circlecolider.o sdlpp_circlerenderer.o sdlpp_collision.o sdlpp_common.o sdlpp_font.o sdlpp_linerenderer.o sdlpp_rectcolider.o sdlpp_rectrenderer.o sdlpp_renderer.o sdlpp_renderobject.o sdlpp_scene.o sdlpp_textrenderer.o sdlpp_texture.o sdlpp_window.o
|
||||||
|
|
||||||
|
all: ${SDLPPLIBRARY}
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
${CXX} ${CPPFLAGS} ${LIBRARYFLAGS} -c $< -o $@
|
||||||
|
|
||||||
|
${SDLPPLIBRARY}: ${OBJECTFILES}
|
||||||
|
${CXX} ${CPPFLAGS} -shared -Wl,-soname,libsdlpp.so.${MAJOR}\
|
||||||
|
-o ${SDLPPLIBRARY} $^
|
||||||
|
ln -sf ${SDLPPLIBRARY} libsdlpp.so
|
||||||
|
ln -sf ${SDLPPLIBRARY} libsdlpp.so.${MAJOR}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
${RM} *.so* *.o
|
||||||
|
|
||||||
|
.PHONY: all clean test
|
20
sdlpp/sdlpp.hpp
Normal file
20
sdlpp/sdlpp.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef SDLPP_HPP
|
||||||
|
#define SDLPP_HPP
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
|
||||||
|
#include "sdlpp_collision.hpp"
|
||||||
|
#include "sdlpp_circlecolider.hpp"
|
||||||
|
#include "sdlpp_circlerenderer.hpp"
|
||||||
|
#include "sdlpp_font.hpp"
|
||||||
|
#include "sdlpp_linerenderer.hpp"
|
||||||
|
#include "sdlpp_scene.hpp"
|
||||||
|
#include "sdlpp_rectcolider.hpp"
|
||||||
|
#include "sdlpp_rectrenderer.hpp"
|
||||||
|
#include "sdlpp_renderer.hpp"
|
||||||
|
#include "sdlpp_renderobject.hpp"
|
||||||
|
#include "sdlpp_textrenderer.hpp"
|
||||||
|
#include "sdlpp_texture.hpp"
|
||||||
|
#include "sdlpp_window.hpp"
|
||||||
|
|
||||||
|
#endif
|
133
sdlpp/sdlpp_circlecolider.cpp
Normal file
133
sdlpp/sdlpp_circlecolider.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// TODO render function like in rectangle
|
||||||
|
#include "sdlpp_circlecolider.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
CircleColider::CircleColider( double x, double y, double rad )
|
||||||
|
: CollisionPolygon( x, y ) {
|
||||||
|
original_rad = rad;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CircleColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
|
||||||
|
if ( other.isCircle() ) {
|
||||||
|
int otherRad = ( other.rightmost() - other.leftmost() ) / 2;
|
||||||
|
int thisRad = getRadius();
|
||||||
|
int totalDist = otherRad + thisRad;
|
||||||
|
int xdiff = other.leftmost() + otherRad - ( leftmost() + thisRad );
|
||||||
|
int ydiff = other.topmost() + otherRad - ( topmost() + thisRad );
|
||||||
|
return ( xdiff * xdiff + ydiff * ydiff ) <= totalDist * totalDist;
|
||||||
|
} else if ( other.isInfinite() ) {
|
||||||
|
return infinityIntersection( other, *this );
|
||||||
|
}
|
||||||
|
int rad = rad_;
|
||||||
|
int centerx = getX();
|
||||||
|
int centery = getY();
|
||||||
|
if ( other.topmost() <= centery && other.bottommost() >= centery ) {
|
||||||
|
return other.leftmost() <= rightmost() &&
|
||||||
|
other.rightmost() >= leftmost();
|
||||||
|
} else if ( other.leftmost() <= centerx && other.rightmost() >= centerx ) {
|
||||||
|
return other.topmost() <= bottommost() &&
|
||||||
|
other.bottommost() >= topmost();
|
||||||
|
}
|
||||||
|
int pointx = 0, pointy = 0;
|
||||||
|
if ( centerx > other.rightmost() ) {
|
||||||
|
pointx = other.rightmost();
|
||||||
|
} else {
|
||||||
|
pointx = other.leftmost();
|
||||||
|
}
|
||||||
|
if ( centery < other.topmost() ) {
|
||||||
|
pointy = other.topmost();
|
||||||
|
} else {
|
||||||
|
pointy = other.bottommost();
|
||||||
|
}
|
||||||
|
int distancesquared = ( pointx - centerx ) * ( pointx - centerx ) +
|
||||||
|
( pointy - centery ) * ( pointy - centery );
|
||||||
|
return distancesquared <= rad * rad;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CircleColider::isCircle() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int CircleColider::topmost() const {
|
||||||
|
return getY() - rad_;
|
||||||
|
}
|
||||||
|
int CircleColider::bottommost() const {
|
||||||
|
return getY() + rad_;
|
||||||
|
}
|
||||||
|
int CircleColider::leftmost() const {
|
||||||
|
return getX() - rad_;
|
||||||
|
}
|
||||||
|
int CircleColider::rightmost() const {
|
||||||
|
return getX() + rad_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CircleColider::updateCollision( int x, int y, int w, int h ) {
|
||||||
|
position_x = original_x * w + x;
|
||||||
|
position_y = original_y * h + y;
|
||||||
|
rad_ = original_rad * w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CircleColider::render( Renderer &renderer,
|
||||||
|
const std::tuple< int, int, int, int > &color ) {
|
||||||
|
std::vector< int > rect = { leftmost(), topmost(), rightmost(),
|
||||||
|
bottommost() };
|
||||||
|
auto center_x = getX();
|
||||||
|
auto center_y = getY();
|
||||||
|
auto radsq = rad_ * rad_;
|
||||||
|
for ( int i = rect[0]; i <= rect[2]; i++ ) {
|
||||||
|
auto xdiff = center_x - i;
|
||||||
|
auto xdist = xdiff * xdiff;
|
||||||
|
auto allowed_rad = sqrt( radsq - xdist );
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(),
|
||||||
|
std::get< 0 >( color ), std::get< 1 >( color ),
|
||||||
|
std::get< 2 >( color ), 0x40 );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||||
|
center_y - allowed_rad, i, center_y + allowed_rad );
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(),
|
||||||
|
std::get< 0 >( color ), std::get< 1 >( color ),
|
||||||
|
std::get< 2 >( color ), 0x80 );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||||
|
center_y - allowed_rad, i,
|
||||||
|
center_y - allowed_rad + 2 );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||||
|
center_y + allowed_rad, i,
|
||||||
|
center_y + allowed_rad - 2 );
|
||||||
|
}
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), 0xFF, 0, 0, 0xFF );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y,
|
||||||
|
center_x + rad_, center_y );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y, center_x,
|
||||||
|
center_y + rad_ );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y,
|
||||||
|
center_x - rad_, center_y );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y, center_x,
|
||||||
|
center_y - rad_ );
|
||||||
|
}
|
||||||
|
void CircleColider::render( Renderer &renderer ) {
|
||||||
|
std::vector< int > rect = { leftmost(), topmost(), rightmost(),
|
||||||
|
bottommost() };
|
||||||
|
auto center_x = getX();
|
||||||
|
auto center_y = getY();
|
||||||
|
auto radsq = rad_ * rad_;
|
||||||
|
for ( int i = rect[0]; i <= rect[2]; i++ ) {
|
||||||
|
auto xdiff = center_x - i;
|
||||||
|
auto xdist = xdiff * xdiff;
|
||||||
|
auto allowed_rad = sqrt( radsq - xdist );
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_color.r,
|
||||||
|
sdl_color.g, sdl_color.b, sdl_color.a );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||||
|
center_y - allowed_rad, i, center_y + allowed_rad );
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_outline.r,
|
||||||
|
sdl_outline.g, sdl_outline.b, sdl_outline.a );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||||
|
center_y - allowed_rad, i,
|
||||||
|
center_y - allowed_rad + 2 );
|
||||||
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||||
|
center_y + allowed_rad, i,
|
||||||
|
center_y + allowed_rad - 2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CircleColider::getRadius() const {
|
||||||
|
return rad_;
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
34
sdlpp/sdlpp_circlecolider.hpp
Normal file
34
sdlpp/sdlpp_circlecolider.hpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef SDLPP_HPP_CIRCLE
|
||||||
|
#define SDLPP_HPP_CIRCLE
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_collision.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class CircleColider : public CollisionPolygon {
|
||||||
|
public:
|
||||||
|
CircleColider( double x, double y, double rad );
|
||||||
|
virtual ~CircleColider() {}
|
||||||
|
|
||||||
|
virtual bool colidesWith( const CollisionPolygon &other ) const override;
|
||||||
|
virtual bool isCircle() const override;
|
||||||
|
virtual int topmost() const override;
|
||||||
|
virtual int bottommost() const override;
|
||||||
|
virtual int leftmost() const override;
|
||||||
|
virtual int rightmost() const override;
|
||||||
|
|
||||||
|
virtual void updateCollision( int x, int y, int w, int h ) override;
|
||||||
|
virtual void
|
||||||
|
render( Renderer &renderer,
|
||||||
|
const std::tuple< int, int, int, int > &color ) override;
|
||||||
|
virtual void render( Renderer &renderer ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int getRadius() const;
|
||||||
|
double original_rad;
|
||||||
|
int rad_;
|
||||||
|
};
|
||||||
|
} // namespace SDLPP
|
||||||
|
#endif
|
48
sdlpp/sdlpp_circlerenderer.cpp
Normal file
48
sdlpp/sdlpp_circlerenderer.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "sdlpp_circlerenderer.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
CircleRender::CircleRender( int x, int y, int rad,
|
||||||
|
std::shared_ptr< Renderer > &r )
|
||||||
|
: RenderObject( r ) {
|
||||||
|
x_ = x;
|
||||||
|
y_ = y;
|
||||||
|
rad_ = rad;
|
||||||
|
}
|
||||||
|
|
||||||
|
CircleRender::CircleRender( int x, int y, int rad,
|
||||||
|
std::shared_ptr< Renderer > &r,
|
||||||
|
std::shared_ptr< Texture > &t )
|
||||||
|
: CircleRender( x, y, rad, r ) {
|
||||||
|
setTexture( t );
|
||||||
|
}
|
||||||
|
|
||||||
|
CircleRender::CircleRender( int x, int y, int rad,
|
||||||
|
std::shared_ptr< Renderer > &r,
|
||||||
|
const std::string &img_path )
|
||||||
|
: CircleRender( x, y, rad, r ) {
|
||||||
|
auto texture = std::make_shared< Texture >( r, img_path );
|
||||||
|
setTexture( texture );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CircleRender::render() {
|
||||||
|
std::cout << "I'm a circle, look at me go!" << std::endl
|
||||||
|
<< "My dimensions are: [" << x_ << ", " << y_
|
||||||
|
<< "], radius: " << rad_ << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CircleRender::leftmost() {
|
||||||
|
return x_ - rad_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CircleRender::topmost() {
|
||||||
|
return y_ - rad_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CircleRender::collisionPushX() {
|
||||||
|
return x_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CircleRender::collisionPushY() {
|
||||||
|
return y_;
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
31
sdlpp/sdlpp_circlerenderer.hpp
Normal file
31
sdlpp/sdlpp_circlerenderer.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef SDLPP_HPP_CIRCLE_RENDERER
|
||||||
|
#define SDLPP_HPP_CIRCLE_RENDERER
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_renderobject.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class CircleRender : public RenderObject {
|
||||||
|
public:
|
||||||
|
CircleRender() = delete;
|
||||||
|
virtual ~CircleRender(){};
|
||||||
|
CircleRender( int x, int y, int rad, std::shared_ptr< Renderer > &r );
|
||||||
|
CircleRender( int x, int y, int rad, std::shared_ptr< Renderer > &r,
|
||||||
|
std::shared_ptr< Texture > &t );
|
||||||
|
CircleRender( int x, int y, int rad, std::shared_ptr< Renderer > &r,
|
||||||
|
const std::string &img_path );
|
||||||
|
virtual void render();
|
||||||
|
virtual int leftmost();
|
||||||
|
virtual int topmost();
|
||||||
|
virtual int collisionPushX();
|
||||||
|
virtual int collisionPushY();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int x_;
|
||||||
|
int y_;
|
||||||
|
int rad_;
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
60
sdlpp/sdlpp_collision.cpp
Normal file
60
sdlpp/sdlpp_collision.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "sdlpp_collision.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
CollisionPolygon::CollisionPolygon( double x, double y ) {
|
||||||
|
original_x = x;
|
||||||
|
original_y = y;
|
||||||
|
position_x = 0;
|
||||||
|
position_y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollisionPolygon::isInfinite() const {
|
||||||
|
return infinite;
|
||||||
|
}
|
||||||
|
void CollisionPolygon::setInfinite() {
|
||||||
|
infinite = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollisionPolygon::updateCollision( int x, int y, int w, int h ) {
|
||||||
|
position_x = original_x * w + x;
|
||||||
|
position_y = original_y * h + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CollisionPolygon::getX() const {
|
||||||
|
return position_x;
|
||||||
|
}
|
||||||
|
int CollisionPolygon::getY() const {
|
||||||
|
return position_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollisionPolygon::setColor( const std::string &color ) {
|
||||||
|
sdl_color = getSDLColorHEX( color );
|
||||||
|
}
|
||||||
|
void CollisionPolygon::setOutlineColor( const std::string &color ) {
|
||||||
|
sdl_outline = getSDLColorHEX( color );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infinityIntersection( const SDLPP::CollisionPolygon &infinite,
|
||||||
|
const SDLPP::CollisionPolygon &other ) {
|
||||||
|
int ileft = infinite.leftmost();
|
||||||
|
int iright = infinite.rightmost();
|
||||||
|
int itop = infinite.topmost();
|
||||||
|
int ibottom = infinite.bottommost();
|
||||||
|
bool ret =
|
||||||
|
ileft != -1 && ileft <= other.rightmost() && ileft >= other.leftmost();
|
||||||
|
ret |= iright != -1 && iright >= other.leftmost() &&
|
||||||
|
iright <= other.rightmost();
|
||||||
|
ret |= itop != -1 && itop <= other.bottommost() && itop >= other.topmost();
|
||||||
|
ret |= ibottom != -1 && ibottom >= other.topmost() &&
|
||||||
|
ibottom <= other.bottommost();
|
||||||
|
ret |= ileft == -1 && iright == -1 && itop == -1 && ibottom == -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool intersects( const SDLPP::CollisionPolygon &p1,
|
||||||
|
const SDLPP::CollisionPolygon &p2 ) {
|
||||||
|
return !(
|
||||||
|
p1.rightmost() < p2.leftmost() || p2.rightmost() < p1.leftmost() ||
|
||||||
|
p1.topmost() > p2.bottommost() || p2.topmost() > p1.bottommost() );
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
44
sdlpp/sdlpp_collision.hpp
Normal file
44
sdlpp/sdlpp_collision.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef SDLPP_HPP_COLLISION
|
||||||
|
#define SDLPP_HPP_COLLISION
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_renderer.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class CollisionPolygon {
|
||||||
|
public:
|
||||||
|
CollisionPolygon( double x, double y );
|
||||||
|
virtual ~CollisionPolygon() {}
|
||||||
|
virtual bool colidesWith( const CollisionPolygon &other ) const = 0;
|
||||||
|
virtual bool isCircle() const = 0;
|
||||||
|
virtual bool isInfinite() const;
|
||||||
|
virtual void setInfinite();
|
||||||
|
virtual int topmost() const = 0;
|
||||||
|
virtual int bottommost() const = 0;
|
||||||
|
virtual int leftmost() const = 0;
|
||||||
|
virtual int rightmost() const = 0;
|
||||||
|
virtual void updateCollision( int x, int y, int w, int h );
|
||||||
|
virtual void render( Renderer &renderer,
|
||||||
|
const std::tuple< int, int, int, int > &color ) = 0;
|
||||||
|
virtual void render( Renderer &renderer ) = 0;
|
||||||
|
int getX() const;
|
||||||
|
int getY() const;
|
||||||
|
void setColor( const std::string &color );
|
||||||
|
void setOutlineColor( const std::string &color );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double original_x;
|
||||||
|
double original_y;
|
||||||
|
int position_x;
|
||||||
|
int position_y;
|
||||||
|
bool infinite = false;
|
||||||
|
SDL_Color sdl_color = { 0, 0, 0, 0 };
|
||||||
|
SDL_Color sdl_outline = { 0, 0, 0, 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
bool infinityIntersection( const SDLPP::CollisionPolygon &infinite,
|
||||||
|
const SDLPP::CollisionPolygon &other );
|
||||||
|
bool intersects( const SDLPP::CollisionPolygon &p1,
|
||||||
|
const SDLPP::CollisionPolygon &p2 );
|
||||||
|
} // namespace SDLPP
|
||||||
|
#endif
|
122
sdlpp/sdlpp_common.cpp
Normal file
122
sdlpp/sdlpp_common.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "SDL2/SDL_image.h"
|
||||||
|
#else
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
#endif
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int SDLPP::hex2num( char c ) {
|
||||||
|
if ( c <= '9' )
|
||||||
|
return c - '0';
|
||||||
|
switch ( c ) {
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
return 10;
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
return 11;
|
||||||
|
case 'c':
|
||||||
|
case 'C':
|
||||||
|
return 12;
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
return 13;
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
return 14;
|
||||||
|
default:
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDLPP::init() {
|
||||||
|
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
|
||||||
|
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError()
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( IMG_Init( IMG_INIT_PNG ) != IMG_INIT_PNG ) {
|
||||||
|
std::cerr << "SDL_image could not initialize! SDL_image Error: "
|
||||||
|
<< IMG_GetError() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( TTF_Init() == -1 ) {
|
||||||
|
std::cerr << "SDL_ttf could not initialize! SDL_ttf Error: "
|
||||||
|
<< TTF_GetError() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDLPP::init( uint32_t SDL_OPTIONS ) {
|
||||||
|
if ( SDL_Init( SDL_OPTIONS ) < 0 ) {
|
||||||
|
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError()
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( IMG_Init( IMG_INIT_PNG ) != IMG_INIT_PNG ) {
|
||||||
|
std::cerr << "SDL_image could not initialize! SDL_image Error: "
|
||||||
|
<< IMG_GetError() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDLPP::init( uint32_t SDL_OPTIONS, int IMAGE_OPTIONS ) {
|
||||||
|
if ( SDL_Init( SDL_OPTIONS ) < 0 ) {
|
||||||
|
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError()
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( IMG_Init( IMAGE_OPTIONS ) != IMAGE_OPTIONS ) {
|
||||||
|
std::cerr << "SDL_image could not initialize! SDL_image Error: "
|
||||||
|
<< IMG_GetError() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple< int, int, int, int >
|
||||||
|
SDLPP::getColorsHEX( const std::string &color ) {
|
||||||
|
int red = 0, green = 0, blue = 0, alpha = 255;
|
||||||
|
const char *color_ptr = color.c_str();
|
||||||
|
if ( color_ptr[0] == '#' )
|
||||||
|
color_ptr++;
|
||||||
|
red = hex2num( color_ptr[0] ) * 16 + hex2num( color_ptr[1] );
|
||||||
|
green = hex2num( color_ptr[2] ) * 16 + hex2num( color_ptr[3] );
|
||||||
|
blue = hex2num( color_ptr[4] ) * 16 + hex2num( color_ptr[5] );
|
||||||
|
if ( color_ptr[6] != '\0' )
|
||||||
|
alpha = hex2num( color_ptr[6] ) * 16 + hex2num( color_ptr[7] );
|
||||||
|
return { red, green, blue, alpha };
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Color
|
||||||
|
SDLPP::getSDLColorTuple( const std::tuple< int, int, int, int > &tuple ) {
|
||||||
|
SDL_Color ret_color{};
|
||||||
|
ret_color.r = std::get< 0 >( tuple );
|
||||||
|
ret_color.g = std::get< 1 >( tuple );
|
||||||
|
ret_color.b = std::get< 2 >( tuple );
|
||||||
|
ret_color.a = std::get< 3 >( tuple );
|
||||||
|
return ret_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Color SDLPP::getSDLColorHEX( const std::string &color ) {
|
||||||
|
auto color_tuple = SDLPP::getColorsHEX( color );
|
||||||
|
return getSDLColorTuple( color_tuple );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple< int, int, int, int >
|
||||||
|
SDLPP::getColorsSDLColor( const SDL_Color &color ) {
|
||||||
|
return { color.r, color.g, color.b, color.a };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDLPP::getSDLEvent( SDL_Event &e ) {
|
||||||
|
if ( SDL_PeepEvents( &e, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT,
|
||||||
|
SDL_LASTEVENT ) == 1 ) {
|
||||||
|
SDL_PeepEvents( &e, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
38
sdlpp/sdlpp_common.hpp
Normal file
38
sdlpp/sdlpp_common.hpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef SDLPP_HPP_COMMON
|
||||||
|
#define SDLPP_HPP_COMMON
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "SDL2/SDL.h"
|
||||||
|
#include "SDL2/SDL_image.h"
|
||||||
|
#include "SDL2/SDL_ttf.h"
|
||||||
|
#else
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
#endif // UNIX
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#define SDLPP_TEXT_LEFT 0x0001
|
||||||
|
#define SDLPP_TEXT_RIGHT 0x0002
|
||||||
|
#define SDLPP_TEXT_CENTER 0x0004
|
||||||
|
#define SDLPP_TEXT_TOP 0x0008
|
||||||
|
#define SDLPP_TEXT_BOTTOM 0x0010
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
|
||||||
|
int hex2num( char c );
|
||||||
|
|
||||||
|
bool init();
|
||||||
|
bool init( uint32_t SDL_OPTIONS );
|
||||||
|
bool init( uint32_t SDL_OPTIONS, int IMAGE_OPTIONS );
|
||||||
|
|
||||||
|
std::tuple< int, int, int, int > getColorsHEX( const std::string &color );
|
||||||
|
SDL_Color getSDLColorHEX( const std::string &color );
|
||||||
|
std::tuple< int, int, int, int > getColorsSDLColor( const SDL_Color &color );
|
||||||
|
SDL_Color getSDLColorTuple( const std::tuple< int, int, int, int > &tuple );
|
||||||
|
|
||||||
|
bool getSDLEvent( SDL_Event &e );
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
33
sdlpp/sdlpp_font.cpp
Normal file
33
sdlpp/sdlpp_font.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "sdlpp_font.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
Font::Font( const std::string &font, int size ) {
|
||||||
|
font_ptr = TTF_OpenFont( font.c_str(), size );
|
||||||
|
if ( font_ptr == NULL ) {
|
||||||
|
std::cerr << "Unable to load font '" << font
|
||||||
|
<< "': TTF Error: " << TTF_GetError() << std::endl;
|
||||||
|
throw "TTF_OpenFont error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Font::~Font() {
|
||||||
|
TTF_CloseFont( font_ptr );
|
||||||
|
}
|
||||||
|
const TTF_Font *Font::getFont() const {
|
||||||
|
return font_ptr;
|
||||||
|
}
|
||||||
|
TTF_Font *Font::getFont() {
|
||||||
|
return font_ptr;
|
||||||
|
}
|
||||||
|
void Font::setOutline( int size ) {
|
||||||
|
TTF_SetFontOutline( font_ptr, size );
|
||||||
|
}
|
||||||
|
int Font::getOutline() {
|
||||||
|
return TTF_GetFontOutline( font_ptr );
|
||||||
|
}
|
||||||
|
void Font::setStyle( int style ) {
|
||||||
|
TTF_SetFontStyle( font_ptr, style );
|
||||||
|
}
|
||||||
|
void Font::setHinting( int hinting ) {
|
||||||
|
TTF_SetFontHinting( font_ptr, hinting );
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
25
sdlpp/sdlpp_font.hpp
Normal file
25
sdlpp/sdlpp_font.hpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef SDLPP_HPP_FONT
|
||||||
|
#define SDLPP_HPP_FONT
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class Font {
|
||||||
|
public:
|
||||||
|
Font() = delete;
|
||||||
|
Font( const std::string &font, int size );
|
||||||
|
virtual ~Font();
|
||||||
|
const TTF_Font *getFont() const;
|
||||||
|
TTF_Font *getFont();
|
||||||
|
void setOutline( int size );
|
||||||
|
int getOutline();
|
||||||
|
void setStyle( int style );
|
||||||
|
void setHinting( int hinting );
|
||||||
|
|
||||||
|
private:
|
||||||
|
TTF_Font *font_ptr;
|
||||||
|
};
|
||||||
|
} // namespace SDLPP
|
||||||
|
#endif
|
149
sdlpp/sdlpp_linerenderer.cpp
Normal file
149
sdlpp/sdlpp_linerenderer.cpp
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#include "sdlpp_linerenderer.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
LineRenderer::LineRenderer( double x1, double y1, double x2, double y2,
|
||||||
|
const std::shared_ptr< Renderer > &r )
|
||||||
|
: RenderObject( r ) {
|
||||||
|
og_x1 = x1_ = x1;
|
||||||
|
og_y1 = y1_ = y1;
|
||||||
|
og_x2 = x2_ = x2;
|
||||||
|
og_y2 = y2_ = y2;
|
||||||
|
updateSizeAndPosition();
|
||||||
|
}
|
||||||
|
LineRenderer::LineRenderer( double x1, double y1, double x2, double y2,
|
||||||
|
const std::shared_ptr< Renderer > &r,
|
||||||
|
const std::string &color )
|
||||||
|
: LineRenderer( x1, y1, x2, y2, r ) {
|
||||||
|
setColor( color );
|
||||||
|
}
|
||||||
|
void LineRenderer::setColor( const std::string &color ) {
|
||||||
|
_color = getColorsHEX( color );
|
||||||
|
}
|
||||||
|
void LineRenderer::render() {
|
||||||
|
if ( !getHidden() ) {
|
||||||
|
SDL_SetRenderDrawColor(
|
||||||
|
renderer->getRendererPtr(), std::get< 0 >( _color ),
|
||||||
|
std::get< 1 >( _color ), std::get< 2 >( _color ),
|
||||||
|
std::get< 3 >( _color ) );
|
||||||
|
SDL_RenderDrawLine( renderer->getRendererPtr(), pixel_x1, pixel_y1,
|
||||||
|
pixel_x2, pixel_y2 );
|
||||||
|
}
|
||||||
|
if ( hasCollisions() && renderer->getRenderColiders() && !getHidden() ) {
|
||||||
|
for ( const auto &col : getCollisions() )
|
||||||
|
col->render( *renderer, colider_color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void LineRenderer::move( int ticks ) {
|
||||||
|
if ( permanent )
|
||||||
|
return;
|
||||||
|
auto addx =
|
||||||
|
static_cast< double >( movementSpeed * movementDirection.first ) *
|
||||||
|
( static_cast< double >( ticks ) / 1000 );
|
||||||
|
auto addy =
|
||||||
|
static_cast< double >( movementSpeed * movementDirection.second ) *
|
||||||
|
( static_cast< double >( ticks ) / 1000 );
|
||||||
|
if ( std::isnan( addx ) || std::isnan( addy ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
og_x1 += addx;
|
||||||
|
og_x2 += addx;
|
||||||
|
og_y1 += addy;
|
||||||
|
og_y2 += addy;
|
||||||
|
|
||||||
|
custom_move( ticks );
|
||||||
|
|
||||||
|
updateSizeAndPosition();
|
||||||
|
}
|
||||||
|
void LineRenderer::setPos( double x, double y ) {
|
||||||
|
auto diffx = og_x2 - og_x1;
|
||||||
|
auto diffy = og_y2 - og_y1;
|
||||||
|
og_x1 = x;
|
||||||
|
og_y1 = y;
|
||||||
|
og_x2 = og_x1 + diffx;
|
||||||
|
og_y2 = og_y1 + diffy;
|
||||||
|
updateSizeAndPosition();
|
||||||
|
}
|
||||||
|
void LineRenderer::setPos( const std::pair< double, double > &pos ) {
|
||||||
|
setPos( pos.first, pos.second );
|
||||||
|
}
|
||||||
|
std::pair< double, double > LineRenderer::getPos() const {
|
||||||
|
return { og_x1, og_y1 };
|
||||||
|
}
|
||||||
|
int LineRenderer::leftmost() {
|
||||||
|
return pixel_x1 < pixel_x2 ? pixel_x1 : pixel_x2;
|
||||||
|
}
|
||||||
|
int LineRenderer::topmost() {
|
||||||
|
return pixel_y1 < pixel_y2 ? pixel_y1 : pixel_y2;
|
||||||
|
}
|
||||||
|
int LineRenderer::rightmost() {
|
||||||
|
return pixel_x1 > pixel_x2 ? pixel_x1 : pixel_x2;
|
||||||
|
}
|
||||||
|
int LineRenderer::bottommost() {
|
||||||
|
return pixel_y1 > pixel_y2 ? pixel_y1 : pixel_y2;
|
||||||
|
}
|
||||||
|
int LineRenderer::collisionPushX() {
|
||||||
|
return leftmost();
|
||||||
|
}
|
||||||
|
int LineRenderer::collisionPushY() {
|
||||||
|
return topmost();
|
||||||
|
}
|
||||||
|
int LineRenderer::collisionWidth() {
|
||||||
|
return rightmost() - leftmost();
|
||||||
|
}
|
||||||
|
int LineRenderer::collisionHeight() {
|
||||||
|
return bottommost() - topmost();
|
||||||
|
}
|
||||||
|
void LineRenderer::updateSizeAndPosition() {
|
||||||
|
updateXY();
|
||||||
|
auto dimension = renderer->getSmallerSide();
|
||||||
|
pixel_x1 = std::round( x1_ * dimension );
|
||||||
|
pixel_x2 = std::round( x2_ * dimension );
|
||||||
|
pixel_y1 = std::round( y1_ * dimension );
|
||||||
|
pixel_y2 = std::round( y2_ * dimension );
|
||||||
|
for ( auto &x : collisions ) {
|
||||||
|
x->updateCollision( collisionPushX(), collisionPushY(),
|
||||||
|
collisionWidth(), collisionHeight() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void LineRenderer::centerX() {
|
||||||
|
centerx = true;
|
||||||
|
updateSizeAndPosition();
|
||||||
|
}
|
||||||
|
std::shared_ptr< RenderObject > LineRenderer::copySelf() {
|
||||||
|
// TODO ACTUALLY copy, don't just copy pointers to textures and whatnot,
|
||||||
|
// create new textures!!!
|
||||||
|
return std::make_shared< LineRenderer >( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Rect LineRenderer::getRect() {
|
||||||
|
return { leftmost(), topmost(), rightmost() - leftmost(),
|
||||||
|
bottommost() - topmost() };
|
||||||
|
}
|
||||||
|
std::pair< std::pair< double, double >, std::pair< double, double > >
|
||||||
|
LineRenderer::getDoubleRect() const {
|
||||||
|
return { { og_x1, og_y1 }, { og_x2 - og_x1, og_y2 - og_y1 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineRenderer::updateXY() {
|
||||||
|
if ( !centerx ) {
|
||||||
|
x1_ = og_x1;
|
||||||
|
y1_ = og_y1;
|
||||||
|
x2_ = og_x2;
|
||||||
|
y2_ = og_y2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto width = renderer->getWidth();
|
||||||
|
auto height = renderer->getHeight();
|
||||||
|
if ( width > height ) {
|
||||||
|
auto multiplier =
|
||||||
|
static_cast< double >( width ) / static_cast< double >( height );
|
||||||
|
x1_ = og_x1 + static_cast< double >( multiplier - 1 ) / 2;
|
||||||
|
x2_ = og_x2 + static_cast< double >( multiplier - 1 ) / 2;
|
||||||
|
} else {
|
||||||
|
x1_ = og_x1;
|
||||||
|
x2_ = og_x2;
|
||||||
|
}
|
||||||
|
y1_ = og_y1;
|
||||||
|
y2_ = og_y2;
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
61
sdlpp/sdlpp_linerenderer.hpp
Normal file
61
sdlpp/sdlpp_linerenderer.hpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef SDLPP_HPP_LINE_RENDERER
|
||||||
|
#define SDLPP_HPP_LINE_RENDERER
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_renderobject.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class LineRenderer : public RenderObject {
|
||||||
|
public:
|
||||||
|
LineRenderer() = delete;
|
||||||
|
virtual ~LineRenderer(){};
|
||||||
|
LineRenderer( double x1, double y1, double x2, double y2,
|
||||||
|
const std::shared_ptr< Renderer > &r );
|
||||||
|
LineRenderer( double x1, double y1, double x2, double y2,
|
||||||
|
const std::shared_ptr< Renderer > &r,
|
||||||
|
const std::string &color );
|
||||||
|
virtual void setColor( const std::string &color ) override;
|
||||||
|
virtual void specialAction( int /*UNUSED*/ ) override{};
|
||||||
|
virtual void render() override;
|
||||||
|
virtual void move( int ticks ) override;
|
||||||
|
virtual void custom_move( int /*UNUSED*/ ) override {}
|
||||||
|
virtual void setPos( double x, double y ) override;
|
||||||
|
virtual void setPos( const std::pair< double, double > &pos ) override;
|
||||||
|
virtual std::pair< double, double > getPos() const override;
|
||||||
|
virtual int leftmost() override;
|
||||||
|
virtual int topmost() override;
|
||||||
|
virtual int rightmost() override;
|
||||||
|
virtual int bottommost() override;
|
||||||
|
virtual int collisionPushX() override;
|
||||||
|
virtual int collisionPushY() override;
|
||||||
|
virtual int collisionWidth() override;
|
||||||
|
virtual int collisionHeight() override;
|
||||||
|
virtual void updateSizeAndPosition() override;
|
||||||
|
virtual void centerX() override;
|
||||||
|
virtual std::shared_ptr< RenderObject > copySelf() override;
|
||||||
|
|
||||||
|
virtual SDL_Rect getRect() override;
|
||||||
|
virtual std::pair< std::pair< double, double >,
|
||||||
|
std::pair< double, double > >
|
||||||
|
getDoubleRect() const override;
|
||||||
|
void setOutlineColor( const std::string & /*UNUSED*/ ) override {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateXY();
|
||||||
|
double og_x1;
|
||||||
|
double og_y1;
|
||||||
|
double x1_;
|
||||||
|
double y1_;
|
||||||
|
double og_x2;
|
||||||
|
double og_y2;
|
||||||
|
double x2_;
|
||||||
|
double y2_;
|
||||||
|
int pixel_x1{};
|
||||||
|
int pixel_y1{};
|
||||||
|
int pixel_x2{};
|
||||||
|
int pixel_y2{};
|
||||||
|
bool centerx = false;
|
||||||
|
std::tuple< int, int, int, int > _color;
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
91
sdlpp/sdlpp_rectcolider.cpp
Normal file
91
sdlpp/sdlpp_rectcolider.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "sdlpp_rectcolider.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
RectColider::RectColider( double x, double y, double w, double h )
|
||||||
|
: CollisionPolygon( x, y ) {
|
||||||
|
w_ = w;
|
||||||
|
h_ = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RectColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
|
||||||
|
if ( other.isCircle() ) {
|
||||||
|
return other.colidesWith( *this );
|
||||||
|
}
|
||||||
|
if ( other.isInfinite() ) {
|
||||||
|
return infinityIntersection( other, *this );
|
||||||
|
}
|
||||||
|
if ( isInfinite() )
|
||||||
|
return infinityIntersection( *this, other );
|
||||||
|
return intersects( *this, other );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RectColider::isCircle() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int RectColider::topmost() const {
|
||||||
|
return ( !isInfinite() || original_y != -1 ) * getY() + isInfinite() * -1;
|
||||||
|
}
|
||||||
|
int RectColider::bottommost() const {
|
||||||
|
return ( !isInfinite() || h_ != -1 ) * ( getY() + pixel_h ) +
|
||||||
|
isInfinite() * -1;
|
||||||
|
}
|
||||||
|
int RectColider::leftmost() const {
|
||||||
|
return ( !isInfinite() || original_x != -1 ) * getX() + isInfinite() * -1;
|
||||||
|
}
|
||||||
|
int RectColider::rightmost() const {
|
||||||
|
return ( !isInfinite() || w_ != -1 ) * ( getX() + pixel_w ) +
|
||||||
|
isInfinite() * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RectColider::updateCollision( int x, int y, int w, int h ) {
|
||||||
|
position_x = original_x * w + x;
|
||||||
|
position_y = original_y * h + y;
|
||||||
|
pixel_w = w_ * w;
|
||||||
|
pixel_h = h_ * h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RectColider::render( Renderer &renderer,
|
||||||
|
const std::tuple< int, int, int, int > &color ) {
|
||||||
|
auto rect = getRect();
|
||||||
|
// outline with desired color at 50% opacity
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), std::get< 0 >( color ),
|
||||||
|
std::get< 1 >( color ), std::get< 2 >( color ),
|
||||||
|
0x80 );
|
||||||
|
SDL_RenderDrawRect( renderer.getRendererPtr(), &rect );
|
||||||
|
// fill with desired color at 25% opacity
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), std::get< 0 >( color ),
|
||||||
|
std::get< 1 >( color ), std::get< 2 >( color ),
|
||||||
|
0x40 );
|
||||||
|
SDL_RenderFillRect( renderer.getRendererPtr(), &rect );
|
||||||
|
}
|
||||||
|
|
||||||
|
void RectColider::render( Renderer &renderer ) {
|
||||||
|
auto rect = getRect();
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_color.r, sdl_color.g,
|
||||||
|
sdl_color.b, sdl_color.a );
|
||||||
|
SDL_RenderFillRect( renderer.getRendererPtr(), &rect );
|
||||||
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_outline.r,
|
||||||
|
sdl_outline.g, sdl_outline.b, sdl_outline.a );
|
||||||
|
SDL_RenderDrawRect( renderer.getRendererPtr(), &rect );
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Rect RectColider::getRect() {
|
||||||
|
if ( !isInfinite() )
|
||||||
|
return { leftmost(), topmost(), pixel_w, pixel_h };
|
||||||
|
|
||||||
|
SDL_Rect r = { 0, 0, 0, 0 };
|
||||||
|
if ( ( r.x = leftmost() ) == -1 )
|
||||||
|
r.x = 0;
|
||||||
|
if ( ( r.y = topmost() ) == -1 )
|
||||||
|
r.y = 0;
|
||||||
|
if ( rightmost() == -1 )
|
||||||
|
r.w = std::numeric_limits< int >::max();
|
||||||
|
else
|
||||||
|
r.w = pixel_w;
|
||||||
|
if ( bottommost() == -1 )
|
||||||
|
r.h = std::numeric_limits< int >::max();
|
||||||
|
else
|
||||||
|
r.h = pixel_h;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
35
sdlpp/sdlpp_rectcolider.hpp
Normal file
35
sdlpp/sdlpp_rectcolider.hpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef SDLPP_HPP_RECT_COLIDER
|
||||||
|
#define SDLPP_HPP_RECT_COLIDER
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_collision.hpp"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class RectColider : public CollisionPolygon {
|
||||||
|
public:
|
||||||
|
RectColider( double x, double y, double w, double h );
|
||||||
|
virtual ~RectColider() {}
|
||||||
|
virtual bool colidesWith( const CollisionPolygon &other ) const override;
|
||||||
|
virtual bool isCircle() const override;
|
||||||
|
virtual int topmost() const override;
|
||||||
|
virtual int bottommost() const override;
|
||||||
|
virtual int leftmost() const override;
|
||||||
|
virtual int rightmost() const override;
|
||||||
|
virtual void updateCollision( int x, int y, int w, int h ) override;
|
||||||
|
virtual void
|
||||||
|
render( Renderer &renderer,
|
||||||
|
const std::tuple< int, int, int, int > &color ) override;
|
||||||
|
virtual void render( Renderer &renderer ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDL_Rect getRect();
|
||||||
|
|
||||||
|
double w_;
|
||||||
|
double h_;
|
||||||
|
int pixel_w;
|
||||||
|
int pixel_h;
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
166
sdlpp/sdlpp_rectrenderer.cpp
Normal file
166
sdlpp/sdlpp_rectrenderer.cpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#include "sdlpp_rectrenderer.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
RectangleRender::RectangleRender( double x, double y, double w, double h,
|
||||||
|
const std::shared_ptr< Renderer > &r )
|
||||||
|
: RenderObject( r ) {
|
||||||
|
og_x = x_ = x;
|
||||||
|
og_y = y_ = y;
|
||||||
|
og_w = w_ = w;
|
||||||
|
og_h = h_ = h;
|
||||||
|
updateSizeAndPosition();
|
||||||
|
}
|
||||||
|
RectangleRender::RectangleRender( double x, double y, double w, double h,
|
||||||
|
const std::shared_ptr< Renderer > &r,
|
||||||
|
const std::shared_ptr< Texture > &t )
|
||||||
|
: RectangleRender( x, y, w, h, r ) {
|
||||||
|
setTexture( t );
|
||||||
|
}
|
||||||
|
RectangleRender::RectangleRender( double x, double y, double w, double h,
|
||||||
|
const std::shared_ptr< Renderer > &r,
|
||||||
|
const std::string &img_or_color,
|
||||||
|
bool is_polygon )
|
||||||
|
: RectangleRender( x, y, w, h, r ) {
|
||||||
|
if ( !is_polygon ) {
|
||||||
|
setTexture( img_or_color );
|
||||||
|
} else {
|
||||||
|
setColor( img_or_color );
|
||||||
|
color = img_or_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void RectangleRender::setColor( const std::string &color ) {
|
||||||
|
if ( !polygon ) {
|
||||||
|
polygon = std::make_shared< RectColider >( 0, 0, 1, 1 );
|
||||||
|
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||||
|
collisionWidth(), collisionHeight() );
|
||||||
|
}
|
||||||
|
polygon->setColor( color );
|
||||||
|
}
|
||||||
|
void RectangleRender::setOutlineColor( const std::string &color ) {
|
||||||
|
if ( !polygon ) {
|
||||||
|
polygon = std::make_shared< RectColider >( 0, 0, 1, 1 );
|
||||||
|
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||||
|
collisionWidth(), collisionHeight() );
|
||||||
|
}
|
||||||
|
polygon->setOutlineColor( color );
|
||||||
|
}
|
||||||
|
void RectangleRender::render() {
|
||||||
|
if ( !getHidden() ) {
|
||||||
|
if ( polygon )
|
||||||
|
polygon->render( *renderer );
|
||||||
|
if ( texture != NULL )
|
||||||
|
SDL_RenderCopy( renderer->getRendererPtr(),
|
||||||
|
texture->getTexturePtr(), NULL, &rect );
|
||||||
|
}
|
||||||
|
if ( hasCollisions() && renderer->getRenderColiders() && !getHidden() ) {
|
||||||
|
for ( const auto &col : getCollisions() )
|
||||||
|
col->render( *renderer, colider_color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void RectangleRender::move( int ticks ) {
|
||||||
|
if ( permanent )
|
||||||
|
return;
|
||||||
|
auto addx =
|
||||||
|
static_cast< double >( movementSpeed * movementDirection.first ) *
|
||||||
|
( static_cast< double >( ticks ) / 1000 );
|
||||||
|
auto addy =
|
||||||
|
static_cast< double >( movementSpeed * movementDirection.second ) *
|
||||||
|
( static_cast< double >( ticks ) / 1000 );
|
||||||
|
if ( std::isnan( addx ) || std::isnan( addy ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
og_x += addx;
|
||||||
|
og_y += addy;
|
||||||
|
|
||||||
|
custom_move( ticks );
|
||||||
|
|
||||||
|
updateSizeAndPosition();
|
||||||
|
}
|
||||||
|
std::pair< std::pair< double, double >, std::pair< double, double > >
|
||||||
|
RectangleRender::getDoubleRect() const {
|
||||||
|
return { { og_x, og_y }, { og_w, og_h } };
|
||||||
|
}
|
||||||
|
void RectangleRender::setPos( double x, double y ) {
|
||||||
|
og_x = x;
|
||||||
|
og_y = y;
|
||||||
|
updateSizeAndPosition();
|
||||||
|
}
|
||||||
|
void RectangleRender::setPos( const std::pair< double, double > &pos ) {
|
||||||
|
setPos( pos.first, pos.second );
|
||||||
|
}
|
||||||
|
std::pair< double, double > RectangleRender::getPos() const {
|
||||||
|
return { og_x, og_y };
|
||||||
|
}
|
||||||
|
int RectangleRender::leftmost() {
|
||||||
|
return rect.x;
|
||||||
|
}
|
||||||
|
int RectangleRender::topmost() {
|
||||||
|
return rect.y;
|
||||||
|
}
|
||||||
|
int RectangleRender::rightmost() {
|
||||||
|
return rect.x + rect.w;
|
||||||
|
}
|
||||||
|
int RectangleRender::bottommost() {
|
||||||
|
return rect.y + rect.h;
|
||||||
|
}
|
||||||
|
int RectangleRender::collisionPushX() {
|
||||||
|
return rect.x;
|
||||||
|
}
|
||||||
|
int RectangleRender::collisionPushY() {
|
||||||
|
return rect.y;
|
||||||
|
}
|
||||||
|
int RectangleRender::collisionWidth() {
|
||||||
|
return rect.w;
|
||||||
|
}
|
||||||
|
int RectangleRender::collisionHeight() {
|
||||||
|
return rect.h;
|
||||||
|
}
|
||||||
|
void RectangleRender::updateSizeAndPosition() {
|
||||||
|
updateXY();
|
||||||
|
auto dimension = renderer->getSmallerSide();
|
||||||
|
rect.x = std::round( x_ * dimension );
|
||||||
|
rect.y = std::round( y_ * dimension );
|
||||||
|
rect.w = std::round( ( x_ + w_ ) * dimension ) - rect.x;
|
||||||
|
rect.h = std::round( ( y_ + h_ ) * dimension ) - rect.y;
|
||||||
|
if ( polygon )
|
||||||
|
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||||
|
collisionWidth(), collisionHeight() );
|
||||||
|
for ( auto &x : collisions ) {
|
||||||
|
x->updateCollision( collisionPushX(), collisionPushY(),
|
||||||
|
collisionWidth(), collisionHeight() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_Rect RectangleRender::getRect() {
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
void RectangleRender::centerX() {
|
||||||
|
centerx = true;
|
||||||
|
updateSizeAndPosition();
|
||||||
|
}
|
||||||
|
std::shared_ptr< RenderObject > RectangleRender::copySelf() {
|
||||||
|
// TODO ACTUALLY copy, don't just copy pointers to textures and whatnot,
|
||||||
|
// create new textures!!!
|
||||||
|
return std::make_shared< RectangleRender >( *this );
|
||||||
|
}
|
||||||
|
std::string RectangleRender::getColor() const {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RectangleRender::updateXY() {
|
||||||
|
if ( !centerx ) {
|
||||||
|
x_ = og_x;
|
||||||
|
y_ = og_y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto width = renderer->getWidth();
|
||||||
|
auto height = renderer->getHeight();
|
||||||
|
if ( width > height ) {
|
||||||
|
auto multiplier =
|
||||||
|
static_cast< double >( width ) / static_cast< double >( height );
|
||||||
|
x_ = og_x + static_cast< double >( multiplier - 1 ) / 2;
|
||||||
|
} else {
|
||||||
|
x_ = og_x;
|
||||||
|
}
|
||||||
|
y_ = og_y;
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
62
sdlpp/sdlpp_rectrenderer.hpp
Normal file
62
sdlpp/sdlpp_rectrenderer.hpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#ifndef SDLPP_HPP_RECT_RENDERER
|
||||||
|
#define SDLPP_HPP_RECT_RENDERER
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_renderobject.hpp"
|
||||||
|
#include "sdlpp_rectcolider.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class RectangleRender : public RenderObject {
|
||||||
|
public:
|
||||||
|
RectangleRender() = delete;
|
||||||
|
virtual ~RectangleRender(){};
|
||||||
|
RectangleRender( double x, double y, double w, double h,
|
||||||
|
const std::shared_ptr< Renderer > &r );
|
||||||
|
RectangleRender( double x, double y, double w, double h,
|
||||||
|
const std::shared_ptr< Renderer > &r,
|
||||||
|
const std::shared_ptr< Texture > &t );
|
||||||
|
RectangleRender( double x, double y, double w, double h,
|
||||||
|
const std::shared_ptr< Renderer > &r,
|
||||||
|
const std::string &img_or_color, bool is_polygon = false );
|
||||||
|
virtual void setColor( const std::string &color ) override;
|
||||||
|
virtual void setOutlineColor( const std::string &color ) override;
|
||||||
|
virtual void specialAction( int /*UNUSED*/ ) override{};
|
||||||
|
virtual void render() override;
|
||||||
|
virtual void move( int ticks ) override;
|
||||||
|
virtual void custom_move( int /*UNUSED*/ ) override {}
|
||||||
|
virtual std::pair< std::pair< double, double >,
|
||||||
|
std::pair< double, double > >
|
||||||
|
getDoubleRect() const override;
|
||||||
|
virtual void setPos( double x, double y ) override;
|
||||||
|
virtual void setPos( const std::pair< double, double > &pos ) override;
|
||||||
|
virtual std::pair< double, double > getPos() const override;
|
||||||
|
virtual int leftmost() override;
|
||||||
|
virtual int topmost() override;
|
||||||
|
virtual int rightmost() override;
|
||||||
|
virtual int bottommost() override;
|
||||||
|
virtual int collisionPushX() override;
|
||||||
|
virtual int collisionPushY() override;
|
||||||
|
virtual int collisionWidth() override;
|
||||||
|
virtual int collisionHeight() override;
|
||||||
|
virtual void updateSizeAndPosition() override;
|
||||||
|
virtual SDL_Rect getRect() override;
|
||||||
|
virtual void centerX() override;
|
||||||
|
virtual std::shared_ptr< RenderObject > copySelf() override;
|
||||||
|
std::string getColor() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateXY();
|
||||||
|
double og_x;
|
||||||
|
double og_y;
|
||||||
|
double og_w;
|
||||||
|
double og_h;
|
||||||
|
double x_;
|
||||||
|
double y_;
|
||||||
|
double w_;
|
||||||
|
double h_;
|
||||||
|
bool centerx = false;
|
||||||
|
SDL_Rect rect;
|
||||||
|
std::string color = "";
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
56
sdlpp/sdlpp_renderer.cpp
Normal file
56
sdlpp/sdlpp_renderer.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "sdlpp_renderer.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
Renderer::Renderer( Window &window ) {
|
||||||
|
renderer = SDL_CreateRenderer( window.getWindowPtr(), -1,
|
||||||
|
SDL_RENDERER_ACCELERATED );
|
||||||
|
if ( renderer == NULL ) {
|
||||||
|
std::cerr << "SDL could not create a renderer! SDL_Error: "
|
||||||
|
<< SDL_GetError();
|
||||||
|
throw "Couldn't create renderer";
|
||||||
|
}
|
||||||
|
SDL_SetRenderDrawColor( renderer, 0xFF, 0xFF, 0xFF, 0xFF );
|
||||||
|
}
|
||||||
|
Renderer::~Renderer() {
|
||||||
|
SDL_DestroyRenderer( renderer );
|
||||||
|
}
|
||||||
|
SDL_Renderer *Renderer::getRendererPtr() {
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
std::pair< int, int > Renderer::getDimensions() const {
|
||||||
|
int width = 0, height = 0;
|
||||||
|
SDL_GetRendererOutputSize( renderer, &width, &height );
|
||||||
|
return { width, height };
|
||||||
|
}
|
||||||
|
int Renderer::getWidth() const {
|
||||||
|
return getDimensions().first;
|
||||||
|
}
|
||||||
|
int Renderer::getHeight() const {
|
||||||
|
return getDimensions().second;
|
||||||
|
}
|
||||||
|
int Renderer::getSmallerSide() const {
|
||||||
|
auto dimensions = getDimensions();
|
||||||
|
return dimensions.first < dimensions.second ? dimensions.first
|
||||||
|
: dimensions.second;
|
||||||
|
}
|
||||||
|
int Renderer::getLargerSide() const {
|
||||||
|
auto dimensions = getDimensions();
|
||||||
|
return dimensions.first > dimensions.second ? dimensions.first
|
||||||
|
: dimensions.second;
|
||||||
|
}
|
||||||
|
void Renderer::setBlendMode( SDL_BlendMode blendMode ) {
|
||||||
|
SDL_SetRenderDrawBlendMode( renderer, blendMode );
|
||||||
|
}
|
||||||
|
void Renderer::setRenderColiders( bool render ) {
|
||||||
|
render_coliders = render;
|
||||||
|
}
|
||||||
|
bool Renderer::getRenderColiders() {
|
||||||
|
return render_coliders;
|
||||||
|
}
|
||||||
|
void Renderer::clearRenderer() {
|
||||||
|
SDL_RenderClear( getRendererPtr() );
|
||||||
|
}
|
||||||
|
void Renderer::presentRenderer() {
|
||||||
|
SDL_RenderPresent( getRendererPtr() );
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
32
sdlpp/sdlpp_renderer.hpp
Normal file
32
sdlpp/sdlpp_renderer.hpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef SDLPP_HPP_RENDERER
|
||||||
|
#define SDLPP_HPP_RENDERER
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_window.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class Renderer {
|
||||||
|
public:
|
||||||
|
Renderer() = delete;
|
||||||
|
Renderer( Window &window );
|
||||||
|
virtual ~Renderer();
|
||||||
|
SDL_Renderer *getRendererPtr();
|
||||||
|
std::pair< int, int > getDimensions() const;
|
||||||
|
int getWidth() const;
|
||||||
|
int getHeight() const;
|
||||||
|
int getSmallerSide() const;
|
||||||
|
int getLargerSide() const;
|
||||||
|
void setBlendMode( SDL_BlendMode blendMode );
|
||||||
|
void setRenderColiders( bool render );
|
||||||
|
bool getRenderColiders();
|
||||||
|
void clearRenderer();
|
||||||
|
void presentRenderer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDL_Renderer *renderer = NULL;
|
||||||
|
bool render_coliders = false;
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
107
sdlpp/sdlpp_renderobject.cpp
Normal file
107
sdlpp/sdlpp_renderobject.cpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include "sdlpp_renderobject.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
bool RenderObject::colidesWith( const RenderObject &other ) const {
|
||||||
|
if ( !hasCollisions() || !other.hasCollisions() || getHidden() ||
|
||||||
|
other.getHidden() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for ( const auto &x : collisions ) {
|
||||||
|
for ( const auto &y : other.getCollisions() ) {
|
||||||
|
if ( x->colidesWith( *y ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool RenderObject::hasCollisions() const {
|
||||||
|
return !collisions.empty();
|
||||||
|
}
|
||||||
|
const std::vector< std::shared_ptr< CollisionPolygon > > &
|
||||||
|
RenderObject::getCollisions() const {
|
||||||
|
return collisions;
|
||||||
|
}
|
||||||
|
void RenderObject::setTexture( const std::shared_ptr< Texture > &t ) {
|
||||||
|
texture = t;
|
||||||
|
}
|
||||||
|
void RenderObject::setTexture( const std::string &img_path ) {
|
||||||
|
texture = std::make_shared< Texture >( renderer, img_path );
|
||||||
|
}
|
||||||
|
void RenderObject::setTexture( Font &font, const std::string &text,
|
||||||
|
const std::string &color,
|
||||||
|
const std::string &outline_color,
|
||||||
|
int outline_size ) {
|
||||||
|
texture = std::make_shared< Texture >( renderer, font, text, color,
|
||||||
|
outline_color, outline_size );
|
||||||
|
}
|
||||||
|
void RenderObject::unsetTexture() {
|
||||||
|
texture.reset();
|
||||||
|
}
|
||||||
|
void RenderObject::unsetColor() {
|
||||||
|
polygon.reset();
|
||||||
|
}
|
||||||
|
// per second, relative to window width
|
||||||
|
void RenderObject::setMovementSpeed( double speed ) {
|
||||||
|
movementSpeed = speed;
|
||||||
|
}
|
||||||
|
void RenderObject::addMovement( int x, int y ) {
|
||||||
|
movementDirection.first += x;
|
||||||
|
movementDirection.second += y;
|
||||||
|
}
|
||||||
|
void RenderObject::resetMovementX() {
|
||||||
|
movementDirection.first = 0;
|
||||||
|
}
|
||||||
|
void RenderObject::resetMovementY() {
|
||||||
|
movementDirection.second = 0;
|
||||||
|
}
|
||||||
|
void RenderObject::clearColided() {
|
||||||
|
colidedWith.clear();
|
||||||
|
}
|
||||||
|
void RenderObject::addColided( std::shared_ptr< RenderObject > &obj ) {
|
||||||
|
colidedWith.push_back( obj );
|
||||||
|
}
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > &RenderObject::getColidedWith() {
|
||||||
|
return colidedWith;
|
||||||
|
}
|
||||||
|
void RenderObject::setId( uint64_t input_id ) {
|
||||||
|
id = input_id;
|
||||||
|
}
|
||||||
|
uint64_t RenderObject::getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
void RenderObject::setHidden( bool hid ) {
|
||||||
|
hidden = hid;
|
||||||
|
}
|
||||||
|
bool RenderObject::getHidden() const {
|
||||||
|
return hidden;
|
||||||
|
}
|
||||||
|
void RenderObject::destroy() {
|
||||||
|
setHidden( true );
|
||||||
|
kill = true;
|
||||||
|
}
|
||||||
|
bool RenderObject::getKilled() {
|
||||||
|
return kill;
|
||||||
|
}
|
||||||
|
void RenderObject::setColiderColor( const std::string &color ) {
|
||||||
|
colider_color = getColorsHEX( color );
|
||||||
|
}
|
||||||
|
void RenderObject::setPermanent( bool perm ) {
|
||||||
|
permanent = perm;
|
||||||
|
setStatic( perm );
|
||||||
|
}
|
||||||
|
bool RenderObject::getPermanent() const {
|
||||||
|
return permanent;
|
||||||
|
}
|
||||||
|
bool RenderObject::isStatic() {
|
||||||
|
return is_static;
|
||||||
|
}
|
||||||
|
void RenderObject::setStatic( bool stat ) {
|
||||||
|
is_static = stat;
|
||||||
|
}
|
||||||
|
std::shared_ptr< Renderer > RenderObject::getRenderer() const {
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
void RenderObject::setSceneID( int id ) {
|
||||||
|
scene_id = id;
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
104
sdlpp/sdlpp_renderobject.hpp
Normal file
104
sdlpp/sdlpp_renderobject.hpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#ifndef SDLPP_HPP_RENDER_OBJECT
|
||||||
|
#define SDLPP_HPP_RENDER_OBJECT
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_collision.hpp"
|
||||||
|
#include "sdlpp_renderer.hpp"
|
||||||
|
#include "sdlpp_texture.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class Scene;
|
||||||
|
|
||||||
|
class RenderObject {
|
||||||
|
public:
|
||||||
|
RenderObject( const std::shared_ptr< Renderer > &r ) : renderer( r ) {}
|
||||||
|
virtual ~RenderObject() {}
|
||||||
|
virtual void render() = 0;
|
||||||
|
virtual int leftmost() = 0;
|
||||||
|
virtual int topmost() = 0;
|
||||||
|
virtual int rightmost() = 0;
|
||||||
|
virtual int bottommost() = 0;
|
||||||
|
virtual int collisionPushX() = 0;
|
||||||
|
virtual int collisionPushY() = 0;
|
||||||
|
virtual int collisionWidth() = 0;
|
||||||
|
virtual int collisionHeight() = 0;
|
||||||
|
virtual void specialAction( int code ) = 0;
|
||||||
|
virtual std::pair< std::pair< double, double >,
|
||||||
|
std::pair< double, double > >
|
||||||
|
getDoubleRect() const = 0;
|
||||||
|
virtual void setPos( double x, double y ) = 0;
|
||||||
|
virtual void setPos( const std::pair< double, double > &pos ) = 0;
|
||||||
|
virtual std::pair< double, double > getPos() const = 0;
|
||||||
|
bool colidesWith( const RenderObject &other ) const;
|
||||||
|
template < class T > void addCollision( const T &p ) {
|
||||||
|
collisions.push_back( std::make_shared< T >( p ) );
|
||||||
|
collisions.back()->updateCollision( collisionPushX(), collisionPushY(),
|
||||||
|
collisionWidth(),
|
||||||
|
collisionHeight() );
|
||||||
|
}
|
||||||
|
bool hasCollisions() const;
|
||||||
|
const std::vector< std::shared_ptr< CollisionPolygon > > &
|
||||||
|
getCollisions() const;
|
||||||
|
virtual void setTexture( const std::shared_ptr< Texture > &t );
|
||||||
|
virtual void setTexture( const std::string &img_path );
|
||||||
|
virtual void setTexture( Font &font, const std::string &text,
|
||||||
|
const std::string &color = "FFFFFF",
|
||||||
|
const std::string &outline_color = "000000",
|
||||||
|
int outline_size = -1 );
|
||||||
|
virtual void setColor( const std::string &color ) = 0;
|
||||||
|
virtual void setOutlineColor( const std::string &color ) = 0;
|
||||||
|
virtual void unsetTexture();
|
||||||
|
virtual void unsetColor();
|
||||||
|
// per second, relative to window width
|
||||||
|
void setMovementSpeed( double speed );
|
||||||
|
void addMovement( int x, int y );
|
||||||
|
void resetMovementX();
|
||||||
|
void resetMovementY();
|
||||||
|
void clearColided();
|
||||||
|
void addColided( std::shared_ptr< RenderObject > &obj );
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > &getColidedWith();
|
||||||
|
void setId( uint64_t input_id );
|
||||||
|
uint64_t getId();
|
||||||
|
void setHidden( bool hid );
|
||||||
|
bool getHidden() const;
|
||||||
|
void destroy();
|
||||||
|
bool getKilled();
|
||||||
|
void setColiderColor( const std::string &color );
|
||||||
|
virtual void move( int ticks ) = 0;
|
||||||
|
virtual void custom_move( int ticks ) = 0;
|
||||||
|
virtual void updateSizeAndPosition() = 0;
|
||||||
|
virtual SDL_Rect getRect() = 0;
|
||||||
|
void setPermanent( bool perm = true );
|
||||||
|
bool getPermanent() const;
|
||||||
|
virtual void centerX() = 0;
|
||||||
|
virtual std::shared_ptr< RenderObject > copySelf() = 0;
|
||||||
|
bool isStatic();
|
||||||
|
void setStatic( bool stat = true );
|
||||||
|
std::shared_ptr< Renderer > getRenderer() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector< std::shared_ptr< CollisionPolygon > > collisions;
|
||||||
|
std::shared_ptr< Texture > texture;
|
||||||
|
std::shared_ptr< Renderer > renderer;
|
||||||
|
std::shared_ptr< CollisionPolygon > polygon;
|
||||||
|
double movementSpeed = 0;
|
||||||
|
std::pair< int, int > movementDirection = { 0, 0 };
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > colidedWith;
|
||||||
|
uint64_t id = -1;
|
||||||
|
bool hidden = false;
|
||||||
|
bool kill = false;
|
||||||
|
std::tuple< int, int, int, int > colider_color = { 0x00, 0xFF, 0xFF, 0xFF };
|
||||||
|
uint64_t scene_id = -1;
|
||||||
|
bool permanent = false;
|
||||||
|
bool is_static = true;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setSceneID( int id );
|
||||||
|
friend Scene;
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
|
||||||
|
#endif
|
235
sdlpp/sdlpp_scene.cpp
Normal file
235
sdlpp/sdlpp_scene.cpp
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
#include "sdlpp_scene.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
Scene::Scene( std::shared_ptr< Renderer > &r ) : renderer( r ) {
|
||||||
|
SDL_SetRenderDrawColor( renderer->getRendererPtr(), 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF );
|
||||||
|
prev_ticks = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
void Scene::addObject( const std::shared_ptr< RenderObject > &obj ) {
|
||||||
|
std::lock_guard< std::mutex > lock( render_mutex );
|
||||||
|
render_objects.push_back( obj );
|
||||||
|
obj->setSceneID( ++max_object_id );
|
||||||
|
if ( obj->hasCollisions() ) {
|
||||||
|
collision_objects.push_back( obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( render_objects.size() == 1 ) {
|
||||||
|
leftmost_obj = obj;
|
||||||
|
rightmost_obj = obj;
|
||||||
|
} else {
|
||||||
|
auto rect = obj->getDoubleRect();
|
||||||
|
auto leftmost_rect = leftmost_obj->getDoubleRect();
|
||||||
|
if ( rect.first.first < leftmost_rect.first.first )
|
||||||
|
leftmost_obj = obj;
|
||||||
|
auto rightmost_rect = rightmost_obj->getDoubleRect();
|
||||||
|
if ( rect.first.first + rect.second.first >
|
||||||
|
rightmost_rect.first.first + rightmost_rect.second.first )
|
||||||
|
rightmost_obj = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Scene::setZIndex( const std::shared_ptr< RenderObject > &obj, int index ) {
|
||||||
|
std::lock_guard< std::mutex > guard( render_mutex );
|
||||||
|
int original_index = 0;
|
||||||
|
for ( long unsigned int i = 0; i < render_objects.size(); i++ ) {
|
||||||
|
if ( render_objects[i] == obj ) {
|
||||||
|
original_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( original_index == index )
|
||||||
|
return;
|
||||||
|
if ( original_index > index )
|
||||||
|
original_index++;
|
||||||
|
render_objects.insert( render_objects.begin() + index, obj );
|
||||||
|
render_objects.erase( render_objects.begin() + original_index );
|
||||||
|
}
|
||||||
|
void Scene::moveDownZ( const std::shared_ptr< RenderObject > &obj ) {
|
||||||
|
moveZ( obj, -1 );
|
||||||
|
}
|
||||||
|
void Scene::moveUpZ( const std::shared_ptr< RenderObject > &obj ) {
|
||||||
|
moveZ( obj, 1 );
|
||||||
|
}
|
||||||
|
void Scene::moveZ( const std::shared_ptr< RenderObject > &obj, int addition ) {
|
||||||
|
int original_index = 0;
|
||||||
|
for ( long unsigned int i = 0; i < render_objects.size(); i++ ) {
|
||||||
|
if ( render_objects[i] == obj ) {
|
||||||
|
original_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::iter_swap( render_objects.begin() + original_index,
|
||||||
|
render_objects.begin() + original_index + addition );
|
||||||
|
}
|
||||||
|
// TODO addCollision
|
||||||
|
std::shared_ptr< RenderObject > Scene::getObject( int index ) {
|
||||||
|
return render_objects[index];
|
||||||
|
}
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > Scene::getObjects() {
|
||||||
|
return render_objects;
|
||||||
|
}
|
||||||
|
std::vector< std::shared_ptr< RenderObject > >
|
||||||
|
Scene::getObjects( const std::unordered_set< int > &objectIDs ) {
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > ret{};
|
||||||
|
for ( const auto &x : render_objects ) {
|
||||||
|
// check if object exists because of possible race condition
|
||||||
|
if ( x && objectIDs.find( x->getId() ) != objectIDs.end() ) {
|
||||||
|
ret.push_back( x );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void Scene::movement() {
|
||||||
|
checkKilled();
|
||||||
|
std::lock_guard< std::mutex > lock( render_mutex );
|
||||||
|
int now_ticks = SDL_GetTicks();
|
||||||
|
for ( const auto &x : render_objects ) {
|
||||||
|
x->move( now_ticks - prev_ticks );
|
||||||
|
}
|
||||||
|
prev_ticks = now_ticks;
|
||||||
|
}
|
||||||
|
std::vector< std::shared_ptr< RenderObject > >
|
||||||
|
Scene::getCollisions( RenderObject &r ) {
|
||||||
|
if ( r.getHidden() )
|
||||||
|
return {};
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > ret{};
|
||||||
|
for ( const auto &x : collision_objects ) {
|
||||||
|
if ( x->colidesWith( r ) ) {
|
||||||
|
ret.push_back( x );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
std::vector< std::shared_ptr< RenderObject > >
|
||||||
|
Scene::getCollisions( RenderObject &r,
|
||||||
|
const std::unordered_set< int > &objectIDs ) {
|
||||||
|
if ( r.getHidden() )
|
||||||
|
return {};
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > ret{};
|
||||||
|
for ( const auto &x : collision_objects ) {
|
||||||
|
if ( objectIDs.find( x->getId() ) != objectIDs.end() &&
|
||||||
|
x->colidesWith( r ) ) {
|
||||||
|
ret.push_back( x );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void Scene::renderScene( bool clear_renderer ) {
|
||||||
|
checkKilled();
|
||||||
|
std::lock_guard< std::mutex > lock( render_mutex );
|
||||||
|
if ( clear_renderer )
|
||||||
|
SDL_RenderClear( renderer->getRendererPtr() );
|
||||||
|
if ( background && background->getTexturePtr() )
|
||||||
|
SDL_RenderCopy( renderer->getRendererPtr(), background->getTexturePtr(),
|
||||||
|
NULL, NULL );
|
||||||
|
for ( const auto &x : render_objects ) {
|
||||||
|
x->render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Scene::presentScene() {
|
||||||
|
SDL_RenderPresent( renderer->getRendererPtr() );
|
||||||
|
}
|
||||||
|
void Scene::setBackground( std::shared_ptr< Texture > bg ) {
|
||||||
|
background = bg;
|
||||||
|
}
|
||||||
|
void Scene::setBackground( const std::string &img_path ) {
|
||||||
|
background = std::make_shared< Texture >( renderer, img_path );
|
||||||
|
}
|
||||||
|
void Scene::updateSizeAndPosition() {
|
||||||
|
checkKilled();
|
||||||
|
std::lock_guard< std::mutex > lock( render_mutex );
|
||||||
|
for ( auto &x : render_objects ) {
|
||||||
|
x->updateSizeAndPosition();
|
||||||
|
for ( auto &col : x->getCollisions() ) {
|
||||||
|
col->updateCollision( x->collisionPushX(), x->collisionPushY(),
|
||||||
|
x->collisionWidth(), x->collisionHeight() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Scene::moveEverything( double x, double y ) {
|
||||||
|
checkKilled();
|
||||||
|
std::lock_guard< std::mutex > lock( render_mutex );
|
||||||
|
for ( auto &obj : render_objects ) {
|
||||||
|
if ( obj->getPermanent() )
|
||||||
|
continue;
|
||||||
|
auto curPos = obj->getDoubleRect();
|
||||||
|
obj->setPos( curPos.first.first + x, curPos.first.second + y );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const std::shared_ptr< RenderObject > &Scene::leftmost() {
|
||||||
|
return leftmost_obj;
|
||||||
|
}
|
||||||
|
const std::shared_ptr< RenderObject > &Scene::rightmost() {
|
||||||
|
return rightmost_obj;
|
||||||
|
}
|
||||||
|
std::pair< int, int > Scene::getDimensions() const {
|
||||||
|
return renderer->getDimensions();
|
||||||
|
}
|
||||||
|
int Scene::getWidth() const {
|
||||||
|
return renderer->getWidth();
|
||||||
|
}
|
||||||
|
int Scene::getHeight() const {
|
||||||
|
return renderer->getHeight();
|
||||||
|
}
|
||||||
|
Renderer &Scene::getRenderer() {
|
||||||
|
return *renderer;
|
||||||
|
}
|
||||||
|
std::shared_ptr< Renderer > Scene::getRendererShared() {
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
void Scene::setPrevTicks( int ticks ) {
|
||||||
|
prev_ticks = ticks;
|
||||||
|
}
|
||||||
|
void Scene::saveScene() {
|
||||||
|
saved_render_objects.clear();
|
||||||
|
saved_collision_objects.clear();
|
||||||
|
for ( auto &obj : render_objects ) {
|
||||||
|
if ( !obj->isStatic() )
|
||||||
|
saved_render_objects.push_back( obj->copySelf() );
|
||||||
|
else
|
||||||
|
saved_render_objects.push_back( obj );
|
||||||
|
}
|
||||||
|
for ( auto &obj : collision_objects ) {
|
||||||
|
if ( !obj->isStatic() )
|
||||||
|
saved_collision_objects.push_back( obj->copySelf() );
|
||||||
|
else
|
||||||
|
saved_collision_objects.push_back( obj );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Scene::resetScene() {
|
||||||
|
render_objects.clear();
|
||||||
|
collision_objects.clear();
|
||||||
|
for ( auto &obj : saved_render_objects ) {
|
||||||
|
if ( !obj->isStatic() )
|
||||||
|
render_objects.push_back( obj->copySelf() );
|
||||||
|
else
|
||||||
|
render_objects.push_back( obj );
|
||||||
|
}
|
||||||
|
for ( auto &obj : saved_collision_objects ) {
|
||||||
|
if ( !obj->isStatic() )
|
||||||
|
collision_objects.push_back( obj->copySelf() );
|
||||||
|
else
|
||||||
|
collision_objects.push_back( obj );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::checkKilled() {
|
||||||
|
std::lock_guard< std::mutex > lock( render_mutex );
|
||||||
|
std::vector< int > killed;
|
||||||
|
std::vector< int > killed_collisions;
|
||||||
|
for ( long unsigned int i = 0; i < render_objects.size(); i++ ) {
|
||||||
|
if ( render_objects[i]->getKilled() )
|
||||||
|
killed.push_back( i );
|
||||||
|
if ( i < collision_objects.size() && collision_objects[i]->getKilled() )
|
||||||
|
killed_collisions.push_back( i );
|
||||||
|
}
|
||||||
|
// reverse so we don't screw up indexing while going thorugh the kill
|
||||||
|
// indices
|
||||||
|
std::reverse( killed.begin(), killed.end() );
|
||||||
|
std::reverse( killed_collisions.begin(), killed_collisions.end() );
|
||||||
|
for ( auto &index : killed ) {
|
||||||
|
render_objects.erase( render_objects.begin() + index );
|
||||||
|
}
|
||||||
|
for ( auto &index : killed_collisions ) {
|
||||||
|
collision_objects.erase( collision_objects.begin() + index );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
66
sdlpp/sdlpp_scene.hpp
Normal file
66
sdlpp/sdlpp_scene.hpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#ifndef SDLPP_HPP_SCENE
|
||||||
|
#define SDLPP_HPP_SCENE
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_renderer.hpp"
|
||||||
|
#include "sdlpp_renderobject.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class Scene {
|
||||||
|
public:
|
||||||
|
Scene( std::shared_ptr< Renderer > &r );
|
||||||
|
void addObject( const std::shared_ptr< RenderObject > &obj );
|
||||||
|
void setZIndex( const std::shared_ptr< RenderObject > &obj, int index );
|
||||||
|
void moveDownZ( const std::shared_ptr< RenderObject > &obj );
|
||||||
|
void moveUpZ( const std::shared_ptr< RenderObject > &obj );
|
||||||
|
void moveZ( const std::shared_ptr< RenderObject > &obj, int addition );
|
||||||
|
// TODO addCollision
|
||||||
|
std::shared_ptr< RenderObject > getObject( int index );
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > getObjects();
|
||||||
|
std::vector< std::shared_ptr< RenderObject > >
|
||||||
|
getObjects( const std::unordered_set< int > &objectIDs );
|
||||||
|
void movement();
|
||||||
|
std::vector< std::shared_ptr< RenderObject > >
|
||||||
|
getCollisions( RenderObject &r );
|
||||||
|
std::vector< std::shared_ptr< RenderObject > >
|
||||||
|
getCollisions( RenderObject &r,
|
||||||
|
const std::unordered_set< int > &objectIDs );
|
||||||
|
void renderScene( bool clear_renderer = true );
|
||||||
|
void presentScene();
|
||||||
|
void setBackground( std::shared_ptr< Texture > bg );
|
||||||
|
void setBackground( const std::string &img_path );
|
||||||
|
void updateSizeAndPosition();
|
||||||
|
void moveEverything( double x, double y );
|
||||||
|
const std::shared_ptr< RenderObject > &leftmost();
|
||||||
|
const std::shared_ptr< RenderObject > &rightmost();
|
||||||
|
std::pair< int, int > getDimensions() const;
|
||||||
|
int getWidth() const;
|
||||||
|
int getHeight() const;
|
||||||
|
Renderer &getRenderer();
|
||||||
|
std::shared_ptr< Renderer > getRendererShared();
|
||||||
|
void setPrevTicks( int ticks );
|
||||||
|
void saveScene();
|
||||||
|
void resetScene();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkKilled();
|
||||||
|
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > render_objects;
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > collision_objects;
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > saved_render_objects;
|
||||||
|
std::vector< std::shared_ptr< RenderObject > > saved_collision_objects;
|
||||||
|
std::shared_ptr< Renderer > renderer;
|
||||||
|
std::shared_ptr< Texture > background;
|
||||||
|
int prev_ticks = 0;
|
||||||
|
std::shared_ptr< RenderObject > leftmost_obj;
|
||||||
|
std::shared_ptr< RenderObject > rightmost_obj;
|
||||||
|
uint64_t max_object_id = 0;
|
||||||
|
std::mutex render_mutex;
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
98
sdlpp/sdlpp_textrenderer.cpp
Normal file
98
sdlpp/sdlpp_textrenderer.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "sdlpp_textrenderer.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
TextRenderer::TextRenderer( double x, double y, double w, double h,
|
||||||
|
std::shared_ptr< Renderer > &r )
|
||||||
|
: RectangleRender( x, y, w, h, r ) {}
|
||||||
|
TextRenderer::TextRenderer( double x, double y, double w, double h,
|
||||||
|
std::shared_ptr< Renderer > &r, Font &font,
|
||||||
|
const std::string &text, const std::string &color,
|
||||||
|
const std::string &outline_color, int outline_size,
|
||||||
|
int flags )
|
||||||
|
: RectangleRender( x, y, w, h, r ) {
|
||||||
|
position_flags = flags;
|
||||||
|
setText( font, text, color, outline_color, outline_size );
|
||||||
|
}
|
||||||
|
void TextRenderer::setText( Font &font, const std::string &text,
|
||||||
|
const std::string &color,
|
||||||
|
const std::string &outline_color,
|
||||||
|
int outline_size ) {
|
||||||
|
_text = text;
|
||||||
|
setTextColor( font, color, outline_color, outline_size );
|
||||||
|
}
|
||||||
|
void TextRenderer::setTextColor( Font &font, const std::string &color,
|
||||||
|
const std::string &outline_color,
|
||||||
|
int outline_size ) {
|
||||||
|
setTexture( font, _text, color, outline_color, outline_size );
|
||||||
|
updateDstRect();
|
||||||
|
}
|
||||||
|
void TextRenderer::changeText( const std::string &text ) {
|
||||||
|
_text = text;
|
||||||
|
}
|
||||||
|
void TextRenderer::setFlags( int flags ) {
|
||||||
|
position_flags = flags;
|
||||||
|
updateDstRect();
|
||||||
|
}
|
||||||
|
void TextRenderer::render() {
|
||||||
|
if ( !getHidden() ) {
|
||||||
|
if ( polygon )
|
||||||
|
polygon->render( *renderer );
|
||||||
|
if ( texture != NULL )
|
||||||
|
SDL_RenderCopy( renderer->getRendererPtr(),
|
||||||
|
texture->getTexturePtr(), NULL, &dst_rect );
|
||||||
|
}
|
||||||
|
if ( hasCollisions() && renderer->getRenderColiders() && !getHidden() ) {
|
||||||
|
for ( const auto &col : getCollisions() )
|
||||||
|
col->render( *renderer, colider_color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void TextRenderer::updateSizeAndPosition() {
|
||||||
|
RectangleRender::updateSizeAndPosition();
|
||||||
|
updateDstRect();
|
||||||
|
}
|
||||||
|
std::shared_ptr< RenderObject > TextRenderer::copySelf() {
|
||||||
|
// TODO ACTUALLY copy, don't just copy pointers to textures and whatnot,
|
||||||
|
// create new textures!!!
|
||||||
|
return std::make_shared< TextRenderer >( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextRenderer::updateDstRect() {
|
||||||
|
if ( !texture )
|
||||||
|
return;
|
||||||
|
int text_width{}, text_height{};
|
||||||
|
SDL_QueryTexture( texture->getTexturePtr(), NULL, NULL, &text_width,
|
||||||
|
&text_height );
|
||||||
|
if ( text_width < rect.w && text_height < rect.h ) {
|
||||||
|
dst_rect.w = text_width;
|
||||||
|
dst_rect.h = text_height;
|
||||||
|
} else {
|
||||||
|
double x_div = static_cast< double >( text_width ) /
|
||||||
|
static_cast< double >( rect.w );
|
||||||
|
double y_div = static_cast< double >( text_height ) /
|
||||||
|
static_cast< double >( rect.h );
|
||||||
|
if ( x_div > y_div ) {
|
||||||
|
dst_rect.w = text_width / x_div;
|
||||||
|
dst_rect.h = text_height / x_div;
|
||||||
|
} else {
|
||||||
|
dst_rect.w = text_width / y_div;
|
||||||
|
dst_rect.h = text_height / y_div;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !( position_flags & SDLPP_TEXT_LEFT ||
|
||||||
|
position_flags & SDLPP_TEXT_RIGHT ) ) {
|
||||||
|
dst_rect.x = rect.x + ( rect.w - dst_rect.w ) / 2;
|
||||||
|
} else if ( position_flags & SDLPP_TEXT_LEFT ) {
|
||||||
|
dst_rect.x = rect.x;
|
||||||
|
} else if ( position_flags & SDLPP_TEXT_RIGHT ) {
|
||||||
|
dst_rect.x = rect.x + rect.w - dst_rect.w;
|
||||||
|
}
|
||||||
|
if ( !( position_flags & SDLPP_TEXT_TOP ||
|
||||||
|
position_flags & SDLPP_TEXT_BOTTOM ) ) {
|
||||||
|
dst_rect.y = rect.y + ( rect.h - dst_rect.h ) / 2;
|
||||||
|
} else if ( position_flags & SDLPP_TEXT_TOP ) {
|
||||||
|
dst_rect.y = rect.y;
|
||||||
|
} else if ( position_flags & SDLPP_TEXT_BOTTOM ) {
|
||||||
|
dst_rect.y = rect.y + rect.h - dst_rect.h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
41
sdlpp/sdlpp_textrenderer.hpp
Normal file
41
sdlpp/sdlpp_textrenderer.hpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef SDLPP_HPP_TEXT_RENDERER
|
||||||
|
#define SDLPP_HPP_TEXT_RENDERER
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_rectrenderer.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class TextRenderer : public RectangleRender {
|
||||||
|
public:
|
||||||
|
TextRenderer() = delete;
|
||||||
|
TextRenderer( double x, double y, double w, double h,
|
||||||
|
std::shared_ptr< Renderer > &r );
|
||||||
|
TextRenderer( double x, double y, double w, double h,
|
||||||
|
std::shared_ptr< Renderer > &r, Font &font,
|
||||||
|
const std::string &text, const std::string &color = "FFFFFF",
|
||||||
|
const std::string &outline_color = "000000",
|
||||||
|
int outline_size = -1, int flags = SDLPP_TEXT_CENTER );
|
||||||
|
void setText( Font &font, const std::string &text,
|
||||||
|
const std::string &color = "FFFFFF",
|
||||||
|
const std::string &outline_color = "000000",
|
||||||
|
int outline_size = -1 );
|
||||||
|
void setTextColor( Font &font, const std::string &color = "FFFFFF",
|
||||||
|
const std::string &outline_color = "000000",
|
||||||
|
int outline_size = -1 );
|
||||||
|
void changeText( const std::string &text );
|
||||||
|
void setFlags( int flags );
|
||||||
|
virtual void render() override;
|
||||||
|
virtual void updateSizeAndPosition() override;
|
||||||
|
virtual std::shared_ptr< RenderObject > copySelf() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateDstRect();
|
||||||
|
std::string _text{};
|
||||||
|
int position_flags = 0;
|
||||||
|
SDL_Rect dst_rect{};
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
75
sdlpp/sdlpp_texture.cpp
Normal file
75
sdlpp/sdlpp_texture.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "sdlpp_texture.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
Texture::Texture( std::shared_ptr< Renderer > &renderer,
|
||||||
|
const std::string &img_path, const std::string &color_key ) {
|
||||||
|
SDL_Surface *surface = IMG_Load( img_path.c_str() );
|
||||||
|
if ( surface == NULL ) {
|
||||||
|
std::cerr << "Unable to load image '" << img_path
|
||||||
|
<< "': IMG Error: " << IMG_GetError() << std::endl;
|
||||||
|
throw "IMG_Load error";
|
||||||
|
}
|
||||||
|
if ( !color_key.empty() ) {
|
||||||
|
auto colors = getColorsHEX( color_key );
|
||||||
|
SDL_SetColorKey( surface, SDL_TRUE,
|
||||||
|
SDL_MapRGB( surface->format, std::get< 0 >( colors ),
|
||||||
|
std::get< 1 >( colors ),
|
||||||
|
std::get< 2 >( colors ) ) );
|
||||||
|
}
|
||||||
|
setTextureFromSurface( renderer, surface );
|
||||||
|
}
|
||||||
|
Texture::Texture( std::shared_ptr< Renderer > &renderer, Font &font,
|
||||||
|
const std::string &text, const std::string &color,
|
||||||
|
const std::string &outline_color, const int outline_size ) {
|
||||||
|
if ( outline_size != -1 ) {
|
||||||
|
font.setOutline( outline_size );
|
||||||
|
}
|
||||||
|
int og_outline = 0;
|
||||||
|
SDL_Surface *bg_surface = NULL;
|
||||||
|
if ( ( og_outline = font.getOutline() ) != 0 ) {
|
||||||
|
bg_surface = TTF_RenderUTF8_Blended( font.getFont(), text.c_str(),
|
||||||
|
getSDLColorHEX( outline_color ) );
|
||||||
|
if ( bg_surface == NULL ) {
|
||||||
|
std::cerr << "Unable to render text '" << text
|
||||||
|
<< "': TTF Error: " << TTF_GetError() << std::endl;
|
||||||
|
throw "TTF_RenderUTF8_Shaded error";
|
||||||
|
}
|
||||||
|
font.setOutline( 0 );
|
||||||
|
}
|
||||||
|
SDL_Surface *surface = TTF_RenderUTF8_Blended( font.getFont(), text.c_str(),
|
||||||
|
getSDLColorHEX( color ) );
|
||||||
|
if ( surface == NULL ) {
|
||||||
|
std::cerr << "Unable to render text '" << text
|
||||||
|
<< "': TTF Error: " << TTF_GetError() << std::endl;
|
||||||
|
throw "TTF_RenderUTF8_Shaded error";
|
||||||
|
}
|
||||||
|
if ( og_outline != 0 ) {
|
||||||
|
SDL_Rect rect = { og_outline, og_outline, surface->w, surface->h };
|
||||||
|
SDL_SetSurfaceBlendMode( surface, SDL_BLENDMODE_BLEND );
|
||||||
|
SDL_BlitSurface( surface, NULL, bg_surface, &rect );
|
||||||
|
SDL_FreeSurface( surface );
|
||||||
|
surface = bg_surface;
|
||||||
|
bg_surface = NULL;
|
||||||
|
font.setOutline( og_outline );
|
||||||
|
}
|
||||||
|
setTextureFromSurface( renderer, surface );
|
||||||
|
}
|
||||||
|
Texture::~Texture() {
|
||||||
|
SDL_DestroyTexture( texture );
|
||||||
|
}
|
||||||
|
SDL_Texture *Texture::getTexturePtr() {
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::setTextureFromSurface( std::shared_ptr< Renderer > &renderer,
|
||||||
|
SDL_Surface *surface ) {
|
||||||
|
texture =
|
||||||
|
SDL_CreateTextureFromSurface( renderer->getRendererPtr(), surface );
|
||||||
|
if ( texture == NULL ) {
|
||||||
|
std::cerr << "Unable to create texture from surface! SDL Error: "
|
||||||
|
<< SDL_GetError() << std::endl;
|
||||||
|
throw "Texture error";
|
||||||
|
}
|
||||||
|
SDL_FreeSurface( surface );
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
32
sdlpp/sdlpp_texture.hpp
Normal file
32
sdlpp/sdlpp_texture.hpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef SDLPP_HPP_TEXTURE
|
||||||
|
#define SDLPP_HPP_TEXTURE
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
#include "sdlpp_font.hpp"
|
||||||
|
#include "sdlpp_renderer.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class Texture {
|
||||||
|
public:
|
||||||
|
Texture() = delete;
|
||||||
|
Texture( std::shared_ptr< Renderer > &renderer,
|
||||||
|
const std::string &img_path )
|
||||||
|
: Texture( renderer, img_path, "" ) {}
|
||||||
|
Texture( std::shared_ptr< Renderer > &renderer, const std::string &img_path,
|
||||||
|
const std::string &color_key );
|
||||||
|
Texture( std::shared_ptr< Renderer > &renderer, Font &font,
|
||||||
|
const std::string &text, const std::string &color = "FFFFFF",
|
||||||
|
const std::string &outline_color = "000000",
|
||||||
|
const int outline_size = -1 );
|
||||||
|
virtual ~Texture();
|
||||||
|
SDL_Texture *getTexturePtr();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setTextureFromSurface( std::shared_ptr< Renderer > &renderer,
|
||||||
|
SDL_Surface *surface );
|
||||||
|
SDL_Texture *texture = NULL;
|
||||||
|
};
|
||||||
|
} // end of namespace SDLPP
|
||||||
|
#endif
|
33
sdlpp/sdlpp_window.cpp
Normal file
33
sdlpp/sdlpp_window.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "sdlpp_window.hpp"
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
Window::Window()
|
||||||
|
: Window( "SDL Window", 640, 480, SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED ) {}
|
||||||
|
Window::Window( const std::string &window_name )
|
||||||
|
: Window( window_name, 640, 480, SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED ) {}
|
||||||
|
Window::Window( const std::string &window_name, uint32_t width,
|
||||||
|
uint32_t height )
|
||||||
|
: Window( window_name, width, height, SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED ) {}
|
||||||
|
Window::Window( const std::string &window_name, uint32_t width, uint32_t height,
|
||||||
|
uint32_t posx, uint32_t posy ) {
|
||||||
|
window = SDL_CreateWindow( window_name.c_str(), posx, posy, width, height,
|
||||||
|
SDL_WINDOW_SHOWN );
|
||||||
|
if ( window == NULL ) {
|
||||||
|
std::cerr << "SDL could not create a window! SDL_Error: "
|
||||||
|
<< SDL_GetError() << std::endl;
|
||||||
|
throw "Couldn't create window";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Window::setResizable( bool resizable ) {
|
||||||
|
SDL_SetWindowResizable( window, resizable ? SDL_TRUE : SDL_FALSE );
|
||||||
|
}
|
||||||
|
Window::~Window() {
|
||||||
|
SDL_DestroyWindow( window );
|
||||||
|
}
|
||||||
|
SDL_Window *Window::getWindowPtr() {
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
} // namespace SDLPP
|
24
sdlpp/sdlpp_window.hpp
Normal file
24
sdlpp/sdlpp_window.hpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef SDLPP_HPP_WINDOW
|
||||||
|
#define SDLPP_HPP_WINDOW
|
||||||
|
|
||||||
|
#include "sdlpp_common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace SDLPP {
|
||||||
|
class Window {
|
||||||
|
public:
|
||||||
|
Window();
|
||||||
|
Window( const std::string &window_name );
|
||||||
|
Window( const std::string &window_name, uint32_t width, uint32_t height );
|
||||||
|
Window( const std::string &window_name, uint32_t width, uint32_t height,
|
||||||
|
uint32_t posx, uint32_t posy );
|
||||||
|
void setResizable( bool resizable );
|
||||||
|
virtual ~Window();
|
||||||
|
SDL_Window *getWindowPtr();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDL_Window *window = NULL;
|
||||||
|
};
|
||||||
|
} // namespace SDLPP
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user