pet.h (2219B)
1 #pragma once 2 #include <stdint.h> 3 4 // The badge companion. A "pet" is a name + a face per state (short ASCII faces, 5 // e.g. "(^_^)"). The active one is chosen on the PET view (double-tap to swap); 6 // 3 ship built-in, with a 4th "custom" slot uploadable via the provisioning page 7 // (see docs/provisioning.md). 8 // 9 // ─── NAMING: the user-facing word is "AVATAR"; the code says "pet" ─────────── 10 // Every string a recipient reads — the OLED's "Avatar:" row, the setup app, the 11 // FAQ at badge.virtualshack.io — says *avatar*. Identifiers here (pet.h, PET_*, 12 // g_pet_idx, OptView::pet, PET_UUID) deliberately still say *pet*. That split is 13 // intentional, not leftover: renaming the identifiers buys a recipient nothing, 14 // and one class of them CANNOT be renamed safely at all — 15 // 16 // the NVS keys "pet", "petcust", "petc_ok" (main.cpp). 17 // 18 // Those are persisted on every badge already in the field. Changing a key does 19 // not migrate the value, it orphans it: every custom avatar uploaded before the 20 // change silently reverts to the built-in default, and the owner's selected slot 21 // resets. If you rename anything here, leave the NVS keys and the BLE UUID alone. 22 23 enum PetState { 24 PET_IDLE = 0, // resting 25 PET_CONTACT, // a new crew badge just came into range 26 PET_MILESTONE, // crossed a points milestone 27 PET_LONELY, // no crew in range 28 PET_LOWBATT, // battery low 29 PET_STATE_COUNT 30 }; 31 32 #define PET_NAME_MAX 12 33 #define PET_FACE_MAX 16 34 #define PET_BUILTIN_N 3 35 36 struct Pet { 37 char name[PET_NAME_MAX]; 38 char face[PET_STATE_COUNT][PET_FACE_MAX]; // indexed by PetState 39 }; 40 41 // Built-in pets. Face order matches PetState: idle, contact, milestone, lonely, lowbatt. 42 static const Pet PET_BUILTINS[PET_BUILTIN_N] = { 43 { "ghost", { "(^_^)", "(o_o)!", "(^o^)", "(-_-)z", "(>_<)" } }, 44 { "bot", { "[o_o]", "[O_O]!", "[^o^]", "[-_-]", "[x_x]" } }, 45 { "cat", { "(=^.^=)", "(=o.o=)", "(=^o^=)", "(=-.-=)", "(=T.T=)" } }, 46 }; 47 48 // Active pet by index (clamped). Custom slot (index PET_BUILTIN_N) lands in Phase 3. 49 static inline const Pet* pet_get(int idx) { 50 if (idx < 0 || idx >= PET_BUILTIN_N) idx = 0; 51 return &PET_BUILTINS[idx]; 52 }