Aller au contenu

Couche d'abstraction de portabilité (PAL)

Ce document décrit les composants de la couche de portabilité qui permettent au projet de fonctionner sur Linux, macOS et Windows.

Vue d'ensemble

La PAL (Portability Abstraction Layer) est organisée en trois modules dans src/platform/ :

Module Fichier Responsabilité
platform_utils platform_utils.c/.h Détection de plateforme, macros
platform_time platform_time.c/.h Mesure du temps haute résolution
platform_fs platform_fs.c/.h Opérations sur le système de fichiers

Composant : platform_utils

Détection de plateforme

#if defined(_WIN32)
    #define PLATFORM_WINDOWS 1
#elif defined(__APPLE__)
    #define PLATFORM_MACOS 1
#elif defined(__linux__)
    #define PLATFORM_LINUX 1
#endif

Macros utilitaires

// Attributs portables
#define MAYBE_UNUSED __attribute__((unused))
#define INLINE       static inline __attribute__((always_inline))

// Séparateur de chemin
#ifdef PLATFORM_WINDOWS
    #define PATH_SEP '\\'
#else
    #define PATH_SEP '/'
#endif

Composant : platform_time

Fournit un chronomètre haute résolution indépendant de la plateforme :

typedef struct { uint64_t value; } PlatformTime;

PlatformTime platform_time_now(void);
double platform_time_elapsed_ms(PlatformTime start, PlatformTime end);
double platform_time_elapsed_s(PlatformTime start, PlatformTime end);

Implémentation : - Linux : clock_gettime(CLOCK_MONOTONIC) - macOS : mach_absolute_time() - Windows : QueryPerformanceCounter()

Composant : platform_fs

Listage de répertoires basé sur le callback

L'API de listage de répertoires utilise une architecture callback pour éviter l'allocation dynamique et permettre un traitement streaming :

typedef void (*fs_dir_entry_callback)(const char* path, void* user_data);

int platform_fs_list_dir(const char* dir,
                         fs_dir_entry_callback callback,
                         void* user_data);

Usage :

// Lister tous les fichiers .hdr dans le dossier assets
void on_hdr_found(const char* path, void* ctx) {
    if (str_ends_with(path, ".hdr")) {
        add_environment(ctx, path);
    }
}

platform_fs_list_dir("assets/environments", on_hdr_found, &env_list);

Opérations courantes

// Vérifier l'existence d'un fichier
bool platform_fs_exists(const char* path);

// Obtenir la taille d'un fichier
int64_t platform_fs_size(const char* path);

// Lire un fichier entier en mémoire
uint8_t* platform_fs_read_all(const char* path, size_t* out_size);

Support Windows (cross-compilation)

La compilation Windows s'effectue via la toolchain MinGW :

# Configurer pour Windows
just configure-win

# Compiler
just build-win

# Exécuter via Wine
just run-win

La toolchain est définie dans toolchain-mingw.cmake :

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)

L'exécution des tests sous Wine est gérée par le script wrapper run_test_with_xvfb.sh, qui détecte automatiquement les binaires .exe et les préfixe avec wine64. Chaque test standalone dans tests/CMakeLists.txt utilise ce wrapper en build WIN32 :

if(WIN32)
    add_test(NAME test_foo
             COMMAND ${CMAKE_SOURCE_DIR}/.github/workflows/scripts/run_test_with_xvfb.sh $<TARGET_FILE:test_foo>)
else()
    add_test(NAME test_foo COMMAND test_foo)
endif()

Limitations connues

Manette/Joystick non détecté sous Wine

L'API gamepad de GLFW (glfwJoystickIsGamepad) repose sur la pile native de la plateforme. Sous Wine, cela correspond aux API Windows WinMM/XInput, qui nécessitent que Wine détecte le périphérique joystick Linux.

  • Cause : Le passthrough joystick de Wine dépend de la présence de libSDL2 dans le préfixe Wine et des permissions udev correctes sur /dev/input/js* et /dev/input/event*.
  • Symptômes : La manette fonctionne parfaitement avec le build Linux natif (just run) mais n'est pas reconnue sous Wine (just run-win). L'overlay F2 masque correctement la page manette puisque gamepad.connected == 0.
  • Statut : C'est une limitation connue de Wine, pas un bug applicatif. Le support manette sous Wine est best-effort. Pour une fonctionnalité manette complète, utiliser le build Linux natif.

Voir aussi