diff options
Diffstat (limited to 'src/crepe/facade')
-rw-r--r-- | src/crepe/facade/DB.cpp | 4 | ||||
-rw-r--r-- | src/crepe/facade/DB.h | 4 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 305 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 39 | ||||
-rw-r--r-- | src/crepe/facade/Sound.cpp | 2 | ||||
-rw-r--r-- | src/crepe/facade/Sound.h | 2 |
6 files changed, 104 insertions, 252 deletions
diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp index d5d19dc..95cf606 100644 --- a/src/crepe/facade/DB.cpp +++ b/src/crepe/facade/DB.cpp @@ -18,8 +18,8 @@ DB::DB(const string & path) { this->db = {db, [](libdb::DB * db) { db->close(db, 0); }}; // load or create database file - ret = this->db->open(this->db.get(), NULL, path.c_str(), NULL, libdb::DB_BTREE, DB_CREATE, - 0); + const char * file = path.empty() ? NULL : path.c_str(); + ret = this->db->open(this->db.get(), NULL, file, NULL, libdb::DB_BTREE, DB_CREATE, 0); if (ret != 0) throw runtime_error(format("db->open: {}", libdb::db_strerror(ret))); // create cursor diff --git a/src/crepe/facade/DB.h b/src/crepe/facade/DB.h index 629b0eb..115c0f1 100644 --- a/src/crepe/facade/DB.h +++ b/src/crepe/facade/DB.h @@ -22,8 +22,10 @@ class DB { public: /** * \param path The path of the database (created if nonexistant) + * + * \note If \p path is empty, the database is entirely in-memory */ - DB(const std::string & path); + DB(const std::string & path = ""); virtual ~DB() = default; public: diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 3fb7f05..ff7c9f0 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -1,5 +1,6 @@ #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> +#include <SDL2/SDL_keycode.h> #include <SDL2/SDL_rect.h> #include <SDL2/SDL_render.h> #include <SDL2/SDL_surface.h> @@ -7,15 +8,15 @@ #include <cmath> #include <cstddef> #include <functional> -#include <iostream> #include <memory> +#include <stdexcept> #include <string> #include <array> +#include "../api/Camera.h" #include "../api/Sprite.h" #include "../api/Texture.h" #include "../api/Transform.h" -#include "../api/EventManager.h" #include "../util/Log.h" @@ -33,29 +34,22 @@ SDLContext::SDLContext() { dbg_trace(); // FIXME: read window defaults from config manager - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - // FIXME: throw exception - std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl; - return; + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + throw runtime_error(format("SDLContext: SDL_Init error: {}", SDL_GetError())); } SDL_Window * tmp_window = SDL_CreateWindow("Crepe Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->viewport.w, this->viewport.h, 0); if (!tmp_window) { - // FIXME: throw exception - std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl; - return; + throw runtime_error(format("SDLContext: SDL_Window error: {}", SDL_GetError())); } this->game_window = {tmp_window, [](SDL_Window * window) { SDL_DestroyWindow(window); }}; SDL_Renderer * tmp_renderer = SDL_CreateRenderer(this->game_window.get(), -1, SDL_RENDERER_ACCELERATED); if (!tmp_renderer) { - // FIXME: throw exception - std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() - << std::endl; - SDL_DestroyWindow(this->game_window.get()); - return; + throw runtime_error( + format("SDLContext: SDL_CreateRenderer error: {}", SDL_GetError())); } this->game_renderer @@ -63,9 +57,7 @@ SDLContext::SDLContext() { int img_flags = IMG_INIT_PNG; if (!(IMG_Init(img_flags) & img_flags)) { - // FIXME: throw exception - std::cout << "SDL_image could not initialize! SDL_image Error: " << IMG_GetError() - << std::endl; + throw runtime_error("SDLContext: SDL_image could not initialize!"); } } @@ -82,211 +74,67 @@ SDLContext::~SDLContext() { SDL_Quit(); } -void SDLContext::handle_events(bool &running) { - EventManager& event_manager = EventManager::get_instance(); - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - running = false; - event_manager.trigger_event(ShutDownEvent{}); - break; - case SDL_KEYDOWN: - event_manager.trigger_event<KeyPressEvent>(KeyPressEvent{ - .repeat = event.key.repeat, - .key = this->sdl_to_keycode(event.key.keysym.scancode) - }); - break; - - case SDL_KEYUP: - event_manager.trigger_event<KeyReleaseEvent>(KeyReleaseEvent{ - .key = this->sdl_to_keycode(event.key.keysym.scancode), - }); - break; +void SDLContext::handle_events(bool & running) { + //TODO: wouter i need events + /* + SDL_Event event; + SDL_PollEvent(&event); + switch (event.type) { + case SDL_QUIT: + running = false; + break; + case SDL_KEYDOWN: + triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); + break; + case SDL_MOUSEBUTTONDOWN: + int x, y; + SDL_GetMouseState(&x, &y); + triggerEvent(MousePressedEvent(x, y)); + break; + } + */ +} - case SDL_MOUSEBUTTONDOWN: - { - int x, y; - SDL_GetMouseState(&x, &y); - event_manager.trigger_event<MousePressEvent>(MousePressEvent{ - .mouse_x = x, - .mouse_y = y, - .button = this->sdl_to_mousebutton(event.button.button) - }); - } - break; +void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); } +void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); } - case SDL_MOUSEBUTTONUP: - { - int x, y; - SDL_GetMouseState(&x, &y); - event_manager.trigger_event<MouseReleaseEvent>(MouseReleaseEvent{ - .mouse_x = x, - .mouse_y = y, - .button = this->sdl_to_mousebutton(event.button.button) - }); - } - break; +SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const { + return SDL_Rect{ + .x = sprite.sprite_rect.x, + .y = sprite.sprite_rect.y, + .w = sprite.sprite_rect.w, + .h = sprite.sprite_rect.h, + }; +} +SDL_Rect SDLContext::get_dst_rect(const Sprite & sprite, const vec2 & pos, + const double & scale, const Camera & cam) const { - case SDL_MOUSEMOTION: - event_manager.trigger_event<MouseMoveEvent>(MouseMoveEvent{ - .mouse_x = event.motion.x, - .mouse_y = event.motion.y, - .rel_x = event.motion.xrel, - .rel_y = event.motion.yrel - }); - break; + double adjusted_w = sprite.sprite_rect.w * scale * cam.zoom; + double adjusted_h = sprite.sprite_rect.h * scale * cam.zoom; + double adjusted_x = (pos.x - cam.x) * cam.zoom - adjusted_w / 2; + double adjusted_y = (pos.y - cam.y) * cam.zoom - adjusted_h / 2; - case SDL_MOUSEWHEEL: - event_manager.trigger_event<MouseScrollEvent>(MouseScrollEvent{ - .scroll_x = event.wheel.x, - .scroll_y = event.wheel.y, - .direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1) - }); - break; - } - } + return SDL_Rect{ + .x = static_cast<int>(adjusted_x), + .y = static_cast<int>(adjusted_y), + .w = static_cast<int>(adjusted_w), + .h = static_cast<int>(adjusted_h), + }; } +void SDLContext::draw_particle(const Sprite & sprite, const vec2 & pos, const double & angle, + const double & scale, const Camera & camera) { + SDL_RendererFlip render_flip + = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) + | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); -Keycode SDLContext::sdl_to_keycode(SDL_Keycode sdl_key) { - static const std::array<Keycode, SDL_NUM_SCANCODES> LOOKUP_TABLE = [] { - std::array<Keycode, SDL_NUM_SCANCODES> table{}; - table.fill(Keycode::NONE); - - table[SDL_SCANCODE_SPACE] = Keycode::SPACE; - table[SDL_SCANCODE_APOSTROPHE] = Keycode::APOSTROPHE; - table[SDL_SCANCODE_COMMA] = Keycode::COMMA; - table[SDL_SCANCODE_MINUS] = Keycode::MINUS; - table[SDL_SCANCODE_PERIOD] = Keycode::PERIOD; - table[SDL_SCANCODE_SLASH] = Keycode::SLASH; - table[SDL_SCANCODE_0] = Keycode::D0; - table[SDL_SCANCODE_1] = Keycode::D1; - table[SDL_SCANCODE_2] = Keycode::D2; - table[SDL_SCANCODE_3] = Keycode::D3; - table[SDL_SCANCODE_4] = Keycode::D4; - table[SDL_SCANCODE_5] = Keycode::D5; - table[SDL_SCANCODE_6] = Keycode::D6; - table[SDL_SCANCODE_7] = Keycode::D7; - table[SDL_SCANCODE_8] = Keycode::D8; - table[SDL_SCANCODE_9] = Keycode::D9; - table[SDL_SCANCODE_SEMICOLON] = Keycode::SEMICOLON; - table[SDL_SCANCODE_EQUALS] = Keycode::EQUAL; - table[SDL_SCANCODE_A] = Keycode::A; - table[SDL_SCANCODE_B] = Keycode::B; - table[SDL_SCANCODE_C] = Keycode::C; - table[SDL_SCANCODE_D] = Keycode::D; - table[SDL_SCANCODE_E] = Keycode::E; - table[SDL_SCANCODE_F] = Keycode::F; - table[SDL_SCANCODE_G] = Keycode::G; - table[SDL_SCANCODE_H] = Keycode::H; - table[SDL_SCANCODE_I] = Keycode::I; - table[SDL_SCANCODE_J] = Keycode::J; - table[SDL_SCANCODE_K] = Keycode::K; - table[SDL_SCANCODE_L] = Keycode::L; - table[SDL_SCANCODE_M] = Keycode::M; - table[SDL_SCANCODE_N] = Keycode::N; - table[SDL_SCANCODE_O] = Keycode::O; - table[SDL_SCANCODE_P] = Keycode::P; - table[SDL_SCANCODE_Q] = Keycode::Q; - table[SDL_SCANCODE_R] = Keycode::R; - table[SDL_SCANCODE_S] = Keycode::S; - table[SDL_SCANCODE_T] = Keycode::T; - table[SDL_SCANCODE_U] = Keycode::U; - table[SDL_SCANCODE_V] = Keycode::V; - table[SDL_SCANCODE_W] = Keycode::W; - table[SDL_SCANCODE_X] = Keycode::X; - table[SDL_SCANCODE_Y] = Keycode::Y; - table[SDL_SCANCODE_Z] = Keycode::Z; - table[SDL_SCANCODE_LEFTBRACKET] = Keycode::LEFT_BRACKET; - table[SDL_SCANCODE_BACKSLASH] = Keycode::BACKSLASH; - table[SDL_SCANCODE_RIGHTBRACKET] = Keycode::RIGHT_BRACKET; - table[SDL_SCANCODE_GRAVE] = Keycode::GRAVE_ACCENT; - table[SDL_SCANCODE_ESCAPE] = Keycode::ESCAPE; - table[SDL_SCANCODE_RETURN] = Keycode::ENTER; - table[SDL_SCANCODE_TAB] = Keycode::TAB; - table[SDL_SCANCODE_BACKSPACE] = Keycode::BACKSPACE; - table[SDL_SCANCODE_INSERT] = Keycode::INSERT; - table[SDL_SCANCODE_DELETE] = Keycode::DELETE; - table[SDL_SCANCODE_RIGHT] = Keycode::RIGHT; - table[SDL_SCANCODE_LEFT] = Keycode::LEFT; - table[SDL_SCANCODE_DOWN] = Keycode::DOWN; - table[SDL_SCANCODE_UP] = Keycode::UP; - table[SDL_SCANCODE_PAGEUP] = Keycode::PAGE_UP; - table[SDL_SCANCODE_PAGEDOWN] = Keycode::PAGE_DOWN; - table[SDL_SCANCODE_HOME] = Keycode::HOME; - table[SDL_SCANCODE_END] = Keycode::END; - table[SDL_SCANCODE_CAPSLOCK] = Keycode::CAPS_LOCK; - table[SDL_SCANCODE_SCROLLLOCK] = Keycode::SCROLL_LOCK; - table[SDL_SCANCODE_NUMLOCKCLEAR] = Keycode::NUM_LOCK; - table[SDL_SCANCODE_PRINTSCREEN] = Keycode::PRINT_SCREEN; - table[SDL_SCANCODE_PAUSE] = Keycode::PAUSE; - table[SDL_SCANCODE_F1] = Keycode::F1; - table[SDL_SCANCODE_F2] = Keycode::F2; - table[SDL_SCANCODE_F3] = Keycode::F3; - table[SDL_SCANCODE_F4] = Keycode::F4; - table[SDL_SCANCODE_F5] = Keycode::F5; - table[SDL_SCANCODE_F6] = Keycode::F6; - table[SDL_SCANCODE_F7] = Keycode::F7; - table[SDL_SCANCODE_F8] = Keycode::F8; - table[SDL_SCANCODE_F9] = Keycode::F9; - table[SDL_SCANCODE_F10] = Keycode::F10; - table[SDL_SCANCODE_F11] = Keycode::F11; - table[SDL_SCANCODE_F12] = Keycode::F12; - table[SDL_SCANCODE_KP_0] = Keycode::KP0; - table[SDL_SCANCODE_KP_1] = Keycode::KP1; - table[SDL_SCANCODE_KP_2] = Keycode::KP2; - table[SDL_SCANCODE_KP_3] = Keycode::KP3; - table[SDL_SCANCODE_KP_4] = Keycode::KP4; - table[SDL_SCANCODE_KP_5] = Keycode::KP5; - table[SDL_SCANCODE_KP_6] = Keycode::KP6; - table[SDL_SCANCODE_KP_7] = Keycode::KP7; - table[SDL_SCANCODE_KP_8] = Keycode::KP8; - table[SDL_SCANCODE_KP_9] = Keycode::KP9; - table[SDL_SCANCODE_LSHIFT] = Keycode::LEFT_SHIFT; - table[SDL_SCANCODE_LCTRL] = Keycode::LEFT_CONTROL; - table[SDL_SCANCODE_LALT] = Keycode::LEFT_ALT; - table[SDL_SCANCODE_LGUI] = Keycode::LEFT_SUPER; - table[SDL_SCANCODE_RSHIFT] = Keycode::RIGHT_SHIFT; - table[SDL_SCANCODE_RCTRL] = Keycode::RIGHT_CONTROL; - table[SDL_SCANCODE_RALT] = Keycode::RIGHT_ALT; - table[SDL_SCANCODE_RGUI] = Keycode::RIGHT_SUPER; - table[SDL_SCANCODE_MENU] = Keycode::MENU; - - return table; - }(); - - if (sdl_key < 0 || sdl_key >= SDL_NUM_SCANCODES) { - return Keycode::NONE; - } - - return LOOKUP_TABLE[sdl_key]; -} -MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) { - static const std::array<MouseButton, 8> MOUSE_BUTTON_LOOKUP_TABLE = [] { - std::array<MouseButton, 8> table{}; - table.fill(MouseButton::NONE); - - table[SDL_BUTTON_LEFT] = MouseButton::LEFT_MOUSE; - table[SDL_BUTTON_RIGHT] = MouseButton::RIGHT_MOUSE; - table[SDL_BUTTON_MIDDLE] = MouseButton::MIDDLE_MOUSE; - table[SDL_BUTTON_X1] = MouseButton::X1_MOUSE; - table[SDL_BUTTON_X2] = MouseButton::X2_MOUSE; - - return table; - }(); - - if (sdl_button >= MOUSE_BUTTON_LOOKUP_TABLE.size()) { - // Return NONE for invalid or unmapped button - return MouseButton::NONE; - } + SDL_Rect srcrect = this->get_src_rect(sprite); + SDL_Rect dstrect = this->get_dst_rect(sprite, pos, scale, camera); - return MOUSE_BUTTON_LOOKUP_TABLE[sdl_button]; + SDL_RenderCopyEx(this->game_renderer.get(), sprite.sprite_image->texture.get(), &srcrect, + &dstrect, angle, NULL, render_flip); } -void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); } -void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); } void SDLContext::draw(const Sprite & sprite, const Transform & transform, const Camera & cam) { @@ -294,34 +142,18 @@ void SDLContext::draw(const Sprite & sprite, const Transform & transform, const = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); - double adjusted_x = (transform.position.x - cam.x) * cam.zoom; - double adjusted_y = (transform.position.y - cam.y) * cam.zoom; - double adjusted_w = sprite.sprite_rect.w * transform.scale * cam.zoom; - double adjusted_h = sprite.sprite_rect.h * transform.scale * cam.zoom; - - SDL_Rect srcrect = { - .x = sprite.sprite_rect.x, - .y = sprite.sprite_rect.y, - .w = sprite.sprite_rect.w, - .h = sprite.sprite_rect.h, - }; - - SDL_Rect dstrect = { - .x = static_cast<int>(adjusted_x), - .y = static_cast<int>(adjusted_y), - .w = static_cast<int>(adjusted_w), - .h = static_cast<int>(adjusted_h), - }; + SDL_Rect srcrect = this->get_src_rect(sprite); + SDL_Rect dstrect = this->get_dst_rect(sprite, transform.position, transform.scale, cam); SDL_RenderCopyEx(this->game_renderer.get(), sprite.sprite_image->texture.get(), &srcrect, &dstrect, transform.rotation, NULL, render_flip); } -void SDLContext::camera(const Camera & cam) { +void SDLContext::set_camera(const Camera & cam) { this->viewport.w = static_cast<int>(cam.aspect_width); this->viewport.h = static_cast<int>(cam.aspect_height); - this->viewport.x = static_cast<int>(cam.x) - (SCREEN_WIDTH / 2); - this->viewport.y = static_cast<int>(cam.y) - (SCREEN_HEIGHT / 2); + this->viewport.x = static_cast<int>(cam.x) - (this->viewport.w / 2); + this->viewport.y = static_cast<int>(cam.y) - (this->viewport.h / 2); SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r, cam.bg_color.g, cam.bg_color.b, cam.bg_color.a); @@ -333,9 +165,8 @@ std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>> SDLContext::texture_from_path(const std::string & path) { SDL_Surface * tmp = IMG_Load(path.c_str()); - if (tmp == nullptr) { - tmp = IMG_Load("../asset/texture/ERROR.png"); - } + if (tmp == nullptr) + throw runtime_error(format("SDLContext: IMG_Load error: {}", SDL_GetError())); std::unique_ptr<SDL_Surface, std::function<void(SDL_Surface *)>> img_surface; img_surface = {tmp, [](SDL_Surface * surface) { SDL_FreeSurface(surface); }}; @@ -344,7 +175,7 @@ SDLContext::texture_from_path(const std::string & path) { = SDL_CreateTextureFromSurface(this->game_renderer.get(), img_surface.get()); if (tmp_texture == nullptr) { - throw runtime_error(format("Texture cannot be load from {}", path)); + throw runtime_error(format("SDLContext: Texture cannot be load from {}", path)); } std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>> img_texture; diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index dcd7440..5b6b093 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -1,8 +1,10 @@ #pragma once #include <SDL2/SDL.h> #include <SDL2/SDL_keycode.h> +#include <SDL2/SDL_rect.h> #include <SDL2/SDL_render.h> #include <SDL2/SDL_video.h> +#include <cmath> #include <functional> #include <memory> #include <string> @@ -14,17 +16,13 @@ #include "../api/Event.h" #include "api/Camera.h" -// FIXME: this needs to be removed -const int SCREEN_WIDTH = 640; -const int SCREEN_HEIGHT = 480; +#include "types.h" namespace crepe { // TODO: SDL_Keycode is defined in a header not distributed with crepe, which means this // typedef is unusable when crepe is packaged. Wouter will fix this later. //typedef SDL_Keycode CREPE_KEYCODES; - -class Texture; class LoopManager; class InputSystem; /** @@ -119,9 +117,6 @@ private: //! Will use the funtions: texture_from_path, get_width,get_height. friend class Texture; - //! Will use the funtions: texture_from_path, get_width,get_height. - friend class Animator; - /** * \brief Loads a texture from a file path. * \param path Path to the image file. @@ -155,6 +150,9 @@ private: */ void draw(const Sprite & sprite, const Transform & transform, const Camera & camera); + void draw_particle(const Sprite & sprite, const vec2 & pos, const double & angle, + const double & scale, const Camera & camera); + //! Clears the screen, preparing for a new frame. void clear_screen(); @@ -162,10 +160,31 @@ private: void present_screen(); /** - * \brief Sets the current camera for rendering. + * \brief sets the background of the camera (will be adjusted in future PR) * \param camera Reference to the Camera object. */ - void camera(const Camera & camera); + void set_camera(const Camera & camera); + +private: + /** + * \brief calculates the sqaure size of the image + * + * \param sprite Reference to the sprite to calculate the rectangle + * \return sdl rectangle to draw a src image + */ + SDL_Rect get_src_rect(const Sprite & sprite) const; + /** + * \brief calculates the sqaure size of the image for an destination + * + * \param sprite Reference to the sprite to calculate the rectangle + * \param pos the pos in pixel positions + * \param scale the multiplier to increase of decrease for the specified sprite + * \param cam Reference to the current camera in the scene to calculate the position based + * on the camera + * \return sdl rectangle to draw a dst image to draw on the screen + */ + SDL_Rect get_dst_rect(const Sprite & sprite, const vec2 & pos, const double & scale, + const Camera & cam) const; private: //! sdl Window diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp index 7aa89a9..4d3abf5 100644 --- a/src/crepe/facade/Sound.cpp +++ b/src/crepe/facade/Sound.cpp @@ -16,7 +16,7 @@ Sound::Sound(const char * src) { this->load(make_unique<Asset>(src)); } -void Sound::load(unique_ptr<Asset> res) { this->sample.load(res->get_canonical().c_str()); } +void Sound::load(unique_ptr<Asset> res) { this->sample.load(res->get_path().c_str()); } void Sound::play() { SoundContext & ctx = SoundContext::get_instance(); diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h index 32b6478..4c68f32 100644 --- a/src/crepe/facade/Sound.h +++ b/src/crepe/facade/Sound.h @@ -4,7 +4,7 @@ #include <soloud/soloud.h> #include <soloud/soloud_wav.h> -#include "../Asset.h" +#include "../api/Asset.h" namespace crepe { |