- replaced location with box, added get/set functions for size and
sides - preprocessor statements for handling emscripten main loop - pass floats to render functions - added box and get/set box functions to sprite class - functions for filling a texture with solid color or tile texture
This commit is contained in:
parent
bbc53d357c
commit
74ca4da69a
37
README
37
README
|
@ -1,25 +1,28 @@
|
|||
SFW (SDL Framework)
|
||||
===================
|
||||
|
||||
SFW is a library of C++ objects that facilitate the creation of SDL projects.
|
||||
It is modeled after PGFW, a Pygame framework, which is an older project of mine.
|
||||
It is currently in an early untested stage, but it comes with a simple program
|
||||
that demonstrates how the framework can help set up a project in both SDL and
|
||||
OpenGL contexts.
|
||||
SFW is a C++ library that facilitates the creation of SDL projects and adds
|
||||
useful game graphics oriented classes and functions. It is modeled after PGFW, a
|
||||
Pygame framework, which simplifies the set up of Pygame projects and enhances
|
||||
and adds some features to Pygame.
|
||||
|
||||
It is currently in an early untested stage. It comes with a simple program that
|
||||
demonstrates how the framework can help set up a project in both SDL and OpenGL
|
||||
contexts.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The SFW source comes with a few libraries in the lib/ folder, but there are
|
||||
other libraries that must be present in order to compile a project which uses
|
||||
the framework
|
||||
The SFW source includes some external libraries in the lib/ folder, but there
|
||||
are also other libraries that must be present in order to compile a project
|
||||
which uses the framework
|
||||
|
||||
- libSDL2 (developed with 2.0.9)
|
||||
- libSDL2-image
|
||||
- libSDL2-ttf
|
||||
- libSDL2-mixer
|
||||
- Open GL
|
||||
- compiler that supports C++17
|
||||
* libSDL2 (developed against v2.0.12)
|
||||
* libSDL2-image
|
||||
* libSDL2-ttf
|
||||
* libSDL2-mixer
|
||||
* OpenGL
|
||||
* compiler that supports C++17
|
||||
|
||||
Demo
|
||||
----
|
||||
|
@ -35,7 +38,7 @@ License
|
|||
This software is dedicated to the public domain. See
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ for details.
|
||||
|
||||
Contact
|
||||
-------
|
||||
Author
|
||||
------
|
||||
|
||||
You can email me at frank at shampoo.ooo
|
||||
420 at shampoo dot ooo
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
relative coordinates, relative lengths, relative sizes, delta time, specify
|
||||
config parameters on command line, effects chain, asset dict with metadata,
|
||||
move added sprite locations by offset when location is changed, gradients,
|
||||
level select code input, logging
|
||||
level select code input, logging, variable screen resolution, debug display,
|
||||
loading wheel animation
|
||||
|
||||
:) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :)
|
||||
|
||||
|
@ -131,7 +132,7 @@ Mushroom::Mushroom(Node *parent) : Sprite(parent, "resource/shrooms")
|
|||
void Mushroom::update()
|
||||
{
|
||||
move(direction);
|
||||
int x = location.get_x();
|
||||
int x = box.get_x();
|
||||
glm::ivec2 resolution = get_display().get_window_size();
|
||||
if (x > resolution.x or x < 0)
|
||||
{
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "filesystem.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Game.hpp"
|
||||
#include "Location.hpp"
|
||||
#include "Box.hpp"
|
||||
#include "Sprite.hpp"
|
||||
#include "Input.hpp"
|
||||
#include "Delegate.hpp"
|
||||
|
|
|
@ -36,7 +36,7 @@ $(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h
|
|||
$(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h
|
||||
$(CC_LINUX) $(CFLAGS) $< -o $@
|
||||
|
||||
$(SFW_SRC_DIR)Sprite.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Location.*pp Node.*pp Animation.*pp)
|
||||
$(SFW_SRC_DIR)Sprite.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Box.*pp Node.*pp Animation.*pp)
|
||||
$(SFW_SRC_DIR)Game.o: $(addprefix $(SFW_SRC_DIR),Sprite.*pp Configuration.*pp Delegate.*pp Display.*pp \
|
||||
Recorder.*pp Node.*pp Input.*pp)
|
||||
$(SFW_SRC_DIR)Node.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Configuration.*pp Delegate.*pp)
|
||||
|
@ -49,11 +49,11 @@ $(SFW_SRC_DIR)Display.o: $(addprefix $(SFW_SRC_DIR),Node.*pp)
|
|||
$(SFW_SRC_DIR)%.o: $(addprefix $(SFW_SRC_DIR),%.cpp %.hpp)
|
||||
$(CPPC_LINUX) $(CPP_FLAGS) $(SDL_FLAGS) $< -o $@
|
||||
|
||||
Demo.o: Demo.cpp Demo.hpp $(addprefix $(SFW_SRC_DIR),Sprite.*pp Node.*pp Game.*pp Location.*pp Input.*pp \
|
||||
Demo.o: Demo.cpp Demo.hpp $(addprefix $(SFW_SRC_DIR),Sprite.*pp Node.*pp Game.*pp Box.*pp Input.*pp \
|
||||
Recorder.*pp Timer.*pp Animation.*pp extension.*pp)
|
||||
$(CPPC_LINUX) $(CPP_FLAGS) $(SDL_FLAGS) $< -o $@
|
||||
|
||||
linux: Demo.o $(addprefix $(SFW_SRC_DIR),Sprite.o Node.o Game.o Location.o Configuration.o Input.o Delegate.o \
|
||||
linux: Demo.o $(addprefix $(SFW_SRC_DIR),Sprite.o Node.o Game.o Box.o Configuration.o Input.o Delegate.o \
|
||||
Display.o Recorder.o Timer.o Animation.o extension.o) \
|
||||
$(GLEW_DIR)glew.o $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o)
|
||||
$(CPPC_LINUX) $(LFLAGS) -D__LINUX__ $^ -lGL -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs -o demo
|
||||
|
|
|
@ -69,6 +69,10 @@ void Animation::update()
|
|||
{
|
||||
reset();
|
||||
}
|
||||
if (overflow > frame_length)
|
||||
{
|
||||
overflow = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ struct Animation
|
|||
{
|
||||
|
||||
bool playing = false, ending = false, paused = false;
|
||||
int previous_step_time = 0, overflow = 0, count = 0;
|
||||
float delay = 0, frame_length;
|
||||
int previous_step_time = 0, count = 0;
|
||||
float delay = 0, overflow = 0, frame_length;
|
||||
callback step;
|
||||
Node* containing_object;
|
||||
Timer timer = Timer();
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
#include "Box.hpp"
|
||||
|
||||
Box::Box(glm::vec2 nw, glm::vec2 size)
|
||||
{
|
||||
set_nw(nw);
|
||||
set_size(size);
|
||||
}
|
||||
|
||||
float Box::get_x()
|
||||
{
|
||||
return rect.x;
|
||||
}
|
||||
|
||||
float Box::get_y()
|
||||
{
|
||||
return rect.y;
|
||||
}
|
||||
|
||||
float Box::get_w()
|
||||
{
|
||||
return rect.w;
|
||||
}
|
||||
|
||||
float Box::get_h()
|
||||
{
|
||||
return rect.h;
|
||||
}
|
||||
|
||||
void Box::set_x(float x)
|
||||
{
|
||||
rect.x = x;
|
||||
}
|
||||
|
||||
void Box::set_y(float y)
|
||||
{
|
||||
rect.y = y;
|
||||
}
|
||||
|
||||
void Box::set_w(float w)
|
||||
{
|
||||
rect.w = w;
|
||||
}
|
||||
|
||||
void Box::set_h(float h)
|
||||
{
|
||||
rect.h = h;
|
||||
}
|
||||
|
||||
glm::vec2 Box::get_size()
|
||||
{
|
||||
return glm::vec2(get_w(), get_h());
|
||||
}
|
||||
|
||||
void Box::set_size(glm::vec2 size)
|
||||
{
|
||||
set_w(size.x);
|
||||
set_h(size.y);
|
||||
}
|
||||
|
||||
float Box::get_top()
|
||||
{
|
||||
return get_y();
|
||||
}
|
||||
|
||||
float Box::get_right()
|
||||
{
|
||||
return get_x() + get_w();
|
||||
}
|
||||
|
||||
float Box::get_bottom()
|
||||
{
|
||||
return get_y() + get_h();
|
||||
}
|
||||
|
||||
float Box::get_left()
|
||||
{
|
||||
return get_x();
|
||||
}
|
||||
|
||||
void Box::set_top(float top)
|
||||
{
|
||||
set_y(top);
|
||||
}
|
||||
|
||||
void Box::set_right(float right)
|
||||
{
|
||||
move(glm::vec2(right - get_right(), 0));
|
||||
}
|
||||
|
||||
void Box::set_bottom(float bottom)
|
||||
{
|
||||
move(glm::vec2(0, bottom - get_bottom()));
|
||||
}
|
||||
|
||||
void Box::set_left(float left)
|
||||
{
|
||||
set_x(left);
|
||||
}
|
||||
|
||||
glm::vec2 Box::get_nw()
|
||||
{
|
||||
return glm::vec2(get_x(), get_y());
|
||||
}
|
||||
|
||||
glm::vec2 Box::get_north()
|
||||
{
|
||||
return glm::vec2(get_x() + get_w() / 2, get_y());
|
||||
}
|
||||
|
||||
glm::vec2 Box::get_east()
|
||||
{
|
||||
return glm::vec2(get_right(), get_y() + get_h() / 2);
|
||||
}
|
||||
|
||||
glm::vec2 Box::get_south()
|
||||
{
|
||||
return glm::vec2(get_x() + get_w() / 2, get_bottom());
|
||||
}
|
||||
|
||||
glm::vec2 Box::get_west()
|
||||
{
|
||||
return glm::vec2(get_x(), get_y() + get_h() / 2);
|
||||
}
|
||||
|
||||
glm::vec2 Box::get_center()
|
||||
{
|
||||
return glm::vec2(get_x() + get_w() / 2, get_y() + get_h() / 2);
|
||||
}
|
||||
|
||||
void Box::set_nw(glm::vec2 nw)
|
||||
{
|
||||
set_x(nw.x);
|
||||
set_y(nw.y);
|
||||
}
|
||||
|
||||
void Box::set_north(glm::vec2 n)
|
||||
{
|
||||
move(n - get_north());
|
||||
}
|
||||
|
||||
void Box::set_east(glm::vec2 e)
|
||||
{
|
||||
move(e - get_east());
|
||||
}
|
||||
|
||||
void Box::set_south(glm::vec2 s)
|
||||
{
|
||||
move(s - get_south());
|
||||
}
|
||||
|
||||
void Box::set_west(glm::vec2 w)
|
||||
{
|
||||
move(w - get_west());
|
||||
}
|
||||
|
||||
void Box::set_center(glm::vec2 center)
|
||||
{
|
||||
move(center - get_center());
|
||||
}
|
||||
|
||||
SDL_FRect* Box::get_rect()
|
||||
{
|
||||
return ▭
|
||||
}
|
||||
|
||||
void Box::zero()
|
||||
{
|
||||
set_nw(glm::vec2(0, 0));
|
||||
set_size(glm::vec2(0, 0));
|
||||
}
|
||||
|
||||
void Box::move(glm::vec2 delta)
|
||||
{
|
||||
set_x(get_x() + delta.x);
|
||||
set_y(get_y() + delta.y);
|
||||
}
|
||||
|
||||
std::ostream& Box::to_string (std::ostream& out) const
|
||||
{
|
||||
out << "{(" << rect.x << ", " << rect.y << "), (" << rect.w << ", " << rect.h << ")}";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& out, const Box& box)
|
||||
{
|
||||
return box.to_string(out);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef Box_h_
|
||||
#define Box_h_
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include "glm/common.hpp"
|
||||
#include "glm/vec2.hpp"
|
||||
|
||||
struct Box
|
||||
{
|
||||
SDL_FRect rect = {0, 0, 0, 0};
|
||||
|
||||
Box(glm::vec2 = {0, 0}, glm::vec2 = {0, 0});
|
||||
float get_x();
|
||||
float get_y();
|
||||
float get_w();
|
||||
float get_h();
|
||||
void set_x(float);
|
||||
void set_y(float);
|
||||
void set_w(float);
|
||||
void set_h(float);
|
||||
glm::vec2 get_size();
|
||||
void set_size(glm::vec2);
|
||||
float get_top();
|
||||
float get_right();
|
||||
float get_bottom();
|
||||
float get_left();
|
||||
void set_top(float);
|
||||
void set_right(float);
|
||||
void set_bottom(float);
|
||||
void set_left(float);
|
||||
glm::vec2 get_nw();
|
||||
glm::vec2 get_north();
|
||||
glm::vec2 get_east();
|
||||
glm::vec2 get_south();
|
||||
glm::vec2 get_west();
|
||||
glm::vec2 get_center();
|
||||
void set_nw(glm::vec2);
|
||||
void set_north(glm::vec2);
|
||||
void set_east(glm::vec2);
|
||||
void set_south(glm::vec2);
|
||||
void set_west(glm::vec2);
|
||||
void set_center(glm::vec2);
|
||||
SDL_FRect* get_rect();
|
||||
void zero();
|
||||
void move(glm::vec2);
|
||||
std::string get_class_name() { return "Box"; }
|
||||
std::ostream& to_string (std::ostream&) const;
|
||||
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream&, const Box&);
|
||||
|
||||
#include "extension.hpp"
|
||||
|
||||
#endif
|
|
@ -31,7 +31,8 @@ void Configuration::set_defaults()
|
|||
};
|
||||
sys_config["display"] = {
|
||||
{"dimensions", {640, 480}},
|
||||
{"fps", 60}
|
||||
{"fps", 60},
|
||||
{"title", "sfw"}
|
||||
};
|
||||
sys_config["recording"] = {
|
||||
{"enabled", false},
|
||||
|
|
|
@ -2,14 +2,19 @@
|
|||
#include "Game.hpp"
|
||||
|
||||
Display::Display(Node* parent) : Node(parent) {}
|
||||
|
||||
|
||||
glm::ivec2 Display::get_window_size()
|
||||
{
|
||||
glm::ivec2 size;
|
||||
SDL_GetWindowSize(get_root()->window, &size.x, &size.y);
|
||||
SDL_GetWindowSize(get_root()->get_window(), &size.x, &size.y);
|
||||
return size;
|
||||
}
|
||||
|
||||
Box Display::get_window_box()
|
||||
{
|
||||
return Box(glm::vec2(0, 0), get_window_size());
|
||||
}
|
||||
|
||||
void Display::get_screen_pixels(unsigned char* pixels, int w, int h, int x, int y)
|
||||
{
|
||||
if (get_root()->is_gl_context)
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
#define GLEW_STATIC
|
||||
#include "glew/glew.h"
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#include <SDL_image.h>
|
||||
#include "sdl2-gfx/SDL2_gfxPrimitives.h"
|
||||
#include "sdl2-gfx/SDL2_rotozoom.h"
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#include "Node.hpp"
|
||||
#include "Box.hpp"
|
||||
|
||||
struct Display : Node
|
||||
{
|
||||
|
@ -23,6 +24,7 @@ struct Display : Node
|
|||
|
||||
Display(Node*);
|
||||
glm::ivec2 get_window_size();
|
||||
Box get_window_box();
|
||||
void get_screen_pixels(unsigned char*, int, int, int = 0, int = 0);
|
||||
SDL_Surface* get_screen_surface();
|
||||
SDL_Surface* get_screen_surface_from_pixels(unsigned char*, bool);
|
||||
|
|
87
src/Game.cpp
87
src/Game.cpp
|
@ -38,8 +38,9 @@ Game::Game()
|
|||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
||||
print_gl_attributes();
|
||||
std::vector<int> window_size = get_configuration()["display"]["dimensions"];
|
||||
window = SDL_CreateWindow("TARE control", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
window_size[0], window_size[1], SDL_WINDOW_OPENGL);
|
||||
window = SDL_CreateWindow(
|
||||
get_configuration()["display"]["title"].get_ref<const std::string&>().c_str(), SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED, window_size[0], window_size[1], SDL_WINDOW_OPENGL);
|
||||
if (window == NULL)
|
||||
{
|
||||
print_sdl_error("Could not create window");
|
||||
|
@ -56,6 +57,7 @@ Game::Game()
|
|||
SDL_Log("initialized SDL ttf %d.%d.%d", SDL_TTF_MAJOR_VERSION,
|
||||
SDL_TTF_MINOR_VERSION, SDL_TTF_PATCHLEVEL);
|
||||
}
|
||||
#if !defined(__EMSCRIPTEN__)
|
||||
if (Mix_Init(MIX_INIT_FLAC) == 0)
|
||||
{
|
||||
print_sdl_error("Could not initialize SDL mixer");
|
||||
|
@ -66,6 +68,7 @@ Game::Game()
|
|||
SDL_Log("initialized SDL mixer %d.%d.%d", SDL_MIXER_MAJOR_VERSION,
|
||||
SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL);
|
||||
}
|
||||
#endif
|
||||
if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT,
|
||||
MIX_DEFAULT_CHANNELS, 1024) < 0)
|
||||
{
|
||||
|
@ -171,14 +174,6 @@ void Game::load_gl_context()
|
|||
log_display_mode();
|
||||
}
|
||||
|
||||
GLuint Game::create_gl_texture()
|
||||
{
|
||||
GLuint id;
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
return id;
|
||||
}
|
||||
|
||||
bool Game::log_gl_errors(std::string suffix)
|
||||
{
|
||||
GLenum error;
|
||||
|
@ -398,29 +393,81 @@ std::string Game::get_pixel_format_string(Uint32 format)
|
|||
return pixel_format;
|
||||
}
|
||||
|
||||
SDL_Window* Game::get_window()
|
||||
{
|
||||
return window;
|
||||
}
|
||||
|
||||
SDL_Renderer* Game::get_renderer()
|
||||
{
|
||||
return renderer;
|
||||
}
|
||||
|
||||
void Game::run()
|
||||
{
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
||||
emscripten_set_main_loop_arg(&loop, this, -1, true);
|
||||
|
||||
#else
|
||||
|
||||
while (not done)
|
||||
{
|
||||
ticks = SDL_GetTicks();
|
||||
if (ticks - last_frame_timestamp + frame_time_overflow >= frame_length)
|
||||
{
|
||||
last_frame_length = ticks - last_frame_timestamp;
|
||||
frame_time_overflow = last_frame_length + frame_time_overflow - frame_length;
|
||||
last_frame_timestamp = ticks;
|
||||
recorder.update();
|
||||
delegate.dispatch();
|
||||
update();
|
||||
}
|
||||
frame(SDL_GetTicks());
|
||||
SDL_Delay(8);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void Game::frame(float ticks)
|
||||
{
|
||||
// std::cout << "ticks: " << ticks << ", last_frame_timestamp: " << last_frame_timestamp <<
|
||||
// ", frame_time_overflow: " << frame_time_overflow;
|
||||
if (ticks - last_frame_timestamp + frame_time_overflow >= frame_length)
|
||||
{
|
||||
last_frame_length = ticks - last_frame_timestamp;
|
||||
// std::cout << ", last_frame_length: " << last_frame_length << " [rendering frame]";
|
||||
frame_time_overflow = last_frame_length + frame_time_overflow - frame_length;
|
||||
last_frame_timestamp = ticks;
|
||||
recorder.update();
|
||||
delegate.dispatch();
|
||||
update();
|
||||
if (frame_time_overflow > frame_length)
|
||||
{
|
||||
SDL_Log("%i frame(s) dropped", ((int) (frame_time_overflow / frame_length)));
|
||||
frame_time_overflow = 0;
|
||||
}
|
||||
}
|
||||
// std::cout << std::endl;
|
||||
}
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
||||
void loop(void* context)
|
||||
{
|
||||
Game* game = static_cast<Game*>(context);
|
||||
game->frame(emscripten_performance_now());
|
||||
if (game->done)
|
||||
{
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Game::flag_to_end()
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
|
||||
glm::vec2 Game::weight(glm::vec2 motion)
|
||||
{
|
||||
return glm::vec2(weight(motion.x), weight(motion.y));
|
||||
}
|
||||
|
||||
void Game::set_framerate(int fps)
|
||||
{
|
||||
if (fps < 1)
|
||||
|
|
30
src/Game.hpp
30
src/Game.hpp
|
@ -13,8 +13,19 @@
|
|||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#define GLEW_STATIC
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include <GL/glew.h>
|
||||
|
||||
#else
|
||||
|
||||
#include "glew/glew.h"
|
||||
|
||||
#endif
|
||||
|
||||
#include "Node.hpp"
|
||||
#include "Configuration.hpp"
|
||||
#include "Delegate.hpp"
|
||||
|
@ -43,9 +54,9 @@ struct Game : Node
|
|||
SDL_GLContext glcontext = NULL;
|
||||
// 768, 432
|
||||
// 864, 486
|
||||
int frame_time_overflow = 0, framerate, ticks, last_frame_timestamp,
|
||||
frame_count_timestamp, last_frame_length;
|
||||
float frame_length;
|
||||
int framerate, ticks, last_frame_length;
|
||||
float frame_length = 1000.0 / 60.0, frame_time_overflow = 0,
|
||||
last_frame_timestamp, emscripten_previous_time;
|
||||
bool done = false, show_framerate = true, is_gl_context = true;
|
||||
Configuration configuration = Configuration(this);
|
||||
Delegate delegate = Delegate(this);
|
||||
|
@ -60,27 +71,36 @@ struct Game : Node
|
|||
void print_gl_attributes();
|
||||
void load_sdl_context();
|
||||
void load_gl_context();
|
||||
GLuint create_gl_texture();
|
||||
bool log_gl_errors(std::string);
|
||||
void log_display_mode();
|
||||
void log_surface_format(SDL_Surface*, std::string = "surface");
|
||||
std::string get_pixel_format_string(Uint32);
|
||||
SDL_Window* get_window();
|
||||
SDL_Renderer* get_renderer();
|
||||
void run();
|
||||
void frame(float);
|
||||
void flag_to_end();
|
||||
virtual void update() {};
|
||||
glm::vec2 weight(glm::vec2);
|
||||
void set_framerate(int);
|
||||
void handle_quit_event(SDL_Event&);
|
||||
void quit();
|
||||
std::string get_class_name() { return "Game"; }
|
||||
|
||||
template<typename T>
|
||||
float get_weighted_amount(T amount)
|
||||
float weight(T amount)
|
||||
{
|
||||
return (last_frame_length / (1000.0 / 60)) * amount;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
||||
void loop(void*);
|
||||
|
||||
#endif
|
||||
|
||||
#include "Sprite.hpp"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#include "Location.hpp"
|
||||
|
||||
int Location::get_x()
|
||||
{
|
||||
return rect.x;
|
||||
}
|
||||
|
||||
int Location::get_y()
|
||||
{
|
||||
return rect.y;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef Location_h_
|
||||
#define Location_h_
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include "glm/common.hpp"
|
||||
#include "glm/vec2.hpp"
|
||||
|
||||
struct Location
|
||||
{
|
||||
SDL_Rect rect = {0, 0, 0, 0};
|
||||
glm::vec2 overflow;
|
||||
|
||||
Location() { };
|
||||
int get_x();
|
||||
int get_y();
|
||||
std::string get_class_name() { return "Location"; }
|
||||
|
||||
template<typename T1, typename T2>
|
||||
void move_ip(T1 dx, T2 dy = 0)
|
||||
{
|
||||
overflow += glm::vec2(dx, dy);
|
||||
glm::vec2 motion = glm::floor(overflow);
|
||||
overflow -= motion;
|
||||
rect.x += motion[0];
|
||||
rect.y += motion[1];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -359,9 +359,9 @@ void Recorder::update()
|
|||
animation.update();
|
||||
}
|
||||
|
||||
void process_audio(void* user_data, Uint8* stream, int len)
|
||||
void process_audio(void* context, Uint8* stream, int len)
|
||||
{
|
||||
Recorder* recorder = static_cast<Recorder*>(user_data);
|
||||
Recorder* recorder = static_cast<Recorder*>(context);
|
||||
if (recorder->is_active())
|
||||
{
|
||||
int max_length = recorder->get_configuration()["recording"]["max-stash-length"];
|
||||
|
|
125
src/Sprite.cpp
125
src/Sprite.cpp
|
@ -1,17 +1,19 @@
|
|||
#include "Sprite.hpp"
|
||||
#include "Game.hpp"
|
||||
|
||||
Sprite::Sprite(Node *parent) : Node(parent, true) {}
|
||||
Sprite::Sprite(Node* parent) : Node(parent, true)
|
||||
{
|
||||
frame_animation.play();
|
||||
}
|
||||
|
||||
Sprite::Sprite(Node *parent, std::string path) : Node(parent, true)
|
||||
Sprite::Sprite(Node* parent, std::string path) : Sprite(parent)
|
||||
{
|
||||
associate(path);
|
||||
animation.play();
|
||||
}
|
||||
|
||||
void Sprite::set_frame_length(float length)
|
||||
{
|
||||
animation.set_frame_length(length);
|
||||
frame_animation.set_frame_length(length);
|
||||
}
|
||||
|
||||
void Sprite::associate(std::string path)
|
||||
|
@ -62,8 +64,18 @@ void Sprite::load_file(fs::path path)
|
|||
}
|
||||
}
|
||||
|
||||
void Sprite::add_frame(SDL_Texture *texture)
|
||||
void Sprite::add_frame(SDL_Texture* texture)
|
||||
{
|
||||
int w, h;
|
||||
SDL_QueryTexture(texture, NULL, NULL, &w, &h);
|
||||
if (box.get_w() < w)
|
||||
{
|
||||
box.set_w(w);
|
||||
}
|
||||
if (box.get_h() < h)
|
||||
{
|
||||
box.set_h(h);
|
||||
}
|
||||
frames.push_back(texture);
|
||||
}
|
||||
|
||||
|
@ -74,6 +86,7 @@ void Sprite::unload()
|
|||
SDL_DestroyTexture(frames.back());
|
||||
frames.pop_back();
|
||||
}
|
||||
box.zero();
|
||||
}
|
||||
|
||||
void Sprite::advance_frame()
|
||||
|
@ -84,15 +97,105 @@ void Sprite::advance_frame()
|
|||
}
|
||||
}
|
||||
|
||||
void Sprite::hide()
|
||||
{
|
||||
is_hidden = true;
|
||||
}
|
||||
|
||||
void Sprite::unhide()
|
||||
{
|
||||
is_hidden = false;
|
||||
}
|
||||
|
||||
void Sprite::toggle_hidden()
|
||||
{
|
||||
is_hidden = !is_hidden;
|
||||
}
|
||||
|
||||
void Sprite::set_step(glm::vec2 s)
|
||||
{
|
||||
step.x = s.x;
|
||||
step.y = s.y;
|
||||
}
|
||||
|
||||
float Sprite::get_w()
|
||||
{
|
||||
return box.get_w();
|
||||
}
|
||||
|
||||
float Sprite::get_h()
|
||||
{
|
||||
return box.get_h();
|
||||
}
|
||||
|
||||
glm::vec2 Sprite::get_size()
|
||||
{
|
||||
return box.get_size();
|
||||
}
|
||||
|
||||
float Sprite::get_top()
|
||||
{
|
||||
return box.get_top();
|
||||
}
|
||||
|
||||
float Sprite::get_right()
|
||||
{
|
||||
return box.get_right();
|
||||
}
|
||||
|
||||
float Sprite::get_bottom()
|
||||
{
|
||||
return box.get_bottom();
|
||||
}
|
||||
|
||||
float Sprite::get_left()
|
||||
{
|
||||
return box.get_left();
|
||||
}
|
||||
|
||||
glm::vec2 Sprite::get_nw()
|
||||
{
|
||||
return box.get_nw();
|
||||
}
|
||||
|
||||
glm::vec2 Sprite::get_north()
|
||||
{
|
||||
return box.get_north();
|
||||
}
|
||||
|
||||
glm::vec2 Sprite::get_west()
|
||||
{
|
||||
return box.get_west();
|
||||
}
|
||||
|
||||
void Sprite::set_nw(glm::vec2 nw)
|
||||
{
|
||||
box.set_nw(nw);
|
||||
}
|
||||
|
||||
void Sprite::move(glm::vec2 delta, bool weighted)
|
||||
{
|
||||
Game *game = get_root();
|
||||
if (weighted)
|
||||
{
|
||||
delta = game->weight(delta);
|
||||
}
|
||||
box.move(delta);
|
||||
}
|
||||
|
||||
void Sprite::update()
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
animation.update();
|
||||
int w, h;
|
||||
SDL_Texture *frame = frames[frame_ii];
|
||||
SDL_QueryTexture(frame, NULL, NULL, &w, &h);
|
||||
SDL_Rect frame_rect = {location.get_x(), location.get_y(), w, h};
|
||||
SDL_RenderCopy(get_root()->renderer, frame, NULL, &frame_rect);
|
||||
move(step);
|
||||
frame_animation.update();
|
||||
blink_animation.update();
|
||||
if (frames.size() && !is_hidden)
|
||||
{
|
||||
SDL_Texture* texture = frames[frame_ii];
|
||||
SDL_Renderer* renderer = get_root()->renderer;
|
||||
SDL_SetRenderTarget(renderer, NULL);
|
||||
SDL_RenderCopyF(renderer, texture, NULL, box.get_rect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include "Node.hpp"
|
||||
#include "Game.hpp"
|
||||
#include "Location.hpp"
|
||||
#include "Box.hpp"
|
||||
#include "Animation.hpp"
|
||||
|
||||
struct Sprite : Node
|
||||
|
@ -20,8 +20,11 @@ struct Sprite : Node
|
|||
std::vector<SDL_Texture*> frames;
|
||||
std::vector<fs::path> frame_paths;
|
||||
int frame_ii = 0;
|
||||
Location location;
|
||||
Animation animation = Animation(&Sprite::advance_frame, this);
|
||||
Box box;
|
||||
Animation frame_animation = Animation(&Sprite::advance_frame, this);
|
||||
Animation blink_animation = Animation(&Sprite::toggle_hidden, this, 500);
|
||||
bool is_hidden = false;
|
||||
glm::vec2 step = {0, 0};
|
||||
|
||||
Sprite(Node*);
|
||||
Sprite(Node*, std::string);
|
||||
|
@ -32,15 +35,25 @@ struct Sprite : Node
|
|||
void add_frame(SDL_Texture*);
|
||||
void unload();
|
||||
void advance_frame();
|
||||
void hide();
|
||||
void unhide();
|
||||
void toggle_hidden();
|
||||
void set_step(glm::vec2);
|
||||
float get_w();
|
||||
float get_h();
|
||||
glm::vec2 get_size();
|
||||
float get_top();
|
||||
float get_right();
|
||||
float get_bottom();
|
||||
float get_left();
|
||||
glm::vec2 get_nw();
|
||||
glm::vec2 get_north();
|
||||
glm::vec2 get_west();
|
||||
void set_nw(glm::vec2);
|
||||
void move(glm::vec2, bool = true);
|
||||
void update();
|
||||
std::string get_class_name() { return "Sprite"; }
|
||||
|
||||
template<typename T1, typename T2 = int>
|
||||
void move(T1 dx, T2 dy = 0)
|
||||
{
|
||||
Game *game = get_root();
|
||||
location.move_ip(game->get_weighted_amount(dx), game->get_weighted_amount(dy));
|
||||
}
|
||||
~Sprite() { unload(); }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Timer::Timer()
|
|||
|
||||
void Timer::toggle()
|
||||
{
|
||||
is_timing = not is_timing;
|
||||
is_timing = !is_timing;
|
||||
}
|
||||
|
||||
void Timer::toggle(bool state)
|
||||
|
|
|
@ -1,5 +1,40 @@
|
|||
#include "extension.hpp"
|
||||
|
||||
glm::vec2 sfw::get_step(glm::vec2 start, glm::vec2 end, float speed)
|
||||
{
|
||||
float angle = glm::atan(end.x - start.x, end.y - start.y);
|
||||
return glm::vec2(speed * glm::sin(angle), speed * glm::cos(angle));
|
||||
}
|
||||
|
||||
Box sfw::get_texture_box(SDL_Texture* texture)
|
||||
{
|
||||
int w, h;
|
||||
SDL_QueryTexture(texture, NULL, NULL, &w, &h);
|
||||
return Box(glm::vec2(0, 0), glm::vec2(w, h));
|
||||
}
|
||||
|
||||
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, int r, int g, int b, int a)
|
||||
{
|
||||
SDL_SetRenderTarget(renderer, texture);
|
||||
SDL_SetRenderDrawColor(renderer, r, g, b, a);
|
||||
SDL_RenderFillRect(renderer, NULL);
|
||||
}
|
||||
|
||||
void sfw::fill_texture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Texture* tile)
|
||||
{
|
||||
SDL_SetRenderTarget(renderer, texture);
|
||||
Box texture_box = get_texture_box(texture), tile_box = get_texture_box(tile);
|
||||
SDL_FRect draw_rect;
|
||||
for (int x = 0; x < texture_box.get_w(); x += tile_box.get_w())
|
||||
{
|
||||
for (int y = 0; y < texture_box.get_h(); y += tile_box.get_h())
|
||||
{
|
||||
draw_rect = {(float) x, (float) y, tile_box.get_w(), tile_box.get_h()};
|
||||
SDL_RenderCopyF(renderer, tile, NULL, &draw_rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<fs::path> sfw::glob(fs::path query)
|
||||
{
|
||||
fs::path basename = query.parent_path();
|
||||
|
|
|
@ -8,10 +8,21 @@
|
|||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include "glm/trigonometric.hpp"
|
||||
#include "glm/vec2.hpp"
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#include "Box.hpp"
|
||||
#include "filesystem.hpp"
|
||||
|
||||
namespace sfw
|
||||
{
|
||||
glm::vec2 get_step(glm::vec2, glm::vec2, float);
|
||||
Box get_texture_box(SDL_Texture*);
|
||||
void fill_texture(SDL_Renderer*, SDL_Texture*, int, int, int, int = 0xff);
|
||||
void fill_texture(SDL_Renderer*, SDL_Texture*, SDL_Texture*);
|
||||
std::vector<fs::path> glob(fs::path);
|
||||
fs::path get_next_file_name(
|
||||
fs::path, int = 0, std::string = "", std::string = "");
|
||||
|
|
Loading…
Reference in New Issue