diff options
Diffstat (limited to 'src/crepe/facade')
-rw-r--r-- | src/crepe/facade/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 153 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 93 | ||||
-rw-r--r-- | src/crepe/facade/Sound.cpp | 54 | ||||
-rw-r--r-- | src/crepe/facade/Sound.h | 77 | ||||
-rw-r--r-- | src/crepe/facade/SoundContext.cpp | 30 | ||||
-rw-r--r-- | src/crepe/facade/SoundContext.h | 62 | ||||
-rw-r--r-- | src/crepe/facade/SoundHandle.h | 12 | ||||
-rw-r--r-- | src/crepe/facade/Texture.cpp | 28 | ||||
-rw-r--r-- | src/crepe/facade/Texture.h | 69 |
10 files changed, 319 insertions, 261 deletions
diff --git a/src/crepe/facade/CMakeLists.txt b/src/crepe/facade/CMakeLists.txt index 4cc53bc..0598e16 100644 --- a/src/crepe/facade/CMakeLists.txt +++ b/src/crepe/facade/CMakeLists.txt @@ -1,5 +1,6 @@ target_sources(crepe PUBLIC Sound.cpp + Texture.cpp SoundContext.cpp SDLContext.cpp DB.cpp @@ -7,6 +8,7 @@ target_sources(crepe PUBLIC target_sources(crepe PUBLIC FILE_SET HEADERS FILES Sound.h + Texture.h SoundContext.h SDLContext.h DB.h diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 8f6c02c..4552605 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -2,6 +2,7 @@ #include <SDL2/SDL_blendmode.h> #include <SDL2/SDL_image.h> #include <SDL2/SDL_keycode.h> +#include <SDL2/SDL_pixels.h> #include <SDL2/SDL_rect.h> #include <SDL2/SDL_render.h> #include <SDL2/SDL_surface.h> @@ -18,23 +19,18 @@ #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::get_instance() { - static SDLContext instance; - return instance; -} - -SDLContext::SDLContext() { +SDLContext::SDLContext(Mediator & mediator) { dbg_trace(); - if (SDL_Init(SDL_INIT_VIDEO) != 0) { throw runtime_error(format("SDLContext: SDL_Init error: {}", SDL_GetError())); } @@ -62,6 +58,8 @@ SDLContext::SDLContext() { if (!(IMG_Init(img_flags) & img_flags)) { throw runtime_error("SDLContext: SDL_image could not initialize!"); } + + mediator.sdl_context = *this; } SDLContext::~SDLContext() { @@ -236,35 +234,26 @@ 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 * ctx.sprite.aspect_ratio; + size.x = data.size.y * aspect_ratio; } if (data.size.y == 0 && data.size.x != 0) { - size.y = data.size.x / ctx.sprite.aspect_ratio; + size.y = data.size.x / aspect_ratio; } + size *= cam_aux_data.render_scale * ctx.img_scale * data.scale_offset; - const CameraValues & cam = ctx.cam; - - size *= cam.render_scale * ctx.img_scale * data.scale_offset; - - vec2 screen_pos - = (ctx.pos + data.position_offset - cam.cam_pos + (cam.zoomed_viewport) / 2) - * cam.render_scale - - size / 2 + cam.bar_size; + vec2 screen_pos = (ctx.pos + data.position_offset - cam_aux_data.cam_pos + + (cam_aux_data.zoomed_viewport) / 2) + * cam_aux_data.render_scale + - size / 2 + cam_aux_data.bar_size; return SDL_FRect{ .x = screen_pos.x, @@ -275,31 +264,38 @@ 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 = this->get_src_rect(ctx.sprite); + 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_FRect dstrect = this->get_dst_rect(SDLContext::DestinationRectangleData{ .sprite = ctx.sprite, - .cam = ctx.cam, + .texture = ctx.texture, .pos = ctx.pos, .img_scale = ctx.scale, }); double angle = ctx.angle + data.angle_offset; - 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); + 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); } -SDLContext::CameraValues SDLContext::set_camera(const Camera & cam) { +void SDLContext::update_camera_view(const Camera & cam, const vec2 & new_pos) { const Camera::Data & cam_data = cam.data; - CameraValues ret_cam; // resize window int w, h; SDL_GetWindowSize(this->game_window.get(), &w, &h); @@ -307,9 +303,10 @@ SDLContext::CameraValues SDLContext::set_camera(const Camera & cam) { SDL_SetWindowSize(this->game_window.get(), cam.screen.x, cam.screen.y); } - vec2 & zoomed_viewport = ret_cam.zoomed_viewport; - vec2 & bar_size = ret_cam.bar_size; - vec2 & render_scale = ret_cam.render_scale; + vec2 & zoomed_viewport = this->cam_aux_data.zoomed_viewport; + vec2 & bar_size = this->cam_aux_data.bar_size; + vec2 & render_scale = this->cam_aux_data.render_scale; + this->cam_aux_data.cam_pos = new_pos; zoomed_viewport = cam.viewport_size * cam_data.zoom; float screen_aspect = static_cast<float>(cam.screen.x) / cam.screen.y; @@ -351,12 +348,8 @@ SDLContext::CameraValues SDLContext::set_camera(const Camera & cam) { // fill bg color SDL_RenderFillRect(this->game_renderer.get(), &bg); - - 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) { @@ -383,18 +376,17 @@ SDLContext::texture_from_path(const std::string & path) { ivec2 SDLContext::get_size(const Texture & ctx) { ivec2 size; - SDL_QueryTexture(ctx.texture.get(), NULL, NULL, &size.x, &size.y); + SDL_QueryTexture(ctx.get_img(), 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)) { + ivec2 mouse_pos; + mouse_pos.x = (event.button.x - cam.bar_size.x) / cam.render_scale.x; + mouse_pos.y = (event.button.y - cam.bar_size.y) / cam.render_scale.y; switch (event.type) { case SDL_QUIT: event_list.push_back({SDLContext::EventType::SHUTDOWN, {}, {}, {}}); @@ -413,41 +405,38 @@ std::vector<SDLContext::EventData> SDLContext::get_events() { {}}); break; case SDL_MOUSEBUTTONDOWN: - event_list.push_back({SDLContext::EventType::MOUSEDOWN, - {}, - {sdl_to_mousebutton(event.button.button), - {event.button.x, event.button.y}}, - {}}); + 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: - 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_MOUSEWHEEL: + 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( - {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; + 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; } } @@ -489,6 +478,6 @@ void SDLContext::handle_window_event(const SDL_WindowEvent & window_event, } 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); + SDL_SetTextureColorMod(texture.get_img(), color.r, color.g, color.b); + SDL_SetTextureAlphaMod(texture.get_img(), color.a); } diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 053aa59..0a2456d 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -15,16 +15,16 @@ #include "api/Color.h" #include "api/KeyCodes.h" #include "api/Sprite.h" -#include "api/Texture.h" #include "api/Transform.h" + #include "types.h" namespace crepe { -class LoopManager; -class InputSystem; +class Texture; +class Mediator; + /** - * \class SDLContext * \brief Facade for the SDL library * * SDLContext is a singleton that handles the SDL window and renderer, provides methods for @@ -33,7 +33,7 @@ class InputSystem; class SDLContext { public: //! data that the camera component cannot hold - struct CameraValues { + struct CameraAuxiliaryData { //! zoomed in viewport in game_units vec2 zoomed_viewport; @@ -63,7 +63,7 @@ public: //! rendering data needed to render on screen struct RenderContext { const Sprite & sprite; - const CameraValues & cam; + const Texture & texture; const vec2 & pos; const double & angle; const double & scale; @@ -129,14 +129,26 @@ public: */ static SDLContext & get_instance(); +public: SDLContext(const SDLContext &) = delete; SDLContext(SDLContext &&) = delete; SDLContext & operator=(const SDLContext &) = delete; SDLContext & operator=(SDLContext &&) = delete; -private: - //! will only use get_events - friend class InputSystem; +public: + /** + * \brief Constructs an SDLContext instance. + * Initializes SDL, creates a window and renderer. + */ + SDLContext(Mediator & mediator); + + /** + * \brief Destroys the SDLContext instance. + * Cleans up SDL resources, including the window and renderer. + */ + ~SDLContext(); + +public: /** * \brief Retrieves a list of all events from the SDL context. * @@ -177,9 +189,7 @@ private: */ MouseButton sdl_to_mousebutton(Uint8 sdl_button); -private: - //! Will only use delay - friend class LoopTimer; +public: /** * \brief Gets the current SDL ticks since the program started. * \return Current ticks in milliseconds as a constant uint64_t. @@ -195,23 +205,7 @@ private: */ void delay(int ms) const; -private: - /** - * \brief Constructs an SDLContext instance. - * Initializes SDL, creates a window and renderer. - */ - SDLContext(); - - /** - * \brief Destroys the SDLContext instance. - * Cleans up SDL resources, including the window and renderer. - */ - ~SDLContext(); - -private: - //! Will use the funtions: texture_from_path, get_width,get_height. - friend class Texture; - +public: /** * \brief Loads a texture from a file path. * \param path Path to the image file. @@ -222,14 +216,11 @@ private: /** * \brief Gets the size of a texture. * \param texture Reference to the Texture object. - * \return Width and height of the texture as an integer. + * \return Width and height of the texture as an integer in pixels. */ ivec2 get_size(const Texture & ctx); -private: - //! Will use draw,clear_screen, present_screen, camera. - friend class RenderSystem; - +public: /** * \brief Draws a sprite to the screen using the specified transform and camera. * \param RenderContext Reference to rendering data to draw @@ -243,35 +234,28 @@ private: void present_screen(); /** - * \brief sets the background of the camera (will be adjusted in future PR) - * \param camera Reference to the Camera object. + * \brief calculates camera view settings. such as black_bars, zoomed_viewport, scaling and + * adjusting window size. + * + * \note only supports windowed mode. + * \param camera Reference to the current Camera object in the scene. + * \param new_pos new camera position from transform and offset */ - CameraValues set_camera(const Camera & camera); + void update_camera_view(const Camera & camera, const vec2 & new_pos); -private: +public: //! the data needed to construct a sdl dst rectangle struct DestinationRectangleData { const Sprite & sprite; - const CameraValues & cam; + const Texture & texture; const vec2 & pos; const double & img_scale; }; - /** - * \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 destination * - * \param sprite Reference to the sprite to calculate rectangle - * \param pos the pos in world units - * \param cam the camera of the current scene - * \param cam_pos the current postion of the camera - * \param img_scale the image multiplier for increasing img size + * \param data needed to calculate a destination rectangle * \return sdl rectangle to draw a dst image to draw on the screen */ SDL_FRect get_dst_rect(const DestinationRectangleData & data) const; @@ -292,6 +276,13 @@ private: //! black bars rectangle to draw SDL_FRect black_bars[2] = {}; + + /** + * \cam_aux_data extra data that the component cannot hold. + * + * - this is defined in this class because get_events() needs this information aswell + */ + CameraAuxiliaryData cam_aux_data; }; } // namespace crepe diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp index 4d3abf5..97e455e 100644 --- a/src/crepe/facade/Sound.cpp +++ b/src/crepe/facade/Sound.cpp @@ -1,59 +1,13 @@ +#include "../api/Asset.h" #include "../util/Log.h" #include "Sound.h" -#include "SoundContext.h" using namespace crepe; using namespace std; -Sound::Sound(unique_ptr<Asset> res) { +Sound::Sound(const Asset & src, Mediator & mediator) : Resource(src, mediator) { + this->sample.load(src.get_path().c_str()); dbg_trace(); - this->load(std::move(res)); -} - -Sound::Sound(const char * src) { - dbg_trace(); - this->load(make_unique<Asset>(src)); -} - -void Sound::load(unique_ptr<Asset> res) { this->sample.load(res->get_path().c_str()); } - -void Sound::play() { - SoundContext & ctx = SoundContext::get_instance(); - if (ctx.engine.getPause(this->handle)) { - // resume if paused - ctx.engine.setPause(this->handle, false); - } else { - // or start new sound - this->handle = ctx.engine.play(this->sample, this->volume); - ctx.engine.setLooping(this->handle, this->looping); - } -} - -void Sound::pause() { - SoundContext & ctx = SoundContext::get_instance(); - if (ctx.engine.getPause(this->handle)) return; - ctx.engine.setPause(this->handle, true); -} - -void Sound::rewind() { - SoundContext & ctx = SoundContext::get_instance(); - if (!ctx.engine.isValidVoiceHandle(this->handle)) return; - ctx.engine.seek(this->handle, 0); -} - -void Sound::set_volume(float volume) { - this->volume = volume; - - SoundContext & ctx = SoundContext::get_instance(); - if (!ctx.engine.isValidVoiceHandle(this->handle)) return; - ctx.engine.setVolume(this->handle, this->volume); -} - -void Sound::set_looping(bool looping) { - this->looping = looping; - - SoundContext & ctx = SoundContext::get_instance(); - if (!ctx.engine.isValidVoiceHandle(this->handle)) return; - ctx.engine.setLooping(this->handle, this->looping); } +Sound::~Sound() { dbg_trace(); } diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h index ee43d94..4a5d692 100644 --- a/src/crepe/facade/Sound.h +++ b/src/crepe/facade/Sound.h @@ -1,84 +1,31 @@ #pragma once -#include <memory> #include <soloud/soloud.h> #include <soloud/soloud_wav.h> -#include "../api/Asset.h" +#include "../Resource.h" namespace crepe { +class SoundContext; +class Mediator; + /** * \brief Sound resource facade * - * This class is a wrapper around a \c SoLoud::Wav instance, which holds a - * single sample. It is part of the sound facade. + * This class is a wrapper around a \c SoLoud::Wav instance, which holds a single sample. It is + * part of the sound facade. */ -class Sound { -public: - /** - * \brief Pause this sample - * - * Pauses this sound if it is playing, or does nothing if it is already paused. The playhead - * position is saved, such that calling \c play() after this function makes the sound resume. - */ - void pause(); - /** - * \brief Play this sample - * - * Resume playback if this sound is paused, or start from the beginning of the sample. - * - * \note This class only saves a reference to the most recent 'voice' of this sound. Calling - * \c play() while the sound is already playing causes multiple instances of the sample to - * play simultaniously. The sample started last is the one that is controlled afterwards. - */ - void play(); - /** - * \brief Reset playhead position - * - * Resets the playhead position so that calling \c play() after this function makes it play - * from the start of the sample. If the sound is not paused before calling this function, - * this function will stop playback. - */ - void rewind(); - /** - * \brief Set playback volume / gain - * - * \param volume Volume (0 = muted, 1 = full volume) - */ - void set_volume(float volume); - /** - * \brief Get playback volume / gain - * - * \return Volume - */ - float get_volume() const { return this->volume; } - /** - * \brief Set looping behavior for this sample - * - * \param looping Looping behavior (false = one-shot, true = loop) - */ - void set_looping(bool looping); - /** - * \brief Get looping behavior - * - * \return true if looping, false if one-shot - */ - bool get_looping() const { return this->looping; } - +class Sound : public Resource { public: - Sound(const char * src); - Sound(std::unique_ptr<Asset> res); - -private: - void load(std::unique_ptr<Asset> res); + Sound(const Asset & src, Mediator & mediator); + ~Sound(); // dbg_trace private: + //! Deserialized resource (soloud) SoLoud::Wav sample; - SoLoud::handle handle; - - float volume = 1.0f; - bool looping = false; + //! SoundContext uses \c sample + friend class SoundContext; }; } // namespace crepe diff --git a/src/crepe/facade/SoundContext.cpp b/src/crepe/facade/SoundContext.cpp index deb2b62..b1f8cb3 100644 --- a/src/crepe/facade/SoundContext.cpp +++ b/src/crepe/facade/SoundContext.cpp @@ -4,17 +4,33 @@ using namespace crepe; -SoundContext & SoundContext::get_instance() { - static SoundContext instance; - return instance; -} - SoundContext::SoundContext() { dbg_trace(); - engine.init(); + this->engine.init(); + this->engine.setMaxActiveVoiceCount(this->config.audio.voices); } SoundContext::~SoundContext() { dbg_trace(); - engine.deinit(); + this->engine.deinit(); +} + +SoundHandle SoundContext::play(Sound & resource) { + SoLoud::handle real_handle = this->engine.play(resource.sample, 1.0f); + SoundHandle handle = this->next_handle; + this->registry[handle] = real_handle; + this->next_handle++; + return handle; +} + +void SoundContext::stop(const SoundHandle & handle) { + this->engine.stop(this->registry[handle]); +} + +void SoundContext::set_volume(const SoundHandle & handle, float volume) { + this->engine.setVolume(this->registry[handle], volume); +} + +void SoundContext::set_loop(const SoundHandle & handle, bool loop) { + this->engine.setLooping(this->registry[handle], loop); } diff --git a/src/crepe/facade/SoundContext.h b/src/crepe/facade/SoundContext.h index d703c16..d986c59 100644 --- a/src/crepe/facade/SoundContext.h +++ b/src/crepe/facade/SoundContext.h @@ -2,30 +2,80 @@ #include <soloud/soloud.h> +#include "../api/Config.h" + #include "Sound.h" +#include "SoundHandle.h" namespace crepe { /** * \brief Sound engine facade * - * This class is a wrapper around a \c SoLoud::Soloud instance, which provides - * the methods for playing \c Sound instances. It is part of the sound facade. + * This class is a wrapper around a \c SoLoud::Soloud instance, which provides the methods for + * playing \c Sound instances. It is part of the sound facade. */ class SoundContext { -private: - // singleton +public: SoundContext(); virtual ~SoundContext(); + SoundContext(const SoundContext &) = delete; SoundContext(SoundContext &&) = delete; SoundContext & operator=(const SoundContext &) = delete; SoundContext & operator=(SoundContext &&) = delete; + /** + * \brief Play a sample + * + * Plays a Sound from the beginning of the sample and returns a handle to control it later. + * + * \param resource Sound instance to play + * + * \returns Handle to control this voice + */ + virtual SoundHandle play(Sound & resource); + /** + * \brief Stop a voice immediately if it is still playing + * + * \note This function does nothing if the handle is invalid or if the sound is already + * stopped / finished playing. + * + * \param handle Voice handle returned by SoundContext::play + */ + virtual void stop(const SoundHandle & handle); + /** + * \brief Change the volume of a voice + * + * \note This function does nothing if the handle is invalid or if the sound is already + * stopped / finished playing. + * + * \param handle Voice handle returned by SoundContext::play + * \param volume New gain value (0=silent, 1=default) + */ + virtual void set_volume(const SoundHandle & handle, float volume); + /** + * \brief Set the looping behavior of a voice + * + * \note This function does nothing if the handle is invalid or if the sound is already + * stopped / finished playing. + * + * \param handle Voice handle returned by SoundContext::play + * \param loop Looping behavior (false=oneshot, true=loop) + */ + virtual void set_loop(const SoundHandle & handle, bool loop); + private: - static SoundContext & get_instance(); + //! Abstracted class SoLoud::Soloud engine; - friend class Sound; + + //! Config reference + Config & config = Config::get_instance(); + + //! Sound handle registry + std::unordered_map<SoundHandle, SoLoud::handle> registry; + //! Unique handle counter + SoundHandle next_handle = 0; }; } // namespace crepe diff --git a/src/crepe/facade/SoundHandle.h b/src/crepe/facade/SoundHandle.h new file mode 100644 index 0000000..b7925fc --- /dev/null +++ b/src/crepe/facade/SoundHandle.h @@ -0,0 +1,12 @@ +#pragma once + +#include <cstddef> + +namespace crepe { + +/** + * \brief Voice handle returned by + */ +typedef size_t SoundHandle; + +} // namespace crepe diff --git a/src/crepe/facade/Texture.cpp b/src/crepe/facade/Texture.cpp new file mode 100644 index 0000000..b63403d --- /dev/null +++ b/src/crepe/facade/Texture.cpp @@ -0,0 +1,28 @@ +#include "../util/Log.h" +#include "facade/SDLContext.h" +#include "manager/Mediator.h" + +#include "Resource.h" +#include "Texture.h" +#include "types.h" + +using namespace crepe; +using namespace std; + +Texture::Texture(const Asset & src, Mediator & mediator) : Resource(src, mediator) { + dbg_trace(); + SDLContext & ctx = mediator.sdl_context; + this->texture = ctx.texture_from_path(src.get_path()); + this->size = ctx.get_size(*this); + this->aspect_ratio = static_cast<float>(this->size.x) / this->size.y; +} + +Texture::~Texture() { + dbg_trace(); + this->texture.reset(); +} + +const ivec2 & Texture::get_size() const noexcept { return this->size; } +const float & Texture::get_ratio() const noexcept { return this->aspect_ratio; } + +SDL_Texture * Texture::get_img() const noexcept { return this->texture.get(); } diff --git a/src/crepe/facade/Texture.h b/src/crepe/facade/Texture.h new file mode 100644 index 0000000..cdacac4 --- /dev/null +++ b/src/crepe/facade/Texture.h @@ -0,0 +1,69 @@ +#pragma once + +#include <SDL2/SDL_render.h> +#include <memory> + +#include "../Resource.h" + +#include "types.h" + +namespace crepe { + +class Mediator; +class Asset; + +/** + * \class Texture + * \brief Manages texture loading and properties. + * + * The Texture class is responsible for loading an image from a source and providing access to + * its dimensions. Textures can be used for rendering. + */ +class Texture : public Resource { + +public: + /** + * \brief Constructs a Texture from an Asset resource. + * \param src Asset with texture data to load. + * \param mediator use the SDLContext reference to load the image + */ + Texture(const Asset & src, Mediator & mediator); + + /** + * \brief Destroys the Texture instance + */ + ~Texture(); + + /** + * \brief get width and height of image in pixels + * \return pixel size width and height + * + */ + const ivec2 & get_size() const noexcept; + + /** + * \brief aspect_ratio of image + * \return ratio + * + */ + const float & get_ratio() const noexcept; + + /** + * \brief get the image texture + * \return SDL_Texture + * + */ + SDL_Texture * get_img() const noexcept; + +private: + //! The texture of the class from the library + std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>> texture; + + // texture size in pixel + ivec2 size; + + //! ratio of image + float aspect_ratio; +}; + +} // namespace crepe |