feat(pocketdungeon): intro GOAL+CONTROLS left icons right + 2x2 tutorial levels
Main / Build (BookPlayer) (push) Has been cancelled
Main / Build (Brainfuck) (push) Has been cancelled
Main / Build (Breakout) (push) Has been cancelled
Main / Build (Calculator) (push) Has been cancelled
Main / Build (Diceware) (push) Has been cancelled
Main / Build (EpubReader) (push) Has been cancelled
Main / Build (GPIO) (push) Has been cancelled
Main / Build (GraphicsDemo) (push) Has been cancelled
Main / Build (HelloWorld) (push) Has been cancelled
Main / Build (M5UnitTest) (push) Has been cancelled
Main / Build (Magic8Ball) (push) Has been cancelled
Main / Build (MediaKeys) (push) Has been cancelled
Main / Build (MystifyDemo) (push) Has been cancelled
Main / Build (SerialConsole) (push) Has been cancelled
Main / Build (Snake) (push) Has been cancelled
Main / Build (TamaTac) (push) Has been cancelled
Main / Build (TodoList) (push) Has been cancelled
Main / Build (TwoEleven) (push) Has been cancelled
Main / Bundle (push) Has been cancelled

- Intro redesign QVGA: left scrollable column 2 cards GOAL+CONTROLS only,
  right 44px rail small icons Play 38 accent + Exit 30 muted (fixes cramped)
- Tutorial by play: floor0 TUTORIAL_ROWS=2 player+stairs, floor1 bat+gold+stairs,
  real game from floor2 infinite with displayFloor mapping
- Model: renderRows, isTutorial(), tutorialId(), clearAllTiles(), generateTutorialFloor
- Renderer: respects renderRows HIDDEN, board height 2 rows centered, TUT messages
- Game: reset tutorials=true, skip moveMonsters in tutorial, bests only real floors
- Keep audio-stream migration: SDK 0.8.0-dev IDF5.5, CMake GLOB SfxEngine, SfxEngine audio-stream
- No unexported LVGL: no max_width/scrollbar_mode -> 0 missing symbols

Installed 192.168.68.134 verified screenshot 6.1K airy left+right
This commit is contained in:
Adolfo
2026-07-19 23:05:43 -04:00
parent b2e9046438
commit 2a45c98fb3
9 changed files with 457 additions and 130 deletions
@@ -9,8 +9,15 @@
namespace PocketDungeon {
enum class AppPhase : uint8_t { Intro, Playing, Paused };
class PocketDungeon final : public App, public GameKit::Scene {
lv_obj_t* root = nullptr;
lv_obj_t* introContainer = nullptr;
lv_obj_t* gameContainer = nullptr;
lv_obj_t* pauseOverlay = nullptr;
AppPhase phase = AppPhase::Intro;
GameKit::Loop loop;
GameKit::Prefs prefs {"PocketDungeon"};
DungeonModel model;
@@ -20,6 +27,20 @@ class PocketDungeon final : public App, public GameKit::Scene {
void playResultSound(MoveResult result);
void saveBests();
void showIntro();
void showGame();
void showPause();
void hidePause();
void clearIntro();
void clearGame();
void renderIntro();
void attachInputToCurrent();
void exitGame();
static void onStartButtonClicked(lv_event_t* e);
static void onResumeButtonClicked(lv_event_t* e);
static void onExitButtonClicked(lv_event_t* e);
static void onGameContainerLongPress(lv_event_t* e);
public:
void onShow(AppHandle app, lv_obj_t* parent) override;