Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
cce97e9
[ADD] DLLoader
YetAnotherMechanicusEnjoyer Mar 30, 2026
e43fcd3
[ADD] new CMake
YetAnotherMechanicusEnjoyer Mar 30, 2026
e2cf98a
[FIX] Core
YetAnotherMechanicusEnjoyer Mar 30, 2026
059e054
[FIX] Lib stuff
YetAnotherMechanicusEnjoyer Mar 30, 2026
4a6a803
[FIX] typo in CMakeLists.txt
YetAnotherMechanicusEnjoyer Apr 5, 2026
8fdea34
[ADD] DirectoryScanner class
YetAnotherMechanicusEnjoyer Apr 5, 2026
313dd67
[UPDATE] InputAction enum & Cell struct
YetAnotherMechanicusEnjoyer Apr 5, 2026
fcb06e3
[ADD] DLLoader::hasSymbol()
YetAnotherMechanicusEnjoyer Apr 5, 2026
219e965
[UPDATE] Core class & run behaviour
YetAnotherMechanicusEnjoyer Apr 5, 2026
baea88d
[FIX] CMake macro name formatting
YetAnotherMechanicusEnjoyer Apr 5, 2026
5dbb66a
[ADD] NcursesModule.cpp as an exemple
YetAnotherMechanicusEnjoyer Apr 5, 2026
10b53f8
[FIX] Typo in NcursesModule.cpp
YetAnotherMechanicusEnjoyer Apr 5, 2026
c329f8e
[ADD] SnakeModule.cpp as an exemple
YetAnotherMechanicusEnjoyer Apr 5, 2026
3703820
[UPDATE] CMake to remove libs from binary compilation
YetAnotherMechanicusEnjoyer Apr 5, 2026
26b9800
[ADD] lib/ to .gitignore
YetAnotherMechanicusEnjoyer Apr 5, 2026
93ceffb
[REMOVE] InputAction::Exit (didn't know about Quit)
YetAnotherMechanicusEnjoyer Apr 5, 2026
a7b1312
[FIX] DLLoader::hasSymbol crashing with dlerror()
YetAnotherMechanicusEnjoyer Apr 5, 2026
39ffab2
[ADD] Error handling to DirectoryScanner
YetAnotherMechanicusEnjoyer Apr 5, 2026
a528882
[FIX] Snake & Ncurses Modules
YetAnotherMechanicusEnjoyer Apr 5, 2026
e0d6558
[FIX] Exit codes
YetAnotherMechanicusEnjoyer Apr 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
nanotekspice
arcade
.old
compile_commands.json
*.o
.obj/
.cache
*.nts
build/
lib/
48 changes: 48 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
cmake_minimum_required(VERSION 3.16)
project(Arcade VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

add_compile_options(-Wall -Wextra -Werror)

include_directories(${CMAKE_SOURCE_DIR}/include)

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")

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 ${SOURCES})

target_link_libraries(arcade PRIVATE ${CMAKE_DL_LIBS})

macro(add_arcade_library target_name src_files)
add_library(${target_name} SHARED ${src_files})
set_target_properties(${target_name} PROPERTIES PREFIX "")
endmacro()

add_arcade_library(arcade_ncurses "src/graphicals/Ncurses/NcursesModule.cpp")
target_link_libraries(arcade_ncurses ncurses)

#add_arcade_library(arcade_sdl2 "src/graphicals/Ncurses/Sdl2/Sdl2Module.cpp")
#target_link_libraries(arcade_sdl2 SDL2)

#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")
7 changes: 4 additions & 3 deletions include/Common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ namespace Arcade {
};

struct Cell {
Vec2i pos;
CellType type;
std::string text;
float x;
float y;
char character;
int color;
};

struct Drawable {
Expand Down
48 changes: 35 additions & 13 deletions include/Core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,48 @@
#define HELP 2026
#define ERROR 84
#define FAIL 1
#include "IGame.hpp"
#include "IGraphic.hpp"
#include "PluginApi.hpp"
#include "DLLoader.hpp"

namespace Arcade {
class Core {
public:
explicit Core(const std::string &initalGraphicPath);
~Core();
void run();

private:
void loadGraphics(const std::string& path);
void unloadGraphics();
enum class State {
Menu,
Playing,
};
State _state;

private:
std::string _graphicalPath;
void* _graphicHandle;
IGraphics* _graphics;
DestroyFn _destroyGraphics;
std::vector<std::string> _graphicalLibs;
std::vector<std::string> _gameLibs;

size_t _currentGraphIdx;
size_t _currentGameIdx;
size_t _menuSelectionIdx;

std::unique_ptr<DLLoader<IGraphics>> _graphLoader;
std::unique_ptr<IGraphics> _graph;

std::unique_ptr<DLLoader<IGame>> _gameLoader;
std::unique_ptr<IGame> _game;

std::string _playerName;
bool _isRunning;

void loadGraphics(size_t index);
void loadGame(size_t index);
void handleGlobalInput(InputAction action);

void runMenu();
void runGame();

std::vector<Cell> stringToCells(const std::string& str, float startX, float startY);

public:
explicit Core(const std::string &initalGraphicLib);
~Core();
void run();
};
}

Expand Down
62 changes: 62 additions & 0 deletions include/DLLoader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once

#include <string>
#include <memory>
#include <dlfcn.h>
#include "Errors.hpp"

namespace Arcade {

template <typename T>
class DLLoader {
private:
void *_handle;

public:
explicit DLLoader(const std::string& filepath) : _handle(nullptr) {
_handle = dlopen(filepath.c_str(), RTLD_LAZY);
if (!_handle)
throw ARCError(dlerror());
}

~DLLoader() {
if (_handle)
dlclose(_handle);
}

DLLoader(const DLLoader&) = delete;
DLLoader& operator=(const DLLoader&) = delete;

DLLoader(DLLoader&& other) noexcept : _handle(other._handle) {
other._handle = nullptr;
}

DLLoader& operator=(DLLoader&& other) noexcept {
if (this != &other) {
if (_handle)
dlclose(_handle);
_handle = other._handle = nullptr;
}
return *this;
}

bool hasSymbol(const std::string& symbolName) const {
return dlsym(_handle, symbolName.c_str()) != nullptr;
}

std::unique_ptr<T> getInstance(const std::string& entryPointName = "entryPoint") {
dlerror();

void* sym = dlsym(_handle, entryPointName.c_str());

const char *dlsym_error = dlerror();
if (dlsym_error)
throw ARCError(std::string("dlsym error : ") + dlsym_error);

using EntryPointFunc = T* (*)();
EntryPointFunc createFunc = reinterpret_cast<EntryPointFunc>(sym);

return std::unique_ptr<T>(createFunc());
}
};
}
40 changes: 40 additions & 0 deletions include/DirectoryScanner.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include <iostream>
#include <vector>
#include <string>
#include <filesystem>
#include "Errors.hpp"
#include "DLLoader.hpp"

namespace Arcade {
class DirectoryScanner {
public:
static void scan(const std::string& path, std::vector<std::string>& gameLibs, std::vector<std::string>& graphicLibs) {
gameLibs.clear();
graphicLibs.clear();

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 filepath = entry.path().string();
try {
DLLoader<void> 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;
}
}
}
}
};
}
6 changes: 4 additions & 2 deletions include/Errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
#include <exception>
#include <string>

class ARCError: public std::exception {
namespace Arcade {
class ARCError : public std::exception {
public:
ARCError(std::string const &message) : _message(message) {}
const char *what() const noexcept override { return _message.c_str(); }

private:
std::string _message;
std::string _message;
};
}

#endif /* ERRORS */
1 change: 0 additions & 1 deletion include/IGame.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#ifndef IGAME
#define IGAME
#include <iostream>
#include "Common.hpp"

namespace Arcade {
Expand Down
1 change: 0 additions & 1 deletion include/IGraphic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#ifndef IGRAPHICS
#define IGRAPHICS
#include <iostream>
#include "Common.hpp"

namespace Arcade {
Expand Down
Loading
Loading