diff --git a/.gitignore b/.gitignore index 1571a4d..181f0ca 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ lib *.gcda *.o scores.txt +*.zip diff --git a/assets/nibbler/tail.ascii b/assets/nibbler/tail.ascii index 2afd973..301fb5f 100644 --- a/assets/nibbler/tail.ascii +++ b/assets/nibbler/tail.ascii @@ -1,3 +1,3 @@ -║═ +|- ~~~~ -╝╚╗╔ \ No newline at end of file +~~~~ \ No newline at end of file diff --git a/assets/snake/tail.ascii b/assets/snake/tail.ascii index 2afd973..301fb5f 100644 --- a/assets/snake/tail.ascii +++ b/assets/snake/tail.ascii @@ -1,3 +1,3 @@ -║═ +|- ~~~~ -╝╚╗╔ \ No newline at end of file +~~~~ \ No newline at end of file diff --git a/core/src/Core.cpp b/core/src/Core.cpp index c12b444..8cf6683 100644 --- a/core/src/Core.cpp +++ b/core/src/Core.cpp @@ -108,6 +108,9 @@ void Core::_initWindow() this->_graphicsProvider = this->_getGraphicsProvider(0); std::cerr << "No graphic provider selected, using default provider" << std::endl; } + this->_textures.clear(); + this->_fonts.clear(); + this->_sounds.clear(); this->_window = this->_graphicsProvider->createWindow(windowInitProps); this->_sceneStage = PLAY; } diff --git a/core/src/menu/Menu.cpp b/core/src/menu/Menu.cpp index 3bc9252..d1f7f1e 100644 --- a/core/src/menu/Menu.cpp +++ b/core/src/menu/Menu.cpp @@ -266,6 +266,9 @@ void Menu::_initTexts() void Menu::_clearLists() { + this->_nameField.reset(); + this->_font.reset(); + this->_music.reset(); this->_hiddenAuthors.clear(); this->_hiddenTexts.clear(); this->_texts.clear(); @@ -303,8 +306,8 @@ void Menu::_initWindow() }; try { - this->_window = this->_graphicsProvider->createWindow(windowInitProps); this->_clearLists(); + this->_window = this->_graphicsProvider->createWindow(windowInitProps); this->_preventGraphicsProvider(); this->_initTexts(); this->_initTextures(); @@ -410,7 +413,7 @@ void Menu::_selectGame() if (this->_checkBoxType == GAME_CHECKBOX) { for (auto checkBox : this->_gamesCheckBoxes) { if (checkBox->isHovered() && checkBox->isChecked()) - this->_exitWithNewGame(); + return this->_exitWithNewGame(); if (checkBox->isHovered()) checkBox->check(); else @@ -419,7 +422,7 @@ void Menu::_selectGame() } else { for (auto checkBox : this->_graphicsCheckBoxes) { if (checkBox->isHovered() && checkBox->isChecked()) - this->_changeGraphics(checkBox); + return this->_changeGraphics(checkBox); if (checkBox->isHovered()) checkBox->check(); else @@ -436,6 +439,8 @@ void Menu::_changeGraphics(std::shared_ptr checkBox) this->_graphicsProvider = graphicsProvider; this->_window->close(); this->_initWindow(); + this->_previousSelectedGame(); + this->_previousSelectedGraphics(); } } @@ -511,6 +516,11 @@ void Menu::_handleMouseButtonEvents(std::shared_ptr m this->_selectGame(); } } + for (auto checkBox : this->_graphicsCheckBoxes) { + if (checkBox->isHovered(position)) { + this->_selectGame(); + } + } } void Menu::_handleEvents() diff --git a/graphics/CMakeLists.txt b/graphics/CMakeLists.txt index 2715642..1d54559 100644 --- a/graphics/CMakeLists.txt +++ b/graphics/CMakeLists.txt @@ -1,2 +1,2 @@ -#add_subdirectory(ncurses) +add_subdirectory(ncurses) add_subdirectory(sfml) diff --git a/graphics/ncurses/CMakeLists.txt b/graphics/ncurses/CMakeLists.txt index 8abe0ed..4293bad 100644 --- a/graphics/ncurses/CMakeLists.txt +++ b/graphics/ncurses/CMakeLists.txt @@ -1,5 +1,26 @@ +project(ncurses) add_library(ncurses SHARED export.cpp + src/GraphicsProvider.cpp + src/GraphicsProvider.hpp + src/window/Window.cpp + src/window/Window.hpp + src/window/EventsHandler.cpp + src/window/EventsHandler.hpp + src/sound/Sound.cpp + src/sound/Sound.hpp + src/texture/Texture.cpp + src/texture/Texture.hpp + src/font/Font.cpp + src/font/Font.hpp + src/window/Renderer.cpp + src/window/Renderer.hpp ) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) + target_include_directories(ncurses PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) target_include_directories(ncurses PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) +target_include_directories(ncurses PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) + +find_package(Curses REQUIRED) +target_link_libraries(ncurses ${CURSES_LIBRARIES}) diff --git a/graphics/ncurses/export.cpp b/graphics/ncurses/export.cpp index 8ba688b..e5f48bd 100644 --- a/graphics/ncurses/export.cpp +++ b/graphics/ncurses/export.cpp @@ -7,16 +7,21 @@ #include "shared/games/IGameProvider.hpp" #include "shared/types/Libraries.hpp" +#include "src/GraphicsProvider.hpp" + +using namespace arcade::graphics; +using namespace shared::graphics; +using namespace shared::types; extern "C" { - shared::types::LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) + LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) { - return shared::types::LibraryType::GRAPHIC; + return LibraryType::GRAPHIC; } -/* std::shared_ptr SHARED_GRAPHICS_PROVIDER_LOADER_NAME(void) + IGraphicsProvider *SHARED_GRAPHICS_PROVIDER_GETTER_NAME(void) { - return std::make_shared(...); - }*/ + return new ncurses::GraphicsProvider(); + } } diff --git a/graphics/ncurses/src/GraphicsProvider.cpp b/graphics/ncurses/src/GraphicsProvider.cpp new file mode 100644 index 0000000..e154ef6 --- /dev/null +++ b/graphics/ncurses/src/GraphicsProvider.cpp @@ -0,0 +1,52 @@ +/* +** EPITECH PROJECT, 2024 +** GraphicsProvider.cpp +** File description: +** GraphicsProvider class +*/ + +#include +#include "GraphicsProvider.hpp" +#include "utils/compiler.hpp" +#include "window/Window.hpp" +#include "font/Font.hpp" +#include "sound/Sound.hpp" +#include "texture/Texture.hpp" + +using namespace shared::graphics; +using namespace arcade::graphics::ncurses; + +const shared::graphics::GraphicsManifest GraphicsProvider::_manifest = { + .name = "ncurses", + .description = "NCURSES Library", + .version = "1.0", + .authors = { + { + .name = "Yann Masson", + .email = "yann.masson@epitech.eu", + .website = "yannmasson.fr" + } + } +}; + +GraphicsProvider::GraphicsProvider() = default; + +const GraphicsManifest &GraphicsProvider::getManifest() const noexcept { + return GraphicsProvider::_manifest; +} + +std::unique_ptr GraphicsProvider::createWindow(const IWindow::WindowInitProps &props) { + return std::make_unique(props); +} + +std::shared_ptr GraphicsProvider::createSound(const std::string &path) { + return std::make_shared(path); +} + +std::shared_ptr GraphicsProvider::createTexture(unused const std::string &bin, const std::string &ascii) { + return std::make_shared(ascii); +} + +std::shared_ptr GraphicsProvider::createFont(const std::string &path) { + return std::make_shared(path); +} diff --git a/graphics/ncurses/src/GraphicsProvider.hpp b/graphics/ncurses/src/GraphicsProvider.hpp new file mode 100644 index 0000000..b617564 --- /dev/null +++ b/graphics/ncurses/src/GraphicsProvider.hpp @@ -0,0 +1,68 @@ +/* +** EPITECH PROJECT, 2024 +** GraphicsProvider.hpp +** File description: +** GraphicsProvider class +*/ + +#pragma once + +#include "shared/graphics/ITexture.hpp" +#include "shared/graphics/IGraphicsProvider.hpp" + +using namespace shared::graphics; + +namespace arcade::graphics::ncurses +{ + class GraphicsProvider; +} + +class arcade::graphics::ncurses::GraphicsProvider : public shared::graphics::IGraphicsProvider +{ +public: + GraphicsProvider(); + ~GraphicsProvider() override = default; + + /** + * @brief Get the manifest of the graphics library + * + * @return Manifest of the graphics library + */ + const shared::graphics::GraphicsManifest &getManifest() const noexcept override; + + /** + * @brief Create a renderer object + * + * @param windowProps Properties to use to init the window + * @return Created renderer object + */ + std::unique_ptr createWindow(const IWindow::WindowInitProps &windowProps) override; + + /** + * @brief Create a sound object + * + * @param path Path of the sound file + * @return Created sound object + */ + std::shared_ptr createSound(const std::string &path) override; + + /** + * @brief Create a texture object + * + * @param bin Path of the binary texture file + * @param ascii Path of the ascii texture file + * @return Created texture object + */ + std::shared_ptr createTexture(const std::string &bin, const std::string &ascii) override; + + /** + * @brief Create a font object + * + * @param path Path of the font file + * @return Created font object + */ + std::shared_ptr createFont(const std::string &path) override; + +protected: + static const shared::graphics::GraphicsManifest _manifest; +}; diff --git a/graphics/ncurses/src/font/Font.cpp b/graphics/ncurses/src/font/Font.cpp new file mode 100644 index 0000000..50012e8 --- /dev/null +++ b/graphics/ncurses/src/font/Font.cpp @@ -0,0 +1,13 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Font.cpp +*/ + +#include "Font.hpp" +#include "common/exceptions/FontException.hpp" + +using namespace arcade::graphics::ncurses::font; + +Font::Font(const std::string &path) {} diff --git a/graphics/ncurses/src/font/Font.hpp b/graphics/ncurses/src/font/Font.hpp new file mode 100644 index 0000000..9ac74d6 --- /dev/null +++ b/graphics/ncurses/src/font/Font.hpp @@ -0,0 +1,22 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Font.hpp +*/ + +#pragma once + +#include +#include "shared/graphics/IFont.hpp" +#include "utils/compiler.hpp" + +namespace arcade::graphics::ncurses::font { + class Font; +} + +class arcade::graphics::ncurses::font::Font : public shared::graphics::IFont { +public: + explicit Font(const std::string &path); + ~Font() override = default; +}; diff --git a/graphics/ncurses/src/sound/Sound.cpp b/graphics/ncurses/src/sound/Sound.cpp new file mode 100644 index 0000000..7766418 --- /dev/null +++ b/graphics/ncurses/src/sound/Sound.cpp @@ -0,0 +1,32 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Sound.cpp +*/ + +#include "Sound.hpp" +#include "common/exceptions/SoundException.hpp" + +using namespace arcade::graphics::ncurses::sound; +using namespace arcade::graphics::common::exceptions; + +Sound::Sound(const std::string &path, SoundState state) {} + +Sound::SoundVolume Sound::getVolume() const { + return 100; +} + +void Sound::setVolume(SoundVolume volume) {} + +void Sound::setState(SoundState state) {} + +Sound::SoundState Sound::getState() const { + return SoundState::STOP; +} + +void Sound::setLoopState(bool loop) {} + +bool Sound::getLoopState() const { + return false; +} diff --git a/graphics/ncurses/src/sound/Sound.hpp b/graphics/ncurses/src/sound/Sound.hpp new file mode 100644 index 0000000..bd2228c --- /dev/null +++ b/graphics/ncurses/src/sound/Sound.hpp @@ -0,0 +1,31 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Sound.hpp +*/ + +#pragma once + +#include + +#include "shared/graphics/ISound.hpp" + +namespace arcade::graphics::ncurses::sound { + class Sound; +} + +class arcade::graphics::ncurses::sound::Sound : public shared::graphics::ISound { +public: + explicit Sound(const std::string &path, SoundState state = STOP); + ~Sound() override = default; + + SoundVolume getVolume() const override; + SoundState getState() const override; + void setVolume(SoundVolume volume) override; + void setState(SoundState state) override; + void setLoopState(bool loop) override; + bool getLoopState() const override; + +private: +}; diff --git a/graphics/ncurses/src/texture/Texture.cpp b/graphics/ncurses/src/texture/Texture.cpp new file mode 100644 index 0000000..d291d6a --- /dev/null +++ b/graphics/ncurses/src/texture/Texture.cpp @@ -0,0 +1,45 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Texture.cpp +*/ + +#include +#include "Texture.hpp" +#include "common/exceptions/TextureException.hpp" + +using namespace arcade::graphics::ncurses::texture; +using namespace arcade::graphics::common::exceptions; + +Texture::Texture(const std::string &path) { + this->_loadFromFile(path); +} + +std::map> &Texture::getInnerTexture() +{ + return _texture; +} + +void Texture::_loadFromFile(const std::string &path) +{ + std::ifstream file(path); + std::string line; + int x = 0; + int y = 0; + + if (!file.is_open()) + throw TextureException( + "Failed to open file at: " + path, + "loadFromFile in NCURSES library" + ); + while (std::getline(file, line)) { + for (const auto &c : line) { + _texture[y][x] = c; + x++; + } + x = 0; + y++; + } + file.close(); +} diff --git a/graphics/ncurses/src/texture/Texture.hpp b/graphics/ncurses/src/texture/Texture.hpp new file mode 100644 index 0000000..78ea78c --- /dev/null +++ b/graphics/ncurses/src/texture/Texture.hpp @@ -0,0 +1,37 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Texture.hpp +*/ + +#pragma once + +#include +#include +#include "shared/graphics/ITexture.hpp" + +namespace arcade::graphics::ncurses::texture { + class Texture; +} + +class arcade::graphics::ncurses::texture::Texture: public shared::graphics::ITexture { +public: + explicit Texture(const std::string &path); + ~Texture() override = default; + + /** + * @brief Get the inner NCURSES texture + * @return Reference to the inner NCURSES texture + */ + std::map> &getInnerTexture(); + +private: + std::map> _texture; + + /** + * @brief Load a texture from a file + * @param path Path to the file + */ + void _loadFromFile(const std::string &path); +}; diff --git a/graphics/ncurses/src/window/EventsHandler.cpp b/graphics/ncurses/src/window/EventsHandler.cpp new file mode 100644 index 0000000..7d31f05 --- /dev/null +++ b/graphics/ncurses/src/window/EventsHandler.cpp @@ -0,0 +1,92 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** EventHandler.cpp +*/ + +#include + +#include "Window.hpp" +#include "EventsHandler.hpp" +#include "utils/compiler.hpp" + +#include + +using namespace arcade::graphics::ncurses::window; + +EventsHandler::EventsHandler(Window &window) : _window(window) {} + +std::vector EventsHandler::handleEvents() +{ + std::vector events; + + while (true) { + int event = getch(); + + if (event == ERR) { + break; + } else { + auto eventPtr = _handleKeyPressEvent(event); + if (eventPtr) + events.push_back(eventPtr); + } + MEVENT mouseEvent; + if (getmouse(&mouseEvent) == OK) { + if (mouseEvent.bstate & BUTTON1_CLICKED) { + float delta = 0.1; + auto pos = Vector2f{delta + static_cast(mouseEvent.x), delta + static_cast(mouseEvent.y)}; + events.push_back(std::make_shared(pos, arcade::graphics::common::events::MouseButtonPressEvent::MouseButton::LEFT)); + } + } + } + return events; +} + +EventPtr EventsHandler::_handleKeyPressEvent(int code) +{ + if (code >= 265 && code <= 276) + return _handleFunctionKey(code); + if (code >= 258 && code <= 261) + return _handleArrowKey(code); + if (code == 263) + return std::make_shared(IKeyEvent::KeyType::CHAR, IKeyEvent::KeyCode{.character = '\b'}); + if (code == 330) + return std::make_shared(); + return _handleCharKey(code); +} + +EventPtr EventsHandler::_handleFunctionKey(int code) +{ + unsigned char funcCode = code - 265 + 1; + + return std::make_shared(IKeyEvent::KeyType::FUNC, IKeyEvent::KeyCode{.func = funcCode}); +} + +EventPtr EventsHandler::_handleArrowKey(int code) +{ + IKeyEvent::ArrowCode arrowCode; + + switch (code) { + case 259: + arrowCode = IKeyEvent::ArrowCode::UP; + break; + case 258: + arrowCode = IKeyEvent::ArrowCode::DOWN; + break; + case 260: + arrowCode = IKeyEvent::ArrowCode::LEFT; + break; + case 261: + arrowCode = IKeyEvent::ArrowCode::RIGHT; + break; + default: + return nullptr; + } + return std::make_shared(IKeyEvent::KeyType::ARROW, IKeyEvent::KeyCode{.arrow = arrowCode}); +} + +EventPtr EventsHandler::_handleCharKey(int code) +{ + return std::make_shared(IKeyEvent::KeyType::CHAR, IKeyEvent::KeyCode{.character = static_cast(code)}); +} diff --git a/graphics/ncurses/src/window/EventsHandler.hpp b/graphics/ncurses/src/window/EventsHandler.hpp new file mode 100644 index 0000000..1ab4970 --- /dev/null +++ b/graphics/ncurses/src/window/EventsHandler.hpp @@ -0,0 +1,69 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** EventHandler.hpp +*/ + +#pragma once + +#include + +#include "common/events/window/window.hpp" +#include "common/events/mouse/mouse.hpp" +#include "common/events/key/key.hpp" + +namespace arcade::graphics::ncurses::window { + class EventsHandler; + class Window; +} + +class arcade::graphics::ncurses::window::EventsHandler { +public: + explicit EventsHandler(Window &window); + ~EventsHandler() = default; + + typedef EventPtr (*EventHandler)(int code, Window &window); + + /** + * @brief Handle events from NCURSES + * @param window Window object + * @return Vector of events + */ + std::vector handleEvents(); + +private: + + // static EventHandler _getHandler(sf::Event::EventType type); + + + /** + * @brief Handle key press event + * @param code Code of the key + * @return EventPtr, depending on the key + */ + EventPtr _handleKeyPressEvent(int code); + + /** + * @brief Handle Function key event, F1 to F12 + * @param code Code of the key + * @return EventPtr, F1 to F12 + */ + EventPtr _handleFunctionKey(int code); + + /** + * @brief Handle arrow key event, UP, DOWN, LEFT, RIGHT + * @param code Code of the key + * @return EventPtr, UP, DOWN, LEFT, RIGHT + */ + EventPtr _handleArrowKey(int code); + + /** + * @brief Handle char key event + * @param code Code of the key + * @return EventPtr, depending on the key + */ + EventPtr _handleCharKey(int code); + + window::Window &_window; +}; diff --git a/graphics/ncurses/src/window/Renderer.cpp b/graphics/ncurses/src/window/Renderer.cpp new file mode 100644 index 0000000..20e79a4 --- /dev/null +++ b/graphics/ncurses/src/window/Renderer.cpp @@ -0,0 +1,87 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Renderer.cpp +*/ + +#include "Window.hpp" +#include "Renderer.hpp" +#include "font/Font.hpp" +#include "texture/Texture.hpp" +#include "common/exceptions/WindowException.hpp" + +using namespace arcade::graphics::ncurses::window; +using namespace arcade::graphics::common::exceptions; + +Renderer::Renderer(Window &window) : _window(window) +{ +} + +void Renderer::render(const shared::graphics::TextProps &props) +{ + int index = 0; + + int x = _textAlign(props); + int y = _textVerticalAlign(props); + Vector2i position = {x, y}; + for (const auto &letter : props.content) { + _window.map[position.y][position.x + index] = letter; + index += 1; + } +} + +int Renderer::_textVerticalAlign(const shared::graphics::TextProps &props) +{ + switch (props.verticalAlign) { + case shared::graphics::TextVerticalAlign::TOP: + return props.position.y; + case shared::graphics::TextVerticalAlign::MIDDLE: + return props.position.y + (props.size.y / 2); + case shared::graphics::TextVerticalAlign::BOTTOM: + return props.position.y + props.size.y; + } + return props.position.y; +} + +int Renderer::_textAlign(const shared::graphics::TextProps &props) +{ + switch (props.align) { + case shared::graphics::TextAlign::LEFT: + return props.position.x; + case shared::graphics::TextAlign::CENTER: + return props.position.x + (props.size.x / 2) - (props.content.size() / 2); + case shared::graphics::TextAlign::RIGHT: + return props.position.x + props.size.x - props.content.size(); + } + return props.position.x; +} + +void Renderer::render(const shared::graphics::TextureProps &props) +{ + auto texture = _castOrThrow(props.texture); + auto map = texture->getInnerTexture(); + + int x = props.size.x; + int y = props.size.y; + + for (int j = 0; j < y ; j++) { + for (int i = 0; i < x; i++) { + auto securedChar = _getRightChar(props, Vector2i(i, j)); + _window.map[props.position.y + j][props.position.x + i] = securedChar; + } + } +} + +char Renderer::_getRightChar(const shared::graphics::TextureProps &props, const Vector2i &tilePosition) +{ + auto texture = _castOrThrow(props.texture); + auto map = texture->getInnerTexture(); + + auto newPos = Vector2i(props.origin.x + tilePosition.x, props.origin.y + tilePosition.y); + if (newPos.y < map.size() && newPos.x < map[newPos.y].size()) { + return map[newPos.y][newPos.x]; + } else { + return ' '; + } +} diff --git a/graphics/ncurses/src/window/Renderer.hpp b/graphics/ncurses/src/window/Renderer.hpp new file mode 100644 index 0000000..6cee926 --- /dev/null +++ b/graphics/ncurses/src/window/Renderer.hpp @@ -0,0 +1,83 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Renderer.hpp +*/ + +#pragma once + +#include +#include "shared/graphics/ITexture.hpp" +#include "shared/graphics/types/TextureProps.hpp" +#include "shared/graphics/types/TextProps.hpp" +#include "common/exceptions/WindowException.hpp" +#include "texture/Texture.hpp" + +namespace arcade::graphics::ncurses::window { + class Renderer; + + class Window; +} + +class arcade::graphics::ncurses::window::Renderer { +public: + explicit Renderer(Window &window); + + ~Renderer() = default; + + /** + * @brief Render a texture on the window + * @param props Texture properties + */ + void render(const shared::graphics::TextureProps &props); + + /** + * @brief Render a text on the window + * @param props Text properties + */ + void render(const shared::graphics::TextProps &props); + +private: + Window &_window; + + /** + * @brief Align vertically the text + * @param props Text properties + */ + int _textVerticalAlign(const shared::graphics::TextProps &props); + + /** + * @brief Align the text + * @param props Text properties + */ + int _textAlign(const shared::graphics::TextProps &props); + + /** + * @brief Get the right character in the texture + * It manage origin of the texture, of course its size + * @param props Texture properties + * @param tilePosition Position of the tile + * @return Right character + */ + char _getRightChar(const shared::graphics::TextureProps &props, const Vector2i &tilePosition); + + /** + * @brief Cast a shared pointer from a type to another + * @tparam From Type from which to cast + * @tparam To Type to which cast + * @param from Value to cast + * @return Casted value + */ + template + static std::shared_ptr _castOrThrow(std::shared_ptr from) { + std::shared_ptr to = std::dynamic_pointer_cast(from); + if (!to) { + throw common::exceptions::WindowException( + "Failed to cast shared pointer of:" + std::string(typeid(from).name()) + " to " + typeid(to).name(), + "NCURSES Library Renderer::_castOrThrow" + ); + } + return to; + }; +}; diff --git a/graphics/ncurses/src/window/Window.cpp b/graphics/ncurses/src/window/Window.cpp new file mode 100644 index 0000000..2126418 --- /dev/null +++ b/graphics/ncurses/src/window/Window.cpp @@ -0,0 +1,117 @@ +/* +** EPITECH PROJECT, 2024 +** Window.cpp +** File description: +** Window class +*/ + +#include "Window.hpp" +#include "EventsHandler.hpp" +#include "common/events/mouse/mouse.hpp" +#include "common/exceptions/WindowException.hpp" + +using namespace arcade::graphics::ncurses::window; +using namespace arcade::graphics::common::exceptions; + +const Vector2u Window::tileSize = { 35, 35 }; + +Window::Window(const IWindow::WindowInitProps &props): + _size(props.size), + _initialSize(0, 0), + _renderer(*this), + _eventsHandler(*this), + _window(nullptr, &delwin) +{ + _mode = props.mode; + _fps = props.fps; + _initialSize = _size; + _isOpen = true; + initscr(); + cbreak(); + noecho(); + keypad(stdscr, TRUE); + nodelay(stdscr, TRUE); + mousemask(ALL_MOUSE_EVENTS, NULL); + curs_set(0); + _window = std::unique_ptr(newwin(_size.y, _size.x, 0, 0), &delwin); +} + +Window::~Window() +{ + wclear(stdscr); + close(); + endwin(); +} + +std::unique_ptr &Window::getWindow() +{ + return _window; +} + +void Window::setTitle(const std::string &title) { + _title = title; +} + +void Window::setSize(shared::types::Vector2u size) { + _size = size; +} + +shared::types::Vector2u Window::getSize() const { + return _size; +} + +void Window::setFramerateLimit(unsigned int fps) { + _fps = fps; +} + +unsigned int Window::getFramerateLimit() const { + return _fps; +} + +void Window::setMode(IWindow::WindowMode mode) {} + +Window::WindowMode Window::getMode() const { + return _mode; +} + +bool Window::isOpen() const { + return _isOpen; +} + +void Window::setIcon(const std::string &path) {} + +void Window::render(const shared::graphics::TextureProps &props) { + _renderer.render(props); +} + +void Window::render(const shared::graphics::TextProps &props) { + _renderer.render(props); +} + +void Window::clear() { + wclear(_window.get()); +} + +void Window::display() { + for (auto &line : map) { + for (auto &c : line.second) { + mvwprintw(_window.get(), line.first, c.first, &c.second); + } + } + wrefresh(_window.get()); +} + +void Window::close() { + if (_window) { + wclear(_window.get()); + wrefresh(_window.get()); + } + _isOpen = false; + _window.reset(); +} + +std::vector Window::getEvents() { + return _eventsHandler.handleEvents(); +} + +void Window::onResize() {} diff --git a/graphics/ncurses/src/window/Window.hpp b/graphics/ncurses/src/window/Window.hpp new file mode 100644 index 0000000..f5b9635 --- /dev/null +++ b/graphics/ncurses/src/window/Window.hpp @@ -0,0 +1,160 @@ +/* +** EPITECH PROJECT, 2024 +** Window.hpp +** File description: +** Window class +*/ + +#pragma once + +#include +#include +#include "Renderer.hpp" +#include "shared/graphics/IWindow.hpp" +#include "EventsHandler.hpp" + +namespace arcade::graphics::ncurses::window { + class Window; +} + +class arcade::graphics::ncurses::window::Window: public shared::graphics::IWindow { +public: + explicit Window(const WindowInitProps &props); + ~Window() override; + + /** + * @brief Get window object + * + */ + std::unique_ptr &getWindow(); + + /** + * @brief Set the title of current window + * + * @param title Title of the window + */ + void setTitle(const std::string &title) override; + + /** + * @brief Set the size of the window + * + * @param size Size of the window + */ + void setSize(Vector2u size) override; + + /** + * @brief Get the size of the window + * + * @return Size of the window + */ + Vector2u getSize() const override; + + /** + * @brief Set the framerate Limit of the window + * + * @param fps Frame per seconds + */ + void setFramerateLimit(unsigned int fps) override; + + /** + * @brief Get the framerate Limit of the window + * + * @return Frame per seconds + */ + unsigned int getFramerateLimit() const override; + + /** + * @brief Set the mode of the window + * + * @param mode Mode to apply to the window + */ + void setMode(IWindow::WindowMode mode) override; + + /** + * @brief Get the mode of the window + * + * @return Mode of the window + */ + WindowMode getMode() const override; + + /** + * @brief Set the icon of the window + * + * @param icon Icon to use + */ + void setIcon(const std::string &icon) override; + + /** + * @brief Render the text with given properties + * + * @param props Properties of the entity to render + */ + void render(const shared::graphics::TextProps &props) override; + + /** + * @brief Render the entity with given properties + * + * @param props Properties of the entity to render + */ + void render(const shared::graphics::TextureProps &props) override; + + /** + * @brief Clear the content of the window + * + */ + void clear() override; + + /** + * @brief Display the content of the window + * + */ + void display() override; + + /** + * @brief Close the window + * + */ + void close() override; + + /** + * @brief Check if the window is open + * + * @return Open status of the window + */ + bool isOpen() const override; + + /** + * @brief Get the events object + * + * @return Last events occurred + * @warning Call successively this method will result in losing events + * @note Call `A` return `eventsA` containing 2 events, + * but make another call `B` (directly after call `A`) `eventsB` + * will result to an empty vector + */ + std::vector getEvents() override; + + /** + * @brief Get the size of a tile + * @return Size of a tile + */ + static const Vector2u tileSize; + + /** + * @brief Resize the view of the window + */ + void onResize(); + + std::map> map; + +private: + std::unique_ptr _window; + EventsHandler _eventsHandler; + Renderer _renderer; + std::string _title; + unsigned int _fps; + WindowMode _mode; + Vector2u _size; + Vector2u _initialSize; + bool _isOpen; +}; diff --git a/output b/output new file mode 100755 index 0000000..4c7da4e Binary files /dev/null and b/output differ