From fbbb97c12e6b1658b4b2fa28343b784c5f94e216 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Date: Fri, 10 Apr 2026 14:10:24 +0200 Subject: [PATCH 1/3] [ADD] menu were we can switch libs --- CMakeLists.txt | 47 ++++++---- include/DLLoader.hpp | 40 +++++++-- include/DirectoryScanner.hpp | 42 +++++---- include/MenuSelector.hpp | 35 ++++++++ src/MenuSelector.cpp | 161 +++++++++++++++++++++++++++++++++++ src/main.cpp | 89 ++++++++++++------- 6 files changed, 339 insertions(+), 75 deletions(-) create mode 100644 include/MenuSelector.hpp create mode 100644 src/MenuSelector.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d63e50..9de4d3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,38 +5,49 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -add_compile_options(-g -Wall -Wextra -Werror) +add_compile_options(-Wall -Wextra -Werror) include_directories(${CMAKE_SOURCE_DIR}/include) +# Ajoute les chemins Homebrew pour Apple Silicon +include_directories(/opt/homebrew/include) +link_directories(/opt/homebrew/lib) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib) -file(GLOB_RECURSE ALL_SOURCES "src/*.cpp") -set(CORE_SOURCES "") +set(GAME_DIR "src/games/") +set(GRAPHICALS_DIR "src/graphicals/") + +file(GLOB_RECURSE SOURCES "src/*.cpp") -foreach(FILE ${ALL_SOURCES}) - if(NOT FILE MATCHES "/games/" AND NOT FILE MATCHES "/graphicals/") - list(APPEND CORE_SOURCES ${FILE}) +foreach(TMP_PATH ${SOURCES}) + string(FIND ${TMP_PATH} ${GAME_DIR} GAME_DIR_FOUND) + string(FIND ${TMP_PATH} ${GRAPHICALS_DIR} GRAPHICALS_DIR_FOUND) + + if(NOT ${GAME_DIR_FOUND} EQUAL -1 OR NOT ${GRAPHICALS_DIR_FOUND} EQUAL -1) + list(REMOVE_ITEM SOURCES ${TMP_PATH}) endif() endforeach() -add_executable(arcade ${CORE_SOURCES}) +add_executable(arcade ${SOURCES}) + target_link_libraries(arcade PRIVATE ${CMAKE_DL_LIBS}) -macro(add_arcade_library target_name) - add_library(${target_name} SHARED ${ARGN}) +macro(add_arcade_library target_name src_files) + add_library(${target_name} SHARED ${src_files}) set_target_properties(${target_name} PROPERTIES PREFIX "") endmacro() +# Ncurses add_arcade_library(arcade_ncurses "src/graphicals/Ncurses/NcursesModule.cpp") -target_link_libraries(arcade_ncurses PRIVATE ncurses) - -add_arcade_library(arcade_sdl2 "src/graphicals/Sdl2/Sdl2Module.cpp") -target_link_libraries(arcade_sdl2 PRIVATE SDL2 SDL2_ttf) - -#add_arcade_library(arcade_sfml "src/graphicals/Sfml/SfmlModule.cpp") -#target_link_libraries(arcade_sfml sfml-graphics sfml-window sfml-system) - +target_link_libraries(arcade_ncurses ncurses) +# SDL2 - Version corrigée avec SDL2_ttf +add_arcade_library(arcade_sdl2 "src/graphicals/SDL2/SDL2Module.cpp") +target_include_directories(arcade_sdl2 PRIVATE /opt/homebrew/include/SDL2) +target_link_libraries(arcade_sdl2 PRIVATE + /opt/homebrew/lib/libSDL2.dylib + /opt/homebrew/lib/libSDL2_ttf.dylib +) +# Games add_arcade_library(arcade_snake "src/games/Snake/SnakeModule.cpp") -#add_arcade_library(arcade_pacman "src/games/Pacman/PacmanModule.cpp") diff --git a/include/DLLoader.hpp b/include/DLLoader.hpp index cd6b247..1dbd43d 100644 --- a/include/DLLoader.hpp +++ b/include/DLLoader.hpp @@ -15,13 +15,16 @@ class DLLoader { public: explicit DLLoader(const std::string& filepath) : _handle(nullptr) { _handle = dlopen(filepath.c_str(), RTLD_LAZY); - if (!_handle) - throw ARCError(dlerror()); + if (!_handle) { + const char* error = dlerror(); + throw ARCError(std::string("dlopen error: ") + (error ? error : "unknown error")); + } } ~DLLoader() { - if (_handle) + if (_handle) { dlclose(_handle); + } } DLLoader(const DLLoader&) = delete; @@ -35,30 +38,49 @@ class DLLoader { if (this != &other) { if (_handle) dlclose(_handle); - _handle = other._handle = nullptr; + _handle = other._handle; + other._handle = nullptr; } return *this; } bool hasSymbol(const std::string& symbolName) const { - return dlsym(_handle, symbolName.c_str()) != nullptr; + void* sym = dlsym(_handle, symbolName.c_str()); + if (sym) return true; + + std::string macOSName = "_" + symbolName; + sym = dlsym(_handle, macOSName.c_str()); + return sym != nullptr; } std::unique_ptr getInstance(const std::string& entryPointName = "entryPoint") { dlerror(); void* sym = dlsym(_handle, entryPointName.c_str()); + + if (!sym) { + std::string macOSName = "_" + entryPointName; + sym = dlsym(_handle, macOSName.c_str()); + } const char *dlsym_error = dlerror(); - if (dlsym_error) - throw ARCError(std::string("dlsym error : ") + dlsym_error); + if (dlsym_error) { + throw ARCError(std::string("dlsym error: ") + dlsym_error); + } + + if (!sym) { + throw ARCError(std::string("cannot find symbol: ") + entryPointName); + } using EntryPointFunc = T* (*)(); EntryPointFunc createFunc = reinterpret_cast(sym); - if (!createFunc) - throw ARCError(std::string("cannot find entryPointName: ") + entryPointName); + if (!createFunc) { + throw ARCError(std::string("invalid function pointer for: ") + entryPointName); + } + return std::unique_ptr(createFunc()); } }; + } diff --git a/include/DirectoryScanner.hpp b/include/DirectoryScanner.hpp index da5284b..6339c83 100644 --- a/include/DirectoryScanner.hpp +++ b/include/DirectoryScanner.hpp @@ -4,34 +4,46 @@ #include #include #include +#include #include "Errors.hpp" -#include "DLLoader.hpp" namespace Arcade { class DirectoryScanner { public: + static bool hasSymbol(const std::string& libPath, const std::string& symbolName) { + void* handle = dlopen(libPath.c_str(), RTLD_LAZY); + if (!handle) { + return false; + } + + void* sym = dlsym(handle, symbolName.c_str()); + if (!sym) { + std::string macOSName = "_" + symbolName; + sym = dlsym(handle, macOSName.c_str()); + } + + dlclose(handle); + return sym != nullptr; + } + static void scan(const std::string& path, std::vector& gameLibs, std::vector& graphicLibs) { gameLibs.clear(); graphicLibs.clear(); - if (!std::filesystem::exists(path) || !std::filesystem::is_directory(path)) + if (!std::filesystem::exists(path) || !std::filesystem::is_directory(path)) { return; + } for (const auto& entry : std::filesystem::directory_iterator(path)) { - if (entry.path().extension() == ".so") { + std::string extension = entry.path().extension().string(); + + if (extension == ".so" || extension == ".dylib") { std::string filepath = entry.path().string(); - try { - DLLoader inspector(filepath); - - if (inspector.hasSymbol("createGame")) { - gameLibs.push_back(filepath); - } else if (inspector.hasSymbol("createGraphics")) { - graphicLibs.push_back(filepath); - } else { - throw ARCError("Invalid symbol"); - } - } catch (const ARCError& e) { - std::cerr << "Error loading " << filepath << ": " << e.what() << std::endl; + + if (hasSymbol(filepath, "createGraphics")) { + graphicLibs.push_back(filepath); + } else if (hasSymbol(filepath, "createGame")) { + gameLibs.push_back(filepath); } } } diff --git a/include/MenuSelector.hpp b/include/MenuSelector.hpp new file mode 100644 index 0000000..df63b78 --- /dev/null +++ b/include/MenuSelector.hpp @@ -0,0 +1,35 @@ +#ifndef MENUSELECTOR_HPP +#define MENUSELECTOR_HPP + +#include +#include +#include +#include + +namespace Arcade { + +class MenuSelector { +public: + struct MenuOption { + std::string name; + std::string path; + std::function action; + }; + + MenuSelector(); + ~MenuSelector(); + + std::string run(const std::vector& availableLibs); + +private: + void displayMenu(const std::vector& options, int selectedIdx); + void clearScreen(); + int getchNonBlock(); + + bool _running; + int _selectedIdx; +}; + +} // namespace Arcade + +#endif diff --git a/src/MenuSelector.cpp b/src/MenuSelector.cpp new file mode 100644 index 0000000..8fa2564 --- /dev/null +++ b/src/MenuSelector.cpp @@ -0,0 +1,161 @@ +#include "MenuSelector.hpp" +#include +#include +#include +#include +#include +#include + +namespace Arcade { + +MenuSelector::MenuSelector() : _running(true), _selectedIdx(0) { + struct termios term; + tcgetattr(STDIN_FILENO, &term); + term.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &term); +} + +MenuSelector::~MenuSelector() { + struct termios term; + tcgetattr(STDIN_FILENO, &term); + term.c_lflag |= (ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &term); +} + +void MenuSelector::clearScreen() { + printf("\033[2J\033[H"); +} + +int MenuSelector::getchNonBlock() { + int flags = fcntl(STDIN_FILENO, F_GETFL, 0); + fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); + int ch = getchar(); + fcntl(STDIN_FILENO, F_SETFL, flags); + return ch; +} + +void MenuSelector::displayMenu(const std::vector& options, int selectedIdx) { + clearScreen(); + + printf("\n"); + printf(" ╔══════════════════════════════════════╗\n"); + printf(" ║ ARCADE - MENU PRINCIPAL ║\n"); + printf(" ╠══════════════════════════════════════╣\n"); + printf(" ║ ║\n"); + printf(" ║ Choisissez une librairie graphique: ║\n"); + printf(" ║ ║\n"); + + for (size_t i = 0; i < options.size(); ++i) { + if (static_cast(i) == selectedIdx) { + printf(" ║ \033[7m"); + } else { + printf(" ║ "); + } + + std::string displayName = options[i].name; + size_t lastSlash = displayName.find_last_of('/'); + if (lastSlash != std::string::npos) { + displayName = displayName.substr(lastSlash + 1); + } + size_t dotPos = displayName.find(".so"); + if (dotPos != std::string::npos) { + displayName = displayName.substr(0, dotPos); + } + dotPos = displayName.find(".dylib"); + if (dotPos != std::string::npos) { + displayName = displayName.substr(0, dotPos); + } + + printf(" ► %-31s", displayName.c_str()); + + if (static_cast(i) == selectedIdx) { + printf("\033[0m"); + } + printf(" ║\n"); + } + + printf(" ║ ║\n"); + + if (selectedIdx == static_cast(options.size())) { + printf(" ║ \033[7m ► Quitter\033[0m ║\n"); + } else { + printf(" ║ ► Quitter ║\n"); + } + + printf(" ║ ║\n"); + printf(" ╚══════════════════════════════════════╝\n"); + printf("\n"); + printf(" Utilisez les flèches ↑/↓ pour naviguer\n"); + printf(" Appuyez sur Entrée pour sélectionner\n"); + printf(" Appuyez sur 'q' pour quitter\n"); + + fflush(stdout); +} + +std::string MenuSelector::run(const std::vector& availableLibs) { + std::vector options; + + for (const auto& lib : availableLibs) { + MenuOption opt; + opt.name = lib; + opt.path = lib; + options.push_back(opt); + } + + _selectedIdx = 0; + _running = true; + + displayMenu(options, _selectedIdx); + + while (_running) { + int ch = getchNonBlock(); + + if (ch == EOF) { + usleep(10000); + continue; + } + + switch (ch) { + case 27: + ch = getchNonBlock(); + if (ch == 91) { + ch = getchNonBlock(); + switch (ch) { + case 65: + _selectedIdx--; + if (_selectedIdx < 0) + _selectedIdx = options.size(); + displayMenu(options, _selectedIdx); + break; + case 66: + _selectedIdx++; + if (_selectedIdx > static_cast(options.size())) + _selectedIdx = 0; + displayMenu(options, _selectedIdx); + break; + } + } + break; + + case '\n': + case '\r': + if (_selectedIdx == static_cast(options.size())) { + return ""; + } else if (_selectedIdx >= 0 && _selectedIdx < static_cast(options.size())) { + return options[_selectedIdx].path; + } + break; + + case 'q': + case 'Q': + return ""; + break; + } + + usleep(10000); + } + + return ""; +} + +} diff --git a/src/main.cpp b/src/main.cpp index dce260e..b95226b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,50 +1,73 @@ -/* -** EPITECH PROJECT, 2026 -** arcade -** File description: -** arcade -*/ - #include "Core.hpp" #include "Errors.hpp" +#include "MenuSelector.hpp" +#include "DirectoryScanner.hpp" #include +#define SUCCESS 0 +#define HELP 2026 +#define ERROR 84 + static unsigned int handle_args(int argc, const char *argv[]) { - if (argc != 2 || !argv || !argv[1]) { - std::cerr << - "Usage:\n\tarcade [options] \nOptions:\n\t-h, --help Show this help" << - std::endl; + if (argc > 2) { + std::cerr << "Usage:\n\t./arcade\n\t./arcade [graphical_library.so]\n\t./arcade -h, --help" << std::endl; return ERROR; } - std::string flag(argv[1]); - if (flag == "--help" || flag == "-h") { - std::cout << - "Usage:\n\tarcade [options] \nOptions:\n\t-h, --help Show this help" << - std::endl; - return HELP; + if (argc == 2) { + std::string flag(argv[1]); + if (flag == "--help" || flag == "-h") { + std::cout << "Usage:\n\t./arcade [graphical_library.so]\n\n" + "If no library is specified, a menu will let you choose.\n\n" + "Options:\n\t-h, --help Show this help" << std::endl; + return HELP; + } } return SUCCESS; } int main(int argc, const char *argv[]) { - switch (handle_args(argc, argv)) { - case HELP: - return SUCCESS; - case ERROR: - return ERROR; - default: - try { - Arcade::Core core(argv[1]); - - core.run(); - return SUCCESS; - } catch (const Arcade::ARCError &error) { - std::cerr << "Error: " << error.what() << std::endl; - return ERROR; - } catch (...) { - std::cerr << "Uncaught Error." << std::endl; + int result = handle_args(argc, argv); + + if (result == HELP) return SUCCESS; + if (result == ERROR) return ERROR; + + try { + std::string selectedLib; + + if (argc == 1) { + std::vector gameLibs; + std::vector graphicalLibs; + Arcade::DirectoryScanner::scan("./lib/", gameLibs, graphicalLibs); + + if (graphicalLibs.empty()) { + std::cerr << "Error: No graphical library found in ./lib/" << std::endl; return ERROR; } + + Arcade::MenuSelector menu; + selectedLib = menu.run(graphicalLibs); + + if (selectedLib.empty()) { + std::cout << "Goodbye!" << std::endl; + return SUCCESS; + } + } else { + selectedLib = argv[1]; } + + Arcade::Core core(selectedLib); + core.run(); + return SUCCESS; + + } catch (const Arcade::ARCError &error) { + std::cerr << "Error: " << error.what() << std::endl; + return ERROR; + } catch (const std::exception &e) { + std::cerr << "Error: " << e.what() << std::endl; + return ERROR; + } catch (...) { + std::cerr << "Uncaught Error." << std::endl; + return ERROR; + } } From 276e2d5939875dc3a56222673a0015dc892a9584 Mon Sep 17 00:00:00 2001 From: YetAnotherMechanicusEnjoyer Date: Sat, 11 Apr 2026 08:14:07 +0200 Subject: [PATCH 2/3] [FIX] Useless modifications, Menu printing & Removed C functions --- include/DLLoader.hpp | 19 ++++----- include/DirectoryScanner.hpp | 41 +++++++----------- src/Core.cpp | 2 +- src/MenuSelector.cpp | 81 ++++++++++++++++++------------------ src/main.cpp | 76 ++++++++++++++++----------------- 5 files changed, 100 insertions(+), 119 deletions(-) diff --git a/include/DLLoader.hpp b/include/DLLoader.hpp index 1dbd43d..c033b6e 100644 --- a/include/DLLoader.hpp +++ b/include/DLLoader.hpp @@ -22,9 +22,8 @@ class DLLoader { } ~DLLoader() { - if (_handle) { + if (_handle) dlclose(_handle); - } } DLLoader(const DLLoader&) = delete; @@ -38,8 +37,7 @@ class DLLoader { if (this != &other) { if (_handle) dlclose(_handle); - _handle = other._handle; - other._handle = nullptr; + _handle = other._handle = other._handle = nullptr; } return *this; } @@ -47,7 +45,7 @@ class DLLoader { bool hasSymbol(const std::string& symbolName) const { void* sym = dlsym(_handle, symbolName.c_str()); if (sym) return true; - + std::string macOSName = "_" + symbolName; sym = dlsym(_handle, macOSName.c_str()); return sym != nullptr; @@ -57,27 +55,24 @@ class DLLoader { dlerror(); void* sym = dlsym(_handle, entryPointName.c_str()); - + if (!sym) { std::string macOSName = "_" + entryPointName; sym = dlsym(_handle, macOSName.c_str()); } const char *dlsym_error = dlerror(); - if (dlsym_error) { + if (dlsym_error) throw ARCError(std::string("dlsym error: ") + dlsym_error); - } - if (!sym) { + if (!sym) throw ARCError(std::string("cannot find symbol: ") + entryPointName); - } using EntryPointFunc = T* (*)(); EntryPointFunc createFunc = reinterpret_cast(sym); - if (!createFunc) { + if (!createFunc) throw ARCError(std::string("invalid function pointer for: ") + entryPointName); - } return std::unique_ptr(createFunc()); } diff --git a/include/DirectoryScanner.hpp b/include/DirectoryScanner.hpp index 6339c83..f02f9e7 100644 --- a/include/DirectoryScanner.hpp +++ b/include/DirectoryScanner.hpp @@ -4,46 +4,37 @@ #include #include #include -#include +#include "DLLoader.hpp" #include "Errors.hpp" namespace Arcade { class DirectoryScanner { public: - static bool hasSymbol(const std::string& libPath, const std::string& symbolName) { - void* handle = dlopen(libPath.c_str(), RTLD_LAZY); - if (!handle) { - return false; - } - - void* sym = dlsym(handle, symbolName.c_str()); - if (!sym) { - std::string macOSName = "_" + symbolName; - sym = dlsym(handle, macOSName.c_str()); - } - - dlclose(handle); - return sym != nullptr; - } - static void scan(const std::string& path, std::vector& gameLibs, std::vector& graphicLibs) { gameLibs.clear(); graphicLibs.clear(); - if (!std::filesystem::exists(path) || !std::filesystem::is_directory(path)) { + if (!std::filesystem::exists(path) || !std::filesystem::is_directory(path)) return; - } for (const auto& entry : std::filesystem::directory_iterator(path)) { std::string extension = entry.path().extension().string(); - + if (extension == ".so" || extension == ".dylib") { std::string filepath = entry.path().string(); - - if (hasSymbol(filepath, "createGraphics")) { - graphicLibs.push_back(filepath); - } else if (hasSymbol(filepath, "createGame")) { - gameLibs.push_back(filepath); + + try { + DLLoader inspector(filepath); + + if (inspector.hasSymbol("createGame")) { + gameLibs.push_back(filepath); + } else if (inspector.hasSymbol("createGraphics")) { + graphicLibs.push_back(filepath); + } else { + throw ARCError("Invalid symbol."); + } + } catch (const ARCError& e) { + std::cerr << "Error loading " << filepath << ": " << e.what() << std::endl; } } } diff --git a/src/Core.cpp b/src/Core.cpp index 46e0247..bcaf641 100644 --- a/src/Core.cpp +++ b/src/Core.cpp @@ -160,4 +160,4 @@ void Core::run() { } } -} +} diff --git a/src/MenuSelector.cpp b/src/MenuSelector.cpp index 8fa2564..07440ee 100644 --- a/src/MenuSelector.cpp +++ b/src/MenuSelector.cpp @@ -4,7 +4,6 @@ #include #include #include -#include namespace Arcade { @@ -23,7 +22,7 @@ MenuSelector::~MenuSelector() { } void MenuSelector::clearScreen() { - printf("\033[2J\033[H"); + std::cout << "\033[2J\033[H"; } int MenuSelector::getchNonBlock() { @@ -36,22 +35,22 @@ int MenuSelector::getchNonBlock() { void MenuSelector::displayMenu(const std::vector& options, int selectedIdx) { clearScreen(); - - printf("\n"); - printf(" ╔══════════════════════════════════════╗\n"); - printf(" ║ ARCADE - MENU PRINCIPAL ║\n"); - printf(" ╠══════════════════════════════════════╣\n"); - printf(" ║ ║\n"); - printf(" ║ Choisissez une librairie graphique: ║\n"); - printf(" ║ ║\n"); - + + std::cout << "\n"; + std::cout << " ╔══════════════════════════════════════╗\n"; + std::cout << " ║ ARCADE - MENU PRINCIPAL ║\n"; + std::cout << " ╠══════════════════════════════════════╣\n"; + std::cout << " ║ ║\n"; + std::cout << " ║ Choisissez une librairie graphique: ║\n"; + std::cout << " ║ ║\n"; + for (size_t i = 0; i < options.size(); ++i) { if (static_cast(i) == selectedIdx) { - printf(" ║ \033[7m"); + std::cout << " ║ \033[7m"; } else { - printf(" ║ "); + std::cout << " ║ "; } - + std::string displayName = options[i].name; size_t lastSlash = displayName.find_last_of('/'); if (lastSlash != std::string::npos) { @@ -65,56 +64,56 @@ void MenuSelector::displayMenu(const std::vector& options, int selec if (dotPos != std::string::npos) { displayName = displayName.substr(0, dotPos); } - + printf(" ► %-31s", displayName.c_str()); - + if (static_cast(i) == selectedIdx) { - printf("\033[0m"); + std::cout << "\033[0m"; } - printf(" ║\n"); + std::cout << "║\n"; } - - printf(" ║ ║\n"); - + + std::cout << " ║ ║\n"; + if (selectedIdx == static_cast(options.size())) { - printf(" ║ \033[7m ► Quitter\033[0m ║\n"); + std::cout << " ║ \033[7m ► Quitter\033[0m ║\n"; } else { - printf(" ║ ► Quitter ║\n"); + std::cout << " ║ ► Quitter ║\n"; } - - printf(" ║ ║\n"); - printf(" ╚══════════════════════════════════════╝\n"); - printf("\n"); - printf(" Utilisez les flèches ↑/↓ pour naviguer\n"); - printf(" Appuyez sur Entrée pour sélectionner\n"); - printf(" Appuyez sur 'q' pour quitter\n"); - + + std::cout << " ║ ║\n"; + std::cout << " ╚══════════════════════════════════════╝\n"; + std::cout << "\n"; + std::cout << " Utilisez les flèches ↑/↓ pour naviguer\n"; + std::cout << " Appuyez sur Entrée pour sélectionner\n"; + std::cout << " Appuyez sur 'q' pour quitter\n"; + fflush(stdout); } std::string MenuSelector::run(const std::vector& availableLibs) { std::vector options; - + for (const auto& lib : availableLibs) { MenuOption opt; opt.name = lib; opt.path = lib; options.push_back(opt); } - + _selectedIdx = 0; _running = true; - + displayMenu(options, _selectedIdx); - + while (_running) { int ch = getchNonBlock(); - + if (ch == EOF) { usleep(10000); continue; } - + switch (ch) { case 27: ch = getchNonBlock(); @@ -136,7 +135,7 @@ std::string MenuSelector::run(const std::vector& availableLibs) { } } break; - + case '\n': case '\r': if (_selectedIdx == static_cast(options.size())) { @@ -145,16 +144,16 @@ std::string MenuSelector::run(const std::vector& availableLibs) { return options[_selectedIdx].path; } break; - + case 'q': case 'Q': return ""; break; } - + usleep(10000); } - + return ""; } diff --git a/src/main.cpp b/src/main.cpp index b95226b..f98cabb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,47 +27,43 @@ static unsigned int handle_args(int argc, const char *argv[]) { } int main(int argc, const char *argv[]) { - int result = handle_args(argc, argv); - - if (result == HELP) return SUCCESS; - if (result == ERROR) return ERROR; - - try { - std::string selectedLib; - - if (argc == 1) { - std::vector gameLibs; - std::vector graphicalLibs; - Arcade::DirectoryScanner::scan("./lib/", gameLibs, graphicalLibs); - - if (graphicalLibs.empty()) { - std::cerr << "Error: No graphical library found in ./lib/" << std::endl; - return ERROR; - } - - Arcade::MenuSelector menu; - selectedLib = menu.run(graphicalLibs); - - if (selectedLib.empty()) { - std::cout << "Goodbye!" << std::endl; + switch (handle_args(argc, argv)) { + case HELP: + return SUCCESS; + case ERROR: + return ERROR; + default: + try { + std::string selectedLib; + + if (argc == 1) { + std::vector gameLibs; + std::vector graphicalLibs; + Arcade::DirectoryScanner::scan("./lib/", gameLibs, graphicalLibs); + + if (graphicalLibs.empty()) { + throw Arcade::ARCError("No graphical library found in ./lib/"); + } + + Arcade::MenuSelector menu; + selectedLib = menu.run(graphicalLibs); + + if (selectedLib.empty()) { return SUCCESS; } + } else { selectedLib = argv[1]; } + + Arcade::Core core(selectedLib); + + core.run(); return SUCCESS; + } catch (const Arcade::ARCError &error) { + std::cerr << "Error: " << error.what() << std::endl; + return ERROR; + } catch (const std::exception& e) { + std::cerr << "Uncaught Error: " << e.what() << std::endl; + return ERROR; + } catch (...) { + std::cerr << "Uncaught Error." << std::endl; + return ERROR; } - } else { - selectedLib = argv[1]; - } - - Arcade::Core core(selectedLib); - core.run(); - return SUCCESS; - - } catch (const Arcade::ARCError &error) { - std::cerr << "Error: " << error.what() << std::endl; - return ERROR; - } catch (const std::exception &e) { - std::cerr << "Error: " << e.what() << std::endl; - return ERROR; - } catch (...) { - std::cerr << "Uncaught Error." << std::endl; - return ERROR; } } From db29a26e6738d7659c6daed98d5e03d7d4e97f28 Mon Sep 17 00:00:00 2001 From: YetAnotherMechanicusEnjoyer Date: Sat, 11 Apr 2026 08:26:10 +0200 Subject: [PATCH 3/3] [FIX] CMake (again) --- CMakeLists.txt | 47 +++++++++++++++++--------------------------- src/MenuSelector.cpp | 2 +- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9de4d3a..0d63e50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,49 +5,38 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -add_compile_options(-Wall -Wextra -Werror) +add_compile_options(-g -Wall -Wextra -Werror) include_directories(${CMAKE_SOURCE_DIR}/include) -# Ajoute les chemins Homebrew pour Apple Silicon -include_directories(/opt/homebrew/include) -link_directories(/opt/homebrew/lib) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib) -set(GAME_DIR "src/games/") -set(GRAPHICALS_DIR "src/graphicals/") - -file(GLOB_RECURSE SOURCES "src/*.cpp") +file(GLOB_RECURSE ALL_SOURCES "src/*.cpp") +set(CORE_SOURCES "") -foreach(TMP_PATH ${SOURCES}) - string(FIND ${TMP_PATH} ${GAME_DIR} GAME_DIR_FOUND) - string(FIND ${TMP_PATH} ${GRAPHICALS_DIR} GRAPHICALS_DIR_FOUND) - - if(NOT ${GAME_DIR_FOUND} EQUAL -1 OR NOT ${GRAPHICALS_DIR_FOUND} EQUAL -1) - list(REMOVE_ITEM SOURCES ${TMP_PATH}) +foreach(FILE ${ALL_SOURCES}) + if(NOT FILE MATCHES "/games/" AND NOT FILE MATCHES "/graphicals/") + list(APPEND CORE_SOURCES ${FILE}) endif() endforeach() -add_executable(arcade ${SOURCES}) - +add_executable(arcade ${CORE_SOURCES}) target_link_libraries(arcade PRIVATE ${CMAKE_DL_LIBS}) -macro(add_arcade_library target_name src_files) - add_library(${target_name} SHARED ${src_files}) +macro(add_arcade_library target_name) + add_library(${target_name} SHARED ${ARGN}) set_target_properties(${target_name} PROPERTIES PREFIX "") endmacro() -# Ncurses add_arcade_library(arcade_ncurses "src/graphicals/Ncurses/NcursesModule.cpp") -target_link_libraries(arcade_ncurses ncurses) -# SDL2 - Version corrigée avec SDL2_ttf -add_arcade_library(arcade_sdl2 "src/graphicals/SDL2/SDL2Module.cpp") -target_include_directories(arcade_sdl2 PRIVATE /opt/homebrew/include/SDL2) -target_link_libraries(arcade_sdl2 PRIVATE - /opt/homebrew/lib/libSDL2.dylib - /opt/homebrew/lib/libSDL2_ttf.dylib -) -# Games +target_link_libraries(arcade_ncurses PRIVATE ncurses) + +add_arcade_library(arcade_sdl2 "src/graphicals/Sdl2/Sdl2Module.cpp") +target_link_libraries(arcade_sdl2 PRIVATE SDL2 SDL2_ttf) + +#add_arcade_library(arcade_sfml "src/graphicals/Sfml/SfmlModule.cpp") +#target_link_libraries(arcade_sfml sfml-graphics sfml-window sfml-system) + add_arcade_library(arcade_snake "src/games/Snake/SnakeModule.cpp") +#add_arcade_library(arcade_pacman "src/games/Pacman/PacmanModule.cpp") diff --git a/src/MenuSelector.cpp b/src/MenuSelector.cpp index 07440ee..5cf284a 100644 --- a/src/MenuSelector.cpp +++ b/src/MenuSelector.cpp @@ -76,7 +76,7 @@ void MenuSelector::displayMenu(const std::vector& options, int selec std::cout << " ║ ║\n"; if (selectedIdx == static_cast(options.size())) { - std::cout << " ║ \033[7m ► Quitter\033[0m ║\n"; + std::cout << " ║ \033[7m ► Quitter\033[0m ║\n"; } else { std::cout << " ║ ► Quitter ║\n"; }