Added an application framework.

This commit is contained in:
Relintai 2021-04-03 00:53:57 +02:00
parent c690759ca6
commit 373b36664b
13 changed files with 296 additions and 45 deletions

View File

@ -113,6 +113,33 @@ void Renderer::draw_sprite(const Sprite &sprite) {
}
}
void Renderer::draw_sprite(const Sprite *sprite) {
Texture *t = sprite->get_texture();
if (!t) {
return;
}
double angle = sprite->get_angle();
if (Math::is_zero_approx(angle)) {
SDL_Rect sr = sprite->get_texture_clip_rect().as_rect();
SDL_Rect dr = sprite->get_transform().as_rect();
SDL_RenderCopy(_renderer, t->get_texture(), &sr, &dr);
} else {
SDL_Rect sr = sprite->get_texture_clip_rect().as_rect();
SDL_FRect dr = sprite->get_transform().as_frect();
SDL_FPoint p;
p.x = sprite->get_anchor_x();
p.y = sprite->get_anchor_y();
SDL_RenderCopyExF(_renderer, t->get_texture(), &sr, &dr, angle, &p, sprite->get_flip());
}
}
int Renderer::get_dpi() const {
float ddpi;
float hdpi;

View File

@ -33,6 +33,7 @@ public:
void draw_texture(const Texture &texture, const Rect2 &src_rect, const Rect2 &dst_rect, const double angle, const float cx = 0, const float cy = 0, const SDL_RendererFlip flip = SDL_FLIP_NONE);
void draw_sprite(const Sprite &sprite);
void draw_sprite(const Sprite *sprite);
int get_dpi() const;
int get_window_size_w() const;

View File

@ -0,0 +1,78 @@
#include "application.h"
#include "renderer.h"
Application* Application::_instance = nullptr;
#include <chrono>
void Application::event(const SDL_Event &current_event) {
switch (current_event.type) {
case SDL_QUIT:
running = false;
break;
//case SDL_KEYDOWN:
//input->process_event_keydown(current_event);
//break;
//case SDL_KEYUP:
//input->process_event_keyup(current_event);
//break;
}
scene->event(current_event);
}
void Application::update(float delta) {
scene->update(delta);
}
void Application::render() {
scene->render();
Renderer::get_singleton()->present();
}
void Application::main_loop() {
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
//handle input
SDL_Event current_event;
while (SDL_PollEvent(&current_event)) {
event(current_event);
}
update(frame_delta);
render();
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
double t = elapsed_seconds.count();
double tfps = 1.0 / static_cast<double>(target_fps);
double remaining = tfps - t;
if (remaining > 0) {
Uint32 fms = static_cast<Uint32>(remaining * 1000.0);
frame_delta = tfps;
SDL_Delay(fms);
} else {
frame_delta = t;
}
}
Application::Application() {
running = true;
target_fps = 60;
scene = nullptr;
_instance = this;
}
Application::~Application() {
_instance = nullptr;
}
Application* Application::get_singleton() {
return _instance;
}

View File

@ -0,0 +1,32 @@
#ifndef APPLICATION_H
#define APPLICATION_H
#include <SDL.h>
#include "scene.h"
class Application {
public:
bool running;
int target_fps;
virtual void event(const SDL_Event &current_event);
virtual void update(float delta);
virtual void render();
void main_loop();
Application();
virtual ~Application();
Scene *scene;
static Application* get_singleton();
double frame_delta = 0;
protected:
static Application* _instance;
};
#endif

View File

@ -23,7 +23,11 @@ g++ -Wall -g $(sdl2-config --cflags) -c image.cpp -o obj/image.o
g++ -Wall -g $(sdl2-config --cflags) -c texture.cpp -o obj/texture.o
g++ -Wall -g $(sdl2-config --cflags) -c sprite.cpp -o obj/sprite.o
g++ -Wall -g $(sdl2-config --cflags) -c scene.cpp -o obj/scene.o
g++ -Wall -g $(sdl2-config --cflags) -c application.cpp -o obj/application.o
g++ -Wall -g $(sdl2-config --cflags) -c main_scene.cpp -o obj/main_scene.o
g++ -Wall -g $(sdl2-config --cflags) -c main.cpp -o obj/main.o
g++ -o bin/program obj/math.o obj/rect2.o obj/color.o obj/string.o obj/renderer.o obj/image.o obj/texture.o obj/sprite.o obj/main.o $(sdl2-config --libs)
g++ -o bin/program obj/math.o obj/rect2.o obj/color.o obj/string.o obj/renderer.o obj/image.o obj/texture.o obj/sprite.o obj/scene.o obj/application.o obj/main_scene.o obj/main.o $(sdl2-config --libs)

View File

@ -0,0 +1,18 @@
#ifndef IMPL_APPLICATION_H
#define IMPL_APPLICATION_H
#include "application.h"
#include "main_scene.h"
class ImplApplication : public Application {
public:
ImplApplication() : Application() {
scene = new MainScene();
}
~ImplApplication() {
delete scene;
}
};
#endif

View File

@ -1,54 +1,34 @@
#include <SDL.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "image.h"
#include "application.h"
#include "renderer.h"
#include "sprite.h"
#include <SDL.h>
#include "impl_application.h"
#define APPLICATION_CLASS ImplApplication
void main_loop_1() {
bool quit = false;
SDL_Event e;
Renderer *renderer = nullptr;
Application *application = nullptr;
while (!quit) {
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
quit = true;
}
void handle_frame() {
application->main_loop();
}
if (e.type == SDL_KEYDOWN) {
printf("keydown\n");
}
int main(int argc, char *argv[]) {
renderer = new Renderer();
application = new APPLICATION_CLASS();
if (e.type == SDL_KEYUP) {
printf("keyup\n");
}
}
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(handle_frame, 0, 1);
#else
while (application->running) {
application->main_loop();
}
}
#endif
int main(int argv, char **args) {
Renderer r;
delete application;
delete renderer;
Image i("ti.bmp");
r.set_draw_color(0, 0, 0, 255);
r.clear();
Texture t(&i);
Sprite s(&t);
s.set_x(30);
s.set_y(30);
r.draw_sprite(s);
r.present();
main_loop_1();
t.free();
i.free();
r.destroy();
SDL_Quit();
}
return 0;
}

View File

@ -0,0 +1,34 @@
#include "main_scene.h"
#include "renderer.h"
void MainScene::event(const SDL_Event &ev) {
}
void MainScene::update(float delta) {
}
void MainScene::render() {
Renderer::get_singleton()->clear();
_sprite->set_x(30);
_sprite->set_y(30);
Renderer::get_singleton()->draw_sprite(_sprite);
}
MainScene::MainScene() {
_image = new Image("ti.bmp");
_texture = new Texture(_image);
_sprite = new Sprite(_texture);
}
MainScene::~MainScene() {
_texture->free();
_image->free();
delete _sprite;
delete _texture;
delete _image;
}

View File

@ -0,0 +1,24 @@
#ifndef MAIN_SCENE_H
#define MAIN_SCENE_H
#include "scene.h"
#include "image.h"
#include "texture.h"
#include "sprite.h"
class MainScene : public Scene {
public:
void event(const SDL_Event &ev);
void update(float delta);
void render();
MainScene();
~MainScene();
Image *_image;
Texture *_texture;
Sprite *_sprite;
};
#endif

View File

@ -113,6 +113,33 @@ void Renderer::draw_sprite(const Sprite &sprite) {
}
}
void Renderer::draw_sprite(const Sprite *sprite) {
Texture *t = sprite->get_texture();
if (!t) {
return;
}
double angle = sprite->get_angle();
if (Math::is_zero_approx(angle)) {
SDL_Rect sr = sprite->get_texture_clip_rect().as_rect();
SDL_Rect dr = sprite->get_transform().as_rect();
SDL_RenderCopy(_renderer, t->get_texture(), &sr, &dr);
} else {
SDL_Rect sr = sprite->get_texture_clip_rect().as_rect();
SDL_FRect dr = sprite->get_transform().as_frect();
SDL_FPoint p;
p.x = sprite->get_anchor_x();
p.y = sprite->get_anchor_y();
SDL_RenderCopyExF(_renderer, t->get_texture(), &sr, &dr, angle, &p, sprite->get_flip());
}
}
int Renderer::get_dpi() const {
float ddpi;
float hdpi;

View File

@ -33,6 +33,7 @@ public:
void draw_texture(const Texture &texture, const Rect2 &src_rect, const Rect2 &dst_rect, const double angle, const float cx = 0, const float cy = 0, const SDL_RendererFlip flip = SDL_FLIP_NONE);
void draw_sprite(const Sprite &sprite);
void draw_sprite(const Sprite *sprite);
int get_dpi() const;
int get_window_size_w() const;

View File

@ -0,0 +1,9 @@
#include "scene.h"
Scene::Scene() {
}
Scene::~Scene() {
}

View File

@ -0,0 +1,16 @@
#ifndef SCENE_H
#define SCENE_H
#include <SDL.h>
class Scene {
public:
virtual void event(const SDL_Event &ev) = 0;
virtual void update(float delta) = 0;
virtual void render() = 0;
Scene();
virtual ~Scene();
};
#endif