aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-12-12 20:45:49 +0100
committerWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-12-12 20:45:49 +0100
commit431d7cceb25db86f31a8c89440f3cdd2c7bf061f (patch)
treeeb32cf71b0f3fe369cd4509c54b8df960e2765e4
parente75e355c3a59d53a1d64fd8fae3331b2234083e2 (diff)
load font almost working
-rw-r--r--src/crepe/api/Text.cpp2
-rw-r--r--src/crepe/api/Text.h49
-rw-r--r--src/crepe/facade/Font.cpp4
-rw-r--r--src/crepe/facade/Font.h15
-rw-r--r--src/crepe/facade/SDLContext.cpp202
-rw-r--r--src/example/loadfont.cpp13
6 files changed, 181 insertions, 104 deletions
diff --git a/src/crepe/api/Text.cpp b/src/crepe/api/Text.cpp
index dd44dd9..12d01f1 100644
--- a/src/crepe/api/Text.cpp
+++ b/src/crepe/api/Text.cpp
@@ -2,5 +2,5 @@
using namespace crepe;
-Text::Text(game_object_id_t id,const vec2 & dimensions, const vec2 & offset, const Asset & font) : UIObject(id,dimensions,offset),source(font){}
+Text::Text(game_object_id_t id,const vec2 & dimensions, const vec2 & offset,std::string text,std::string font_family) : UIObject(id,dimensions,offset),text(text), font_family(font_family){}
diff --git a/src/crepe/api/Text.h b/src/crepe/api/Text.h
index d5f47fa..51bab98 100644
--- a/src/crepe/api/Text.h
+++ b/src/crepe/api/Text.h
@@ -9,27 +9,42 @@
#include "UIObject.h"
namespace crepe{
+
+/**
+ * \brief Text UIObject component for displaying text
+ *
+ * This class can be used to display text on screen. By setting the font_family to a font already stored on the current device it will automatically be loaded in.
+ */
class Text : public UIObject{
public:
- Text(game_object_id_t id,const vec2 & dimensions, const vec2 & offset, const Asset & font);
+ Text(game_object_id_t id,const vec2 & dimensions, const vec2 & offset,std::string text,std::string font_family);
+ //! Text data that does not have to be set in the constructor
+ struct Data {
+ //! Label text color.
+ Color text_color = Color::BLACK;
+ /**
+ * \brief fontsize for text rendering
+ *
+ * \note this is not the actual font size that is loaded in.
+ *
+ * Since SDL_TTF requires the font size when loading in the font it is not possible to switch the font size.
+ * The default font size that is loaded is set in the Config.
+ * Instead this value is used to upscale the font texture which can cause blurring or distorted text when upscaling or downscaling too much.
+ */
+ unsigned int font_size = 16;
+ //! Layer sorting level of the text
+ const int sorting_in_layer = 0;
+ //! Order within the sorting text
+ const int order_in_layer = 0;
+ };
+public:
+ //! font family name such as (Arial,Helvetica,Inter)
+ std::string font_family = "";
//! Label text.
- std::string text;
- //! Label text color.
- Color text_color = Color::BLACK;
- /**
- * \brief fontsize for text rendering
- *
- * \note this is not the actual font size that is loaded in.
- *
- * Since SDL_TTF requires the font size when loading in the font it is not possible to switch the font size.
- * The default font size that is loaded is set in the Config.
- * Instead this value is used to upscale the font texture which can cause blurring or distorted text when upscaling or downscaling too much.
- */
- unsigned int font_size = 16;
- //! Font asset
- const Asset source;
-private:
+ std::string text = "";
+ // Data instance for data not gotten from constructor
+ Data data;
};
} // namespace crepe
diff --git a/src/crepe/facade/Font.cpp b/src/crepe/facade/Font.cpp
index b600b01..66835ee 100644
--- a/src/crepe/facade/Font.cpp
+++ b/src/crepe/facade/Font.cpp
@@ -23,6 +23,6 @@ Font::Font(std::unique_ptr<Asset> res){
this->load(std::move(res));
}
-const TTF_Font& Font::get_font() const{
- return this->font;
+TTF_Font* Font::get_font() const{
+ return this->font.get();
}
diff --git a/src/crepe/facade/Font.h b/src/crepe/facade/Font.h
index 8bf9fc9..dd1cebf 100644
--- a/src/crepe/facade/Font.h
+++ b/src/crepe/facade/Font.h
@@ -17,17 +17,20 @@ class Font : public Resource{
public:
/**
* \param src Asset with font data to load.
- * \param mediator use the SDLContext reference to load text
+ * \param mediator use the SDLContext reference to get_font()
*/
- Font( src, Mediator & mediator);
+ Font(const Asset & src, Mediator & mediator);
-
- ~Font() = default
- const TTF_Font& get_font() const;
+ /**
+ * \brief getter for TTF_Font
+ *
+ * \param src Asset with font data to load.
+ * \param mediator use the SDLContext reference to get_font()
+ */
+ TTF_Font* get_font() const;
private:
//! The SDL_ttf font object with custom deleter.
std::unique_ptr<TTF_Font, decltype(&TTF_CloseFont)> font;
- unsigned int default_font_size = Config::get_instance().font.size;
};
} // namespace crepe
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index d71a9c8..8f6c02c 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -18,18 +18,23 @@
#include "../api/Color.h"
#include "../api/Config.h"
#include "../api/Sprite.h"
+#include "../api/Texture.h"
#include "../util/Log.h"
-#include "manager/Mediator.h"
#include "SDLContext.h"
-#include "Texture.h"
#include "types.h"
using namespace crepe;
using namespace std;
-SDLContext::SDLContext(Mediator & mediator) {
+SDLContext & SDLContext::get_instance() {
+ static SDLContext instance;
+ return instance;
+}
+
+SDLContext::SDLContext() {
dbg_trace();
+
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
throw runtime_error(format("SDLContext: SDL_Init error: {}", SDL_GetError()));
}
@@ -57,8 +62,6 @@ SDLContext::SDLContext(Mediator & mediator) {
if (!(IMG_Init(img_flags) & img_flags)) {
throw runtime_error("SDLContext: SDL_image could not initialize!");
}
-
- mediator.sdl_context = *this;
}
SDLContext::~SDLContext() {
@@ -74,11 +77,12 @@ SDLContext::~SDLContext() {
SDL_Quit();
}
-Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) {
+Keycode SDLContext::sdl_to_keycode(SDL_Scancode sdl_key) {
static const std::array<Keycode, SDL_NUM_SCANCODES> LOOKUP_TABLE = [] {
std::array<Keycode, SDL_NUM_SCANCODES> table{};
table.fill(Keycode::NONE);
+ // Map all SDL scancodes to Keycodes
table[SDL_SCANCODE_SPACE] = Keycode::SPACE;
table[SDL_SCANCODE_APOSTROPHE] = Keycode::APOSTROPHE;
table[SDL_SCANCODE_COMMA] = Keycode::COMMA;
@@ -180,13 +184,27 @@ Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) {
return table;
}();
-
if (sdl_key < 0 || sdl_key >= SDL_NUM_SCANCODES) {
return Keycode::NONE;
}
-
return LOOKUP_TABLE[sdl_key];
}
+std::array<bool, Keycode::NUM_KEYCODES> SDLContext::get_keyboard_state() {
+ // Array to hold the key states (true if pressed, false if not)
+ std::array<bool, Keycode::NUM_KEYCODES> keyState{};
+ SDL_PumpEvents();
+ const Uint8 * current_state = SDL_GetKeyboardState(nullptr);
+
+ for (int i = 0; i < SDL_NUM_SCANCODES; ++i) {
+ Keycode key = sdl_to_keycode(static_cast<SDL_Scancode>(i));
+
+ if (key != Keycode::NONE) {
+ keyState[key] = current_state[i] != 0;
+ }
+ }
+
+ return keyState;
+}
MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) {
static const std::array<MouseButton, 5> MOUSE_BUTTON_LOOKUP_TABLE = [] {
@@ -218,19 +236,25 @@ void SDLContext::present_screen() {
SDL_RenderPresent(this->game_renderer.get());
}
+SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const {
+ return SDL_Rect{
+ .x = sprite.mask.x,
+ .y = sprite.mask.y,
+ .w = sprite.mask.w,
+ .h = sprite.mask.h,
+ };
+}
+
SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const {
const Sprite::Data & data = ctx.sprite.data;
- float aspect_ratio
- = (ctx.sprite.aspect_ratio == 0) ? ctx.texture.get_ratio() : ctx.sprite.aspect_ratio;
-
vec2 size = data.size;
if (data.size.x == 0 && data.size.y != 0) {
- size.x = data.size.y * aspect_ratio;
+ size.x = data.size.y * ctx.sprite.aspect_ratio;
}
if (data.size.y == 0 && data.size.x != 0) {
- size.y = data.size.x / aspect_ratio;
+ size.y = data.size.x / ctx.sprite.aspect_ratio;
}
const CameraValues & cam = ctx.cam;
@@ -251,24 +275,15 @@ SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const {
}
void SDLContext::draw(const RenderContext & ctx) {
+
const Sprite::Data & data = ctx.sprite.data;
SDL_RendererFlip render_flip
= (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * data.flip.flip_x)
| (SDL_FLIP_VERTICAL * data.flip.flip_y));
- SDL_Rect srcrect;
- SDL_Rect * srcrect_ptr = NULL;
- if (ctx.sprite.mask.w != 0 || ctx.sprite.mask.h != 0) {
- srcrect.w = ctx.sprite.mask.w;
- srcrect.h = ctx.sprite.mask.h;
- srcrect.x = ctx.sprite.mask.x;
- srcrect.y = ctx.sprite.mask.y;
- srcrect_ptr = &srcrect;
- }
-
+ SDL_Rect srcrect = this->get_src_rect(ctx.sprite);
SDL_FRect dstrect = this->get_dst_rect(SDLContext::DestinationRectangleData{
.sprite = ctx.sprite,
- .texture = ctx.texture,
.cam = ctx.cam,
.pos = ctx.pos,
.img_scale = ctx.scale,
@@ -276,9 +291,9 @@ void SDLContext::draw(const RenderContext & ctx) {
double angle = ctx.angle + data.angle_offset;
- this->set_color_texture(ctx.texture, ctx.sprite.data.color);
- SDL_RenderCopyExF(this->game_renderer.get(), ctx.texture.get_img(), srcrect_ptr, &dstrect,
- angle, NULL, render_flip);
+ this->set_color_texture(ctx.sprite.texture, ctx.sprite.data.color);
+ SDL_RenderCopyExF(this->game_renderer.get(), ctx.sprite.texture.texture.get(), &srcrect,
+ &dstrect, angle, NULL, render_flip);
}
SDLContext::CameraValues SDLContext::set_camera(const Camera & cam) {
@@ -340,6 +355,8 @@ SDLContext::CameraValues SDLContext::set_camera(const Camera & cam) {
return ret_cam;
}
+uint64_t SDLContext::get_ticks() const { return SDL_GetTicks64(); }
+
std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>>
SDLContext::texture_from_path(const std::string & path) {
@@ -366,71 +383,112 @@ SDLContext::texture_from_path(const std::string & path) {
ivec2 SDLContext::get_size(const Texture & ctx) {
ivec2 size;
- SDL_QueryTexture(ctx.get_img(), NULL, NULL, &size.x, &size.y);
+ SDL_QueryTexture(ctx.texture.get(), NULL, NULL, &size.x, &size.y);
return size;
}
+void SDLContext::delay(int ms) const { SDL_Delay(ms); }
+
std::vector<SDLContext::EventData> SDLContext::get_events() {
std::vector<SDLContext::EventData> event_list;
SDL_Event event;
+
+ // Handle general SDL events
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::SHUTDOWN,
- });
+ event_list.push_back({SDLContext::EventType::SHUTDOWN, {}, {}, {}});
break;
case SDL_KEYDOWN:
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::KEYDOWN,
- .key = sdl_to_keycode(event.key.keysym.scancode),
- .key_repeat = (event.key.repeat != 0),
- });
+ event_list.push_back(
+ {SDLContext::EventType::KEYDOWN,
+ {sdl_to_keycode(event.key.keysym.scancode), event.key.repeat != 0},
+ {},
+ {}});
break;
case SDL_KEYUP:
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::KEYUP,
- .key = sdl_to_keycode(event.key.keysym.scancode),
- });
+ event_list.push_back({SDLContext::EventType::KEYUP,
+ {sdl_to_keycode(event.key.keysym.scancode), false},
+ {},
+ {}});
break;
case SDL_MOUSEBUTTONDOWN:
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::MOUSEDOWN,
- .mouse_button = sdl_to_mousebutton(event.button.button),
- .mouse_position = {event.button.x, event.button.y},
- });
+ event_list.push_back({SDLContext::EventType::MOUSEDOWN,
+ {},
+ {sdl_to_mousebutton(event.button.button),
+ {event.button.x, event.button.y}},
+ {}});
+ break;
+ case SDL_MOUSEBUTTONUP:
+ event_list.push_back({SDLContext::EventType::MOUSEUP,
+ {},
+ {sdl_to_mousebutton(event.button.button),
+ {event.button.x, event.button.y}},
+ {}});
+ break;
+ case SDL_MOUSEMOTION:
+ event_list.push_back({SDLContext::EventType::MOUSEMOVE,
+ {},
+ {{},
+ {event.motion.x, event.motion.y},
+ -1,
+ INFINITY,
+ {event.motion.xrel, event.motion.yrel}},
+ {}});
break;
- case SDL_MOUSEBUTTONUP: {
- int x, y;
- SDL_GetMouseState(&x, &y);
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::MOUSEUP,
- .mouse_button = sdl_to_mousebutton(event.button.button),
- .mouse_position = {event.button.x, event.button.y},
- });
- } break;
-
- case SDL_MOUSEMOTION: {
+ case SDL_MOUSEWHEEL:
event_list.push_back(
- EventData{.event_type = SDLContext::EventType::MOUSEMOVE,
- .mouse_position = {event.motion.x, event.motion.y},
- .rel_mouse_move = {event.motion.xrel, event.motion.yrel}});
- } break;
-
- case SDL_MOUSEWHEEL: {
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::MOUSEWHEEL,
- .mouse_position = {event.motion.x, event.motion.y},
- // TODO: why is this needed?
- .scroll_direction = event.wheel.y < 0 ? -1 : 1,
- .scroll_delta = event.wheel.preciseY,
- });
- } break;
+ {SDLContext::EventType::MOUSEWHEEL,
+ {},
+ {{}, {}, event.wheel.y < 0 ? -1 : 1, event.wheel.preciseY, {}},
+ {}});
+ break;
+
+ // Forward window events for further processing
+ case SDL_WINDOWEVENT:
+ this->handle_window_event(event.window, event_list);
+ break;
}
}
+
return event_list;
}
+
+// Separate function for SDL_WINDOWEVENT subtypes
+void SDLContext::handle_window_event(const SDL_WindowEvent & window_event,
+ std::vector<SDLContext::EventData> & event_list) {
+ switch (window_event.event) {
+ case SDL_WINDOWEVENT_EXPOSED:
+ event_list.push_back({SDLContext::EventType::WINDOW_EXPOSE, {}, {}, {}});
+ break;
+ case SDL_WINDOWEVENT_RESIZED:
+ event_list.push_back({SDLContext::EventType::WINDOW_RESIZE,
+ {},
+ {},
+ {{}, {window_event.data1, window_event.data2}}});
+ break;
+ case SDL_WINDOWEVENT_MOVED:
+ event_list.push_back({SDLContext::EventType::WINDOW_MOVE,
+ {},
+ {},
+ {{window_event.data1, window_event.data2}, {}}});
+ break;
+ case SDL_WINDOWEVENT_MINIMIZED:
+ event_list.push_back({SDLContext::EventType::WINDOW_MINIMIZE, {}, {}, {}});
+ break;
+ case SDL_WINDOWEVENT_MAXIMIZED:
+ event_list.push_back({SDLContext::EventType::WINDOW_MAXIMIZE, {}, {}, {}});
+ break;
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
+ event_list.push_back({SDLContext::EventType::WINDOW_FOCUS_GAIN, {}, {}, {}});
+ break;
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ event_list.push_back({SDLContext::EventType::WINDOW_FOCUS_LOST, {}, {}, {}});
+ break;
+ }
+}
+
void SDLContext::set_color_texture(const Texture & texture, const Color & color) {
- SDL_SetTextureColorMod(texture.get_img(), color.r, color.g, color.b);
- SDL_SetTextureAlphaMod(texture.get_img(), color.a);
+ SDL_SetTextureColorMod(texture.texture.get(), color.r, color.g, color.b);
+ SDL_SetTextureAlphaMod(texture.texture.get(), color.a);
}
diff --git a/src/example/loadfont.cpp b/src/example/loadfont.cpp
index 0002026..fe5466f 100644
--- a/src/example/loadfont.cpp
+++ b/src/example/loadfont.cpp
@@ -3,18 +3,19 @@
#include <memory>
#include <crepe/facade/SDLFontContext.h>
#include <crepe/api/Text.h>
-
+#include <crepe/facade/Font.h>
+#include <crepe/manager/Mediator.h>
using namespace crepe;
int main() {
SDLFontContext font_facade;
-
- // Create a unique pointer to the font asset
- std::unique_ptr<Asset> asset = font_facade.get_font_asset("OpenSymbol");
- std::cout << "path: " << asset->get_path() << std::endl;
+ Mediator mediator;
try{
// Correct way to create a unique pointer for Text
- std::unique_ptr<Text> label = std::make_unique<Text>(1, vec2(100, 100), vec2(0, 0), *asset);
+ std::unique_ptr<Text> label = std::make_unique<Text>(1, vec2(100, 100), vec2(0, 0), "test test","OpenSymbol");
+ std::unique_ptr<Asset> asset = font_facade.get_font_asset(label->font_family);
+ std::cout << "path: " << asset->get_path() << std::endl;
+ std::unique_ptr<Font> font = make_unique<Font>(asset,mediator)
}catch (const std::exception& e) {
std::cout << "Standard exception thrown: " << e.what() << std::endl;
}