diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 90d3b70..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -project(Arcade LANGUAGES CXX) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - -add_compile_options(-Wall -Wextra -Werror -g) - -include_directories(include) - -file(GLOB_RECURSE SOURCES "src/*.cpp") - -add_executable(arcade ${SOURCES}) diff --git a/Makefile b/Makefile index 8e1b5d2..83f9110 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,8 @@ CC = clang++ SRC_DIR = src/ -SRC_FILES = main.cpp \ +SRC_FILES = Core.cpp \ + main.cpp SRC = $(addprefix $(SRC_DIR), $(SRC_FILES)) diff --git a/include/Common.hpp b/include/Common.hpp new file mode 100644 index 0000000..93295c9 --- /dev/null +++ b/include/Common.hpp @@ -0,0 +1,94 @@ +/* +** EPITECH PROJECT, 2026 +** Common +** File description: +** Common +*/ + +#ifndef COMMON + #define COMMON + #include + #include + #include + +namespace Arcade { + enum class PluginType { + Game, + Graphics + }; + + enum class InputAction { + None, + Quit, + NextGraphics, + PrevGraphics, + NextGame, + PrevGame, + Restart, + Menu, + Select, + Backspace, + Up, + Down, + Left, + Right, + Action + }; + + struct KeyEvent { + InputAction action {InputAction::None}; + char text {'\0'}; + }; + + enum class TileType { + Empty, + Wall, + Player, + Enemy, + Food, + Bonus, + Text + }; + + struct Vec2i { + int x {0}; + int y {0}; + }; + + enum class CellType { + Empty, + Wall, + Player, + Enemy, + Food, + Text + }; + + struct Cell { + Vec2i pos; + CellType type; + std::string text; + }; + + struct Drawable { + TileType type {TileType::Empty}; + Vec2i pos {}; + std::string text {}; + }; + + struct GameState { + std::string name {"Unknown game"}; + std::vector drawables {}; + int score {0}; + bool finished {false}; + }; + + struct MenuState { + std::vector graphics {}; + std::vector games {}; + std::string playerName {"player"}; + std::size_t selectedGraphics {0}; + std::size_t selectedGame {0}; + }; +} +#endif diff --git a/include/Core.hpp b/include/Core.hpp index 55c0a82..2d0b930 100644 --- a/include/Core.hpp +++ b/include/Core.hpp @@ -11,4 +11,27 @@ #define HELP 2026 #define ERROR 84 #define FAIL 1 + #include "IGraphic.hpp" + #include "PluginApi.hpp" + +namespace Arcade { +class Core { +public: + explicit Core(const std::string &initalGraphicPath); + ~Core(); + void run(); + +private: + void loadGraphics(const std::string& path); + void unloadGraphics(); + +private: + std::string _graphicalPath; + void* _graphicHandle; + IGraphics* _graphics; + DestroyFn _destroyGraphics; + +}; +} + #endif /* CORE */ diff --git a/include/IGame.hpp b/include/IGame.hpp new file mode 100644 index 0000000..2d2b4c8 --- /dev/null +++ b/include/IGame.hpp @@ -0,0 +1,25 @@ +/* +** EPITECH PROJECT, 2026 +** IGame +** File description: +** IGame +*/ + +#ifndef IGAME + #define IGAME + #include + #include "Common.hpp" + +namespace Arcade { +class IGame { +public: + virtual ~IGame() = default; + virtual void reset() = 0; + virtual void update() = 0; + virtual void onInput(InputAction action) = 0; + virtual std::vector getDisplay() const = 0; + virtual int getScore() const = 0; + virtual std::string getName() const = 0; +}; +} +#endif diff --git a/include/IGraphic.hpp b/include/IGraphic.hpp new file mode 100644 index 0000000..3355e77 --- /dev/null +++ b/include/IGraphic.hpp @@ -0,0 +1,26 @@ +/* +** EPITECH PROJECT, 2026 +** IGame +** File description: +** IGame +*/ + +#ifndef IGRAPHICS + #define IGRAPHICS + #include + #include "Common.hpp" + +namespace Arcade { +class IGraphics { +public: + virtual ~IGraphics() = default; + virtual void init() = 0; + virtual void shutdown() = 0; + virtual void clear() = 0; + virtual void draw(const std::vector& cells) = 0; + virtual void display() = 0; + virtual InputAction pollEvent() = 0; + virtual std::string getName() const = 0; +}; +} +#endif diff --git a/include/PluginApi.hpp b/include/PluginApi.hpp new file mode 100644 index 0000000..cde2f54 --- /dev/null +++ b/include/PluginApi.hpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2026 +** PluginApi +** File description: +** PluginApi +*/ + +#ifndef PLUGINAPI + #define PLUGINAPI + #include "Common.hpp" + +namespace Arcade { + using CreateFn = void* (*)(); + using DestroyFn = void (*)(void*); + using GetTypeFn = PluginType (*)(); + using GetNameFn = const char* (*)(); +} + +#endif diff --git a/src/Core.cpp b/src/Core.cpp new file mode 100644 index 0000000..157d4d0 --- /dev/null +++ b/src/Core.cpp @@ -0,0 +1,86 @@ +/* +** EPITECH PROJECT, 2026 +** core +** File description: +** core +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "Core.hpp" +#include "Errors.hpp" + +namespace Arcade { + Core::Core(const std::string& graphicalPath) + : _graphicalPath(graphicalPath), + _graphicHandle(nullptr), + _graphics(nullptr), + _destroyGraphics(nullptr) + {} + + Core::~Core(){ + unloadGraphics(); + } + + void Core::loadGraphics(const std::string& path){ + // open graphic lib + _graphicHandle = dlopen(path.c_str(), RTLD_LAZY); + if (!_graphicHandle) + throw ARCError(dlerror()); + + // load getType function of the lib + auto getType = reinterpret_cast(dlsym(_graphicHandle, "getType")); + const char *error = dlerror(); + if (error) + throw ARCError(error); + + // load the create function of the lib + auto create = reinterpret_cast(dlsym(_graphicHandle, "create")); + error = dlerror(); + if (error) + throw ARCError(error); + + //load the destroy fun of the lib + _destroyGraphics = reinterpret_cast(dlsym(_graphicHandle, "destroy")); + error = dlerror(); + if (error) + throw ARCError(error); + + // Error Handling for wrong lib + if (getType() != PluginType::Graphics) + throw ARCError("'" + path + "' is not a graphical library"); + + // create _graphics object for core use + _graphics = static_cast(create()); + if (!_graphics) + throw ARCError("failed to create graphics instance"); + } + + void Core::unloadGraphics() + { + if (_graphics && _destroyGraphics) { + _destroyGraphics(_graphics); + _graphics = nullptr; + } + _destroyGraphics = nullptr; + if (_graphicHandle) { + dlclose(_graphicHandle); + _graphicHandle = nullptr; + } + } + + void Core::run() { + loadGraphics(_graphicalPath); + _graphics->init(); + + //temporary + std::cout << "Graphics library loaded successfully\n"; + + _graphics->shutdown(); + } +} diff --git a/src/main.cpp b/src/main.cpp index a1e2202..00f769e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,8 +5,11 @@ ** arcade */ -#include #include "Core.hpp" +#include "Errors.hpp" +#include +#include +#include static unsigned int handle_args(int argc, const char *argv[]) { if (argc != 2 || !argv || !argv[1]) { @@ -33,6 +36,13 @@ int main(int argc, const char *argv[]) { case ERROR: return ERROR; default: - return SUCCESS; - } + try { + Arcade::Core core(argv[1]); + core.run(); + return EXIT_SUCCESS; + } catch (const ARCError &error) { + std::cerr << "Error" << error.what() << '\n'; + return EXIT_FAILURE; + } + } }