aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/crepe/api/CMakeLists.txt3
-rw-r--r--src/crepe/api/Font.cpp45
-rw-r--r--src/crepe/api/Font.h60
-rw-r--r--src/crepe/api/Text.h42
-rw-r--r--src/crepe/facade/SDLContext.cpp70
-rw-r--r--src/crepe/system/InputSystem.cpp79
-rw-r--r--src/crepe/system/InputSystem.h84
-rw-r--r--src/test/InputTest.cpp7
9 files changed, 167 insertions, 225 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b0b034f..c3f29da 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -9,7 +9,6 @@ project(crepe C CXX)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
-find_package(SDL2_ttf REQUIRED)
find_package(SoLoud REQUIRED)
find_package(GTest REQUIRED)
find_package(whereami REQUIRED)
@@ -25,7 +24,6 @@ target_include_directories(crepe
target_link_libraries(crepe
PRIVATE soloud
PUBLIC SDL2
- PUBLIC SDL_ttf
PUBLIC SDL2_image
PUBLIC ${BERKELEY_DB}
PUBLIC whereami
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index 2d86968..aeb451d 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -25,7 +25,6 @@ target_sources(crepe PUBLIC
Script.cpp
Button.cpp
UiObject.cpp
- Font.cpp
)
target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -63,6 +62,4 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
Asset.h
Button.h
UiObject.h
- Font.h
- Text.h
)
diff --git a/src/crepe/api/Font.cpp b/src/crepe/api/Font.cpp
deleted file mode 100644
index 8db4b23..0000000
--- a/src/crepe/api/Font.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <SDL2/SDL_ttf.h>
-
-#include "facade/SDLContext.h"
-#include "util/Log.h"
-
-#include "Asset.h"
-#include "Font.h"
-
-using namespace crepe;
-using namespace std;
-
-Font::Font(const Asset &src, int size) : font_size(size) {
- dbg_trace();
- this->load(src, size);
-}
-
-Font::~Font() {
- dbg_trace();
- this->font.reset();
-}
-
-void Font::load(const Asset &res, int size) {
- SDLContext &ctx = SDLContext::get_instance();
- // Open the font using SDL's TTF_OpenFontRW, which supports loading from memory
- SDL_RWops *rw_ops = SDL_RWFromFile(res.get_path().c_str(), "rb");
- if (!rw_ops) {
- // dbg_log("Failed to create RWops for font: %s", SDL_GetError());
- return;
- }
-
- TTF_Font *loaded_font = TTF_OpenFontRW(rw_ops, 1, size); // 1 indicates SDL should free the RWops
- if (!loaded_font) {
- // dbg_log("Failed to load font from asset: %s", TTF_GetError());
- return;
- }
-
- // Wrap the TTF_Font with a unique_ptr for automatic cleanup
- this->font = unique_ptr<TTF_Font, function<void(TTF_Font *)>>(loaded_font, [](TTF_Font *f) {
- if (f) TTF_CloseFont(f);
- });
-}
-
-int Font::get_size() const {
- return this->font_size;
-}
diff --git a/src/crepe/api/Font.h b/src/crepe/api/Font.h
deleted file mode 100644
index 012c271..0000000
--- a/src/crepe/api/Font.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include <SDL2/SDL_ttf.h>
-#include <functional>
-#include <memory>
-
-#include "Asset.h"
-
-namespace crepe {
-
-class SDLContext;
-
-/**
- * \class Font
- * \brief Manages font loading and text rendering properties.
- *
- * The Font class is responsible for loading font resources and providing a way to render text
- * with different styles and sizes. It can be used for text rendering in the game engine.
- */
-class Font {
-
-public:
- /**
- * \brief Constructs a Font from an Asset resource.
- * \param src Asset with font data to load.
- * \param size The point size to render the font at.
- */
- Font(const Asset &src, int size);
-
- /**
- * \brief Destroys the Font instance, freeing associated resources.
- */
- ~Font();
-
- /**
- * \brief Gets the size of the font.
- * \return The point size of the font.
- */
- int get_size() const;
-
-private:
- /**
- * \brief Loads the font from an Asset resource.
- * \param res The Asset resource containing the font data.
- * \param size The point size to render the font at.
- */
- void load(const Asset &res, int size);
-
-private:
- //! The font resource from the SDL_ttf library.
- std::unique_ptr<TTF_Font, std::function<void(TTF_Font *)>> font;
-
- //! The size of the font in points.
- int font_size;
-
- //! Grants SDLContext access to private members.
- friend class SDLContext;
-};
-
-} // namespace crepe
diff --git a/src/crepe/api/Text.h b/src/crepe/api/Text.h
deleted file mode 100644
index 6bb011c..0000000
--- a/src/crepe/api/Text.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include <string>
-
-#include "Color.h"
-#include "UiObject.h"
-#include ""
-namespace crepe {
-
-/**
- * \class Button
- * \brief Represents a clickable UI button, derived from the UiObject class.
- *
- * This class provides functionality for a button in the UI, including toggle state,
- * click handling, and mouse hover detection. A callback function can be provided to
- * handle button clicks.
- */
-class Text : public UiObject {
-public:
- /**
- * \brief Constructs a Button with the specified game object ID and dimensions.
- *
- * \param id The unique ID of the game object associated with this button.
- * \param width The width of the button.
- * \param height The height of the button.
- */
- Text(game_object_id_t id, int width, int height);
-
- Color color = Color{0,0,0,0};
- std::string text = "";
- int size = 0;
- const std::shared_ptr<Font> sprite_image;
-public:
- /**
- * \brief Retrieves the maximum number of instances allowed for this button type.
- *
- * \return Always returns 1, as only a single instance of this type is allowed.
- */
- virtual int get_instances_max() const override { return 10; }
-};
-
-} // namespace crepe
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index 9b4595e..03b0cdc 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -16,6 +16,8 @@
#include <stdexcept>
#include "../api/Camera.h"
+#include "../api/EventManager.h"
+#include "../api/Config.h"
#include "../api/Sprite.h"
#include "../api/Texture.h"
#include "../util/Log.h"
@@ -213,7 +215,10 @@ MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) {
return MOUSE_BUTTON_LOOKUP_TABLE[sdl_button];
}
-void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); }
+void SDLContext::clear_screen() {
+ SDL_SetRenderDrawColor(this->game_renderer.get(), 0, 0, 0, 255);
+ SDL_RenderClear(this->game_renderer.get());
+}
void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); }
SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const {
@@ -336,3 +341,66 @@ ivec2 SDLContext::get_size(const Texture & ctx) {
}
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;
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_QUIT:
+ event_list.push_back(EventData{
+ .event_type = 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),
+ });
+ break;
+ case SDL_KEYUP:
+ event_list.push_back(EventData{
+ .event_type = SDLContext::EventType::KEYUP,
+ .key = sdl_to_keycode(event.key.keysym.scancode),
+ });
+ 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},
+ });
+ 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: {
+ 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},
+ .wheel_delta = event.wheel.y,
+ });
+ } break;
+ }
+ }
+ return event_list;
+}
+void SDLContext::set_color_texture(const Texture & texture, const Color & color) {
+ SDL_SetTextureColorMod(texture.texture.get(), color.r, color.g, color.b);
+ SDL_SetTextureAlphaMod(texture.texture.get(), color.a);
+}
diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp
index beeef87..5b220eb 100644
--- a/src/crepe/system/InputSystem.cpp
+++ b/src/crepe/system/InputSystem.cpp
@@ -1,16 +1,35 @@
-#include "ComponentManager.h"
-#include "api/Button.h"
-#include "api/EventManager.h"
+#include "../ComponentManager.h"
+#include "../api/Button.h"
+#include "../api/EventManager.h"
#include "InputSystem.h"
using namespace crepe;
+
void InputSystem::update() {
+ ComponentManager & mgr = this->component_manager;
EventManager & event_mgr = EventManager::get_instance();
std::vector<SDLContext::EventData> event_list = SDLContext::get_instance().get_events();
+ RefVector<Button> buttons = mgr.get_components_by_type<Button>();
+ RefVector<Camera> cameras = mgr.get_components_by_type<Camera>();
+ // Find the active camera
+ for (Camera & cam : cameras) {
+ if (!cam.active) continue;
+ this->curr_cam_ref = cam;
+ break;
+ }
+ if (!curr_cam_ref) return;
+ Camera& current_cam = curr_cam_ref;
+ RefVector<Transform> transform_vec = mgr.get_components_by_id<Transform>(current_cam.game_object_id);
+ Transform& cam_transform = transform_vec.front().get();
+ int camera_origin_x = cam_transform.position.x + current_cam.offset.x - (current_cam.viewport_size.x / 2);
+ int camera_origin_y = cam_transform.position.y + current_cam.offset.y - (current_cam.viewport_size.y / 2);
for (const SDLContext::EventData & event : event_list) {
+ int world_mouse_x = event.mouse_position.first + camera_origin_x;
+ int world_mouse_y = event.mouse_position.second + camera_origin_y;
+
switch (event.event_type) {
case SDLContext::EventType::KEYDOWN:
event_mgr.queue_event<KeyPressEvent>(KeyPressEvent{
@@ -25,43 +44,43 @@ void InputSystem::update() {
break;
case SDLContext::EventType::MOUSEDOWN:
event_mgr.queue_event<MousePressEvent>(MousePressEvent{
- .mouse_x = event.mouse_position.first,
- .mouse_y = event.mouse_position.second,
+ .mouse_x = world_mouse_x,
+ .mouse_y = world_mouse_y,
.button = event.mouse_button,
});
- last_mouse_down_position = event.mouse_position;
+ last_mouse_down_position = {world_mouse_x, world_mouse_y};
last_mouse_button = event.mouse_button;
break;
case SDLContext::EventType::MOUSEUP: {
event_mgr.queue_event<MouseReleaseEvent>(MouseReleaseEvent{
- .mouse_x = event.mouse_position.first,
- .mouse_y = event.mouse_position.second,
+ .mouse_x = world_mouse_x,
+ .mouse_y = world_mouse_y,
.button = event.mouse_button,
});
-
- int delta_x = event.mouse_position.first - last_mouse_down_position.first;
- int delta_y = event.mouse_position.second - last_mouse_down_position.second;
+ //check if its a click by checking the last button down
+ int delta_x = world_mouse_x - last_mouse_down_position.first;
+ int delta_y = world_mouse_y - last_mouse_down_position.second;
if (last_mouse_button == event.mouse_button
&& std::abs(delta_x) <= click_tolerance
&& std::abs(delta_y) <= click_tolerance) {
event_mgr.queue_event<MouseClickEvent>(MouseClickEvent{
- .mouse_x = event.mouse_position.first,
- .mouse_y = event.mouse_position.second,
+ .mouse_x = world_mouse_x,
+ .mouse_y = world_mouse_y,
.button = event.mouse_button,
});
- handle_click(event);
+ handle_click(event.mouse_button, world_mouse_x, world_mouse_y);
}
} break;
case SDLContext::EventType::MOUSEMOVE:
event_mgr.queue_event<MouseMoveEvent>(MouseMoveEvent{
- .mouse_x = event.mouse_position.first,
- .mouse_y = event.mouse_position.second,
+ .mouse_x = world_mouse_x,
+ .mouse_y = world_mouse_y,
.rel_x = event.rel_mouse_move.first,
.rel_y = event.rel_mouse_move.second,
});
- handle_move(event);
+ handle_move(event, world_mouse_x, world_mouse_y);
break;
case SDLContext::EventType::MOUSEWHEEL:
event_mgr.queue_event<MouseScrollEvent>(MouseScrollEvent{
@@ -79,7 +98,7 @@ void InputSystem::update() {
}
}
-void InputSystem::handle_move(const SDLContext::EventData & event_data) {
+void InputSystem::handle_move(const SDLContext::EventData & event_data, const int& world_mouse_x, const int& world_mouse_y) {
ComponentManager & mgr = this->component_manager;
RefVector<Button> buttons = mgr.get_components_by_type<Button>();
@@ -90,19 +109,14 @@ void InputSystem::handle_move(const SDLContext::EventData & event_data) {
OptionalRef<Transform> transform(transform_vec.front().get());
if (!transform) continue;
- bool was_hovering = button.hover; // Store previous hover state
-
- // Check if the mouse is inside the button
- if (button.active && is_mouse_inside_button(event_data, button, transform)) {
+ bool was_hovering = button.hover;
+ if (button.active && is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) {
button.hover = true;
-
- // Trigger the on_enter callback if the hover state just changed to true
if (!was_hovering && button.on_enter) {
button.on_enter();
}
} else {
button.hover = false;
-
// Trigger the on_exit callback if the hover state just changed to false
if (was_hovering && button.on_exit) {
button.on_exit();
@@ -111,7 +125,7 @@ void InputSystem::handle_move(const SDLContext::EventData & event_data) {
}
}
-void InputSystem::handle_click(const SDLContext::EventData & event_data) {
+void InputSystem::handle_click(const MouseButton& mouse_button, const int& world_mouse_x, const int& world_mouse_y) {
ComponentManager & mgr = this->component_manager;
RefVector<Button> buttons = mgr.get_components_by_type<Button>();
@@ -121,18 +135,17 @@ void InputSystem::handle_click(const SDLContext::EventData & event_data) {
= mgr.get_components_by_id<Transform>(button.game_object_id);
OptionalRef<Transform> transform(transform_vec.front().get());
- if (button.active && is_mouse_inside_button(event_data, button, transform)) {
+ if (button.active && is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) {
handle_button_press(button);
}
}
}
-bool InputSystem::is_mouse_inside_button(const SDLContext::EventData & event_data,
- const Button & button, const Transform & transform) {
- return event_data.mouse_position.first >= transform.position.x
- && event_data.mouse_position.first <= transform.position.x + button.width
- && event_data.mouse_position.second >= transform.position.y
- && event_data.mouse_position.second <= transform.position.y + button.height;
+bool InputSystem::is_mouse_inside_button(const int& mouse_x, const int& mouse_y, const Button & button, const Transform & transform) {
+ return mouse_x >= transform.position.x
+ && mouse_x <= transform.position.x + button.width
+ && mouse_y >= transform.position.y
+ && mouse_y <= transform.position.y + button.height;
}
void InputSystem::handle_button_press(Button & button) {
diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h
index c6ca114..e937d01 100644
--- a/src/crepe/system/InputSystem.h
+++ b/src/crepe/system/InputSystem.h
@@ -8,69 +8,77 @@
namespace crepe {
+class Camera;
class Button;
-
class Transform;
+
/**
- * \class InputSystem
* \brief Handles the processing of input events like mouse and keyboard interactions.
- *
+ *
* This system processes events such as mouse clicks, mouse movement, and keyboard
* actions. It is responsible for detecting interactions with UI buttons and
* passing the corresponding events to the registered listeners.
*/
class InputSystem : public System {
public:
- using System::System;
+ using System::System;
- /**
+ /**
* \brief Updates the system, processing all input events.
* This method processes all events and triggers corresponding actions.
*/
- void update() override;
+ void update() override;
private:
- //! Stores the last position of the mouse when the button was pressed.
- std::pair<int, int> last_mouse_down_position{-1, -1};
+ //! Reference to the currently active camera.
+ OptionalRef<Camera> curr_cam_ref;
- //! Stores the last mouse button pressed.
- MouseButton last_mouse_button = MouseButton::NONE;
+ //! Stores the last position of the mouse when the button was pressed.
+ std::pair<int, int> last_mouse_down_position{INFINITY, INFINITY};
- //! The tolerance in game units for detecting a mouse click.
- const int click_tolerance = 5;
+ //! Stores the last mouse button pressed.
+ MouseButton last_mouse_button = MouseButton::NONE;
+ //
+ //! The tolerance in game units for detecting a mouse click.
+ const int click_tolerance = 5;
/**
- * \brief Handles the click event.
- * \param eventData The event data containing information about the mouse click.
- *
- * This method processes the mouse click event and triggers the corresponding button action.
- */
- void handle_click(const SDLContext::EventData & eventData);
+ * \brief Handles the mouse click event.
+ * \param mouse_button The mouse button involved in the click.
+ * \param world_mouse_x The X coordinate of the mouse in world space.
+ * \param world_mouse_y The Y coordinate of the mouse in world space.
+ *
+ * This method processes the mouse click event and triggers the corresponding button action.
+ */
+ void handle_click(const MouseButton& mouse_button, const int& world_mouse_x, const int& world_mouse_y);
/**
- * \brief Handles the mouse movement event.
- * \param eventData The event data containing information about the mouse movement.
- *
- * This method processes the mouse movement event and updates the button hover state.
- */
- void handle_move(const SDLContext::EventData & eventData);
+ * \brief Handles the mouse movement event.
+ * \param event_data The event data containing information about the mouse movement.
+ * \param world_mouse_x The X coordinate of the mouse in world space.
+ * \param world_mouse_y The Y coordinate of the mouse in world space.
+ *
+ * This method processes the mouse movement event and updates the button hover state.
+ */
+ void handle_move(const SDLContext::EventData& event_data, const int& world_mouse_x, const int& world_mouse_y);
+
/**
- * \brief Checks if the mouse position is inside the bounds of the button.
- * \param eventData The event data containing the mouse position.
- * \param button The button to check.
- * \param transform The transform component of the button.
- * \return True if the mouse is inside the button, false otherwise.
- */
- bool is_mouse_inside_button(const SDLContext::EventData & eventData, const Button & button,
- const Transform & transform);
+ * \brief Checks if the mouse position is inside the bounds of the button.
+ * \param mouse_x The X coordinate of the mouse.
+ * \param mouse_y The Y coordinate of the mouse.
+ * \param button The button to check.
+ * \param transform The transform component of the button.
+ * \return True if the mouse is inside the button, false otherwise.
+ */
+ bool is_mouse_inside_button(const int& mouse_x, const int& mouse_y, const Button& button, const Transform& transform);
/**
- * \brief Handles the button press event, calling the on_click callback if necessary.
- * \param button The button being pressed.
- *
- * This method triggers the on_click action for the button when it is pressed.
- */
- void handle_button_press(Button & button);
+ * \brief Handles the button press event, calling the on_click callback if necessary.
+ * \param button The button being pressed.
+ *
+ * This method triggers the on_click action for the button when it is pressed.
+ */
+ void handle_button_press(Button& button);
};
} // namespace crepe
diff --git a/src/test/InputTest.cpp b/src/test/InputTest.cpp
index 4f6077b..9725836 100644
--- a/src/test/InputTest.cpp
+++ b/src/test/InputTest.cpp
@@ -12,6 +12,7 @@
#include <crepe/api/Metadata.h>
#include <crepe/api/Transform.h>
#include <crepe/api/Vector2.h>
+#include <crepe/api/Camera.h>
#include <gmock/gmock.h>
using namespace std;
@@ -26,7 +27,10 @@ public:
EventManager & event_manager = EventManager::get_instance();
protected:
- void SetUp() override { event_manager.clear(); }
+ void SetUp() override {
+ event_manager.clear();
+ // GameObject camera = mgr.new_object<Camera>(Color{0,0,0,0},ivec2{0,0},vec2{500,500},0,vec2{0,0});
+ }
void simulate_mouse_click(int mouse_x, int mouse_y, Uint8 mouse_button) {
SDL_Event event;
@@ -47,6 +51,7 @@ protected:
event.button.button = mouse_button;
SDL_PushEvent(&event);
}
+ GameObject camera;
};
TEST_F(InputTest, MouseDown) {