|
|
||
|---|---|---|
| assets/packs | ||
| assets-cg | ||
| assets-pc/sfx | ||
| build-cg-prof | ||
| DOCS | ||
| pc | ||
| src | ||
| tests | ||
| tools | ||
| .clang-format | ||
| .gitignore | ||
| build-casio | ||
| build-casio-debug | ||
| build-pc | ||
| CHANGELOG.md | ||
| clean.sh | ||
| CMakeLists.txt | ||
| README.md | ||
| run-tests | ||
Npp Rewrite
Réécriture sur base saine du clone N++ pour CASIO fx-CG50 et PC, calquée sur la cible canonique NppFlash (AS3 Metanet). Objectif : rejouer les 600 niveaux NppFlash (120 épisodes × 5) avec une physique fidèle et déterministe, sur deux cibles partageant le même cœur de simulation portable.
Pierre angulaire. La simulation tourne en pas fixe 40 Hz, découplé du rendu (NppFlash
sim_rate = 40). C'est le correctif de l'erreur racine de la v1.0, qui simulait en pas variable → physique dépendante du framerate. Tout le reste (collision, entités, ragdoll) découle de ce choix.
En bref
- Cœur portable pur (
src/sim/) : aucune dépendance gint / SDL / Azur, arithmétique virgule fixeQ16.16, testable et identique sur les deux cibles. - Physique fidèle : portage ligne à ligne de
Ninja.as/Simulator.as(collision cercle r vs segments/arcs, 4 sous-itérations/tick, 22 types d'entités, raycast Q16.16, ragdoll Verlet déterministe). - 600 niveaux importés depuis NppFlash via
tools/build_pack.py(assets/packs/ep00…ep119.npl). - UI pixel-perfect reprise de la version Npp v1.0 : titre, options, browser de packs, écrans Trophées & Stats (49 trophées), éditeur de nom, dialogues in-game.
- Rendu : SDL2 sur PC ; Azur Render Pipeline + gint sur Casio.
- Popup trophée temps-réel : un trophée débloqué en cours de partie s'affiche en carte descriptive glissée en haut à droite.
- Audio : samples NppFlash extraits + sons procéduraux (PC).
- Formats figés : un seul format par artefact, zéro rétrocompat, parseurs bornés hostile-safe (jamais de crash sur entrée corrompue).
État courant
Branche dev (post-tag v2.0-stable). Toutes les phases roadmap P0–P7 sont
closes ; depuis, migration complète vers l'Azur Render Pipeline (Casio),
ajout de l'audio (PC) et du popup trophée temps-réel.
| Cible | Statut |
|---|---|
| PC (tests doctest) | 127 cas verts sous -Werror |
| PC (appli SDL2) | pc/build/npp_play jouable |
| Casio fx-CG50 | Npp.g3a — ROM ≈ 629 KiB (30,7 %), RAM ≈ 34 KiB / 491 KiB (+3 MiB extram via AddMoreRAM) |
Gates : G1 (déterminisme golden) ✅ · G2 (EntitySystem hors god-object) ✅
· G3 (600 niveaux chargés, 0 type ignoré) ✅ · G4 (release : -Werror 2 cibles
✅ ; perf on-device = à mesurer sur matériel réel).
Structure
src/
config/ constantes paramétrables — 1 header par entité (cf. config/README.md)
sim/ CŒUR PORTABLE PUR (aucune dép. gint/SDL/Azur) — testable direct
fixed · vec2 · sim_clock · ninja · simulator · world · seg/edge grid
entities/ (22 types) · loader · npp_format · pack_format · rng · ragdoll
render/ model/view UI pixel-perfect v1.0 (PORTABLE, via Renderer abstrait)
title · options · browser · trophies · trophy_popup · sim_view · sprites · fx
render_cg/ back-end gint/Azur (fx-CG50)
screens/ handlers légers d'écran (menu/options/name-edit/trophies) + play_events
platform/ I/O sûre : fs.h (world-switch Casio) · clock (overclock) · extram
main_casio.cpp point d'entrée gint (frontend complet)
pc/sdl/ port SDL2 : npp_play (appli jouable) + sdl_renderer + keyboard + sound
tests/ doctest (vendor/) — golden, sim, formats, fuzz, entités, UI, trophées…
tools/ build_pack.py (Levels.bin → packs .npl) + outils d'assets
assets/packs/ 600 niveaux (ep00…ep119.npl) + sauvegardes per-pack (.nps)
DOCS/ analyse, roadmap, audits, docs de design figés
Le cœur src/sim/ ne dépend de rien : il se compile et se teste sur PC sans
couche de compatibilité, et tourne tel quel sur Casio. Les vues render/
sont elles aussi portables (elles dessinent via une interface Renderer
abstraite) ; seuls render_cg/ et pc/sdl/ connaissent la cible.
Build & test
./run-tests # compile + lance la suite doctest (pc/build/npp_tests)
./build-pc # build PC (tests + appli SDL2 si SDL2 présent)
./build-casio # Npp.g3a (fxSDK) ; ./build-casio -B = rebuild complet
./clean.sh # purge les builds
- Stack Casio : Azur, gint, fxSDK, cZlib. Stack PC : SDL2 (+ SDL2_image, optionnel pour les sprites), zlib système.
- Qualité : C++23,
-Wall -Wextra -Wpedantic -Werrorsur les deux cibles, jamais-fpermissive. G1 (golden) doit rester vert à chaque commit.
Jouer
L'appli PC charge automatiquement les packs depuis assets/packs/ et ouvre
le menu titre — pas d'argument :
pc/build/npp_play
Contrôles PC (en jeu) : ←/→ se déplacer · Shift ou ↑ sauter ·
N niveau suivant · R rejouer · O pause/options · K (2 s) suicide ·
Échap quitter le run · Entrée valider les dialogues.
Menus : ↑/↓/←/→ naviguer · Entrée valider · Échap retour ·
Shift+←/→ changer d'onglet (Trophées/Stats, catégories browser) ·
F5 rescanner les packs depuis le disque.
Sur Casio, les touches équivalentes gint sont câblées dans main_casio.cpp
(flèches, SHIFT/UP saut, F1–F5, MENU pause, EXE/EXIT).
Formats de fichiers
Tous les formats sont mono-version, zéro rétrocompat (décision figée) et lus par des parseurs bornés qui refusent proprement magic/bornes/troncature.
| Format | Magic / version | Rôle |
|---|---|---|
.npp / .nzp |
NPPL / NZPL |
un niveau (clair / zlib), pack_id = CRC32 |
.npl |
NPLP v1 |
pack de niveaux (concatène des blobs .npp/.nzp) |
.nps |
NPPS v6 |
sauvegarde par pack (epNN.nps) : complété, top-5 temps, perfect/all-gold, deaths |
| settings | NPCO v4 |
options joueur (NppClone.cfg) : thème, couleurs, nom, overclock, FPS/Perf |
| stats | NPST v2 |
compteurs Tier 1/Tier 2 (NppClone.stats) — alimentent les 49 trophées |
Les sauvegardes .nps sont per-pack (write borné < ~600 octets quel que
soit le nombre de packs installés) ; le pack_id est revalidé au chargement
contre l'index NppClone.idx (mismatch ⇒ slice resetée + drapeau d'erreur).
Décisions figées
- D-STEP : pas fixe 40 Hz, rendu découplé (accumulateur + interpolation).
- D-COLL : collision NppFlash fidèle (cercle vs segGrid/edgeGrid/objGrid).
- D-PAR : déterminisme prouvé par golden-test (auto-cohérence Q16.16, pas bit-exact vs double).
- D-ARCH :
EntitySystemdès le départ (pas de god-objectLevel). - D-FMT : un seul format par artefact, zéro rétrocompat.
- D-MENU : UI = design v1.0, mais model/view séparés.
Documentation
CHANGELOG.md— journal détaillé par phase/commit.DOCS/ANALYSE_REWRITE_2026-05-17.md— erreurs v1.0, cible, décisions, risques.DOCS/ROADMAP/— phases P0–P7 et gates.DOCS/— audits de fidélité + docs de design figés (raycast, ragdoll, portes, interpolation, sprites, tile-remap, UI v1.0).