Skip to content

Commit ca252e8

Browse files
authored
feat(baseui): tier the emote set by flash class (#11257)
1 parent 4bb474a commit ca252e8

4 files changed

Lines changed: 122 additions & 7 deletions

File tree

src/graphics/emotes.cpp

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ namespace graphics
77

88
// Always define Emote list and count
99
const Emote emotes[] = {
10-
#ifndef EXCLUDE_EMOJI
10+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_CORE
1111
// --- Thumbs ---
1212
{"\U0001F44D", thumbup, thumbs_width, thumbs_height}, // 👍 Thumbs Up
1313
{"\U0001F44E", thumbdown, thumbs_width, thumbs_height}, // 👎 Thumbs Down
14+
#endif // EMOTE_SET_CORE
1415

16+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_STANDARD
1517
// --- Smileys (Multiple Unicode Aliases) ---
1618
{"\U0001F60A", smiling_eyes, smiling_eyes_width, smiling_eyes_height}, // 😊 Smiling Eyes
1719
{"\U0001F600", grinning, grinning_width, grinning_height}, // 😀 Grinning Face
@@ -24,13 +26,17 @@ const Emote emotes[] = {
2426
{"\U0001F976", cold_face, cold_face_width, cold_face_height}, // 🥶 Cold Face
2527
{"\U0001F629", weary_face, weary_face_width, weary_face_height}, // 😩 Weary Face
2628
{"\U0001F62E", open_mouth, open_mouth_width, open_mouth_height}, // 😮 Open Mouth
29+
#endif // EMOTE_SET_STANDARD
2730

31+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_CORE
2832
// --- Question/Alert ---
2933
{"\u2753", question, question_width, question_height}, // ❓ Question Mark
3034
{"\u203C\uFE0F", bang, bang_width, bang_height}, // ‼️ Double Exclamation Mark
3135
{"\u26A0\uFE0F", caution, caution_width, caution_height}, // ⚠️ Warning Sign
3236
{"\U0001F4F6", antenna_bars, antenna_bars_width, antenna_bars_height}, // 📶 Antenna Bars
37+
#endif // EMOTE_SET_CORE
3338

39+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_STANDARD
3440
// --- Laughing Faces ---
3541
{"\U0001F602", haha, haha_width, haha_height}, // 😂 Face with Tears of Joy
3642
{"\U0001F923", rofl, rofl_width, rofl_height}, // 🤣 Rolling on the Floor Laughing
@@ -44,7 +50,9 @@ const Emote emotes[] = {
4450
{"\U0001F634", sleeping_face, sleeping_face_width, sleeping_face_height}, // 😴 Sleeping Face
4551
{"\U0001F440", eyes, eyes_width, eyes_height}, // 👀 Eyes
4652
{"\U0001F441\uFE0F", eye, eye_width, eye_height}, // 👁️ Eye
53+
#endif // EMOTE_SET_STANDARD
4754

55+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_STANDARD
4856
// --- Gestures and People ---
4957
{"\U0001F44B", wave_icon, wave_icon_width, wave_icon_height}, // 👋 Waving Hand
5058
{"\u270C\uFE0F", peace_sign, peace_sign_width, peace_sign_height}, // ✌️ Victory Hand
@@ -55,15 +63,19 @@ const Emote emotes[] = {
5563
{"\U0001F937", shrug, shrug_width, shrug_height}, // 🤷 Person Shrugging
5664
{"\U0001F920", cowboy, cowboy_width, cowboy_height}, // 🤠 Cowboy Hat Face
5765
{"\U0001F3A7", deadmau5, deadmau5_width, deadmau5_height}, // 🎧 Headphones
66+
#endif // EMOTE_SET_STANDARD
5867

68+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_CORE
5969
// --- Symbols ---
6070
{"\u2714\uFE0F", check_mark, check_mark_width, check_mark_height}, // ✔️ Check Mark
6171
{"\u2705", check_mark, check_mark_width, check_mark_height}, // ✅ Check Mark Button
6272
{"\u2611\uFE0F", check_mark, check_mark_width, check_mark_height}, // ☑️ Check Box with Check
6373
{"\U0001F3E0", house, house_width, house_height}, // 🏠 House
6474
{"\U0001F5FC", tower, tower_width, tower_height}, // 🗼 Tokyo Tower
6575
{"\U0001F4AF", one_hundred, one_hundred_width, one_hundred_height}, // 💯 Hundred Points Symbol
76+
#endif // EMOTE_SET_CORE
6677

78+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_STANDARD
6779
// --- Weather ---
6880
{"\u2600", sun, sun_width, sun_height}, // ☀ Sun (without variation selector)
6981
{"\u2600\uFE0F", sun, sun_width, sun_height}, // ☀️ Sun (with variation selector)
@@ -90,7 +102,9 @@ const Emote emotes[] = {
90102
{"\U0001F304", sunrise, sunrise_width, sunrise_height}, // 🌄 Sunrise
91103
{"\U0001F306", sunset, sunset_width, sunset_height}, // 🌆 Sunset
92104
{"\U0001F307", sunset, sunset_width, sunset_height}, // 🌇 Sunset
105+
#endif // EMOTE_SET_STANDARD
93106

107+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_FULL
94108
// --- Moon Phases ---
95109
{"\U0001F311", new_moon, new_moon_width, new_moon_height}, // 🌑 New Moon
96110
{"\U0001F312", waxing_crescent_moon, waxing_crescent_moon_width, waxing_crescent_moon_height}, // 🌒 Waxing Crescent Moon
@@ -102,13 +116,17 @@ const Emote emotes[] = {
102116
{"\U0001F318", waning_crescent_moon, waning_crescent_moon_width, waning_crescent_moon_height}, // 🌘 Waning Crescent Moon
103117
{"\U0001F31B", first_quarter_moon_face, first_quarter_moon_face_width,
104118
first_quarter_moon_face_height}, // 🌛 First Quarter Moon Face
119+
#endif // EMOTE_SET_FULL
105120

121+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_STANDARD
106122
// --- Misc Faces ---
107123
{"\U0001F608", devil, devil_width, devil_height}, // 😈 Smiling Face with Horns
108124
{"\U0001F921", clown, clown_width, clown_height}, // 🤡 Clown Face
109125
{"\U0001F916", robo, robo_width, robo_height}, // 🤖 Robot Face
110126
{"\U0001F479", ogre, ogre_width, ogre_height}, // 👹 Ogre
127+
#endif // EMOTE_SET_STANDARD
111128

129+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_CORE
112130
// --- Hearts (Multiple Unicode Aliases) ---
113131
{"\u2665", heart, heart_width, heart_height}, // ♥ Black Heart Suit
114132
{"\u2665\uFE0F", heart, heart_width, heart_height}, // ♥️ Black Heart Suit (emoji presentation)
@@ -120,7 +138,9 @@ const Emote emotes[] = {
120138
{"\U0001F496", heart, heart_width, heart_height}, // 💖 Sparkling Heart
121139
{"\U0001F497", heart, heart_width, heart_height}, // 💗 Growing Heart
122140
{"\U0001F498", heart, heart_width, heart_height}, // 💘 Heart with Arrow
141+
#endif // EMOTE_SET_CORE
123142

143+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_FULL
124144
// --- Objects ---
125145
{"\U0001F4A9", poo, poo_width, poo_height}, // 💩 Pile of Poo
126146
{"\U0001F514", bell_icon, bell_icon_width, bell_icon_height}, // 🔔 Bell
@@ -138,7 +158,9 @@ const Emote emotes[] = {
138158
{"\U0001F37A", beer, beer_width, beer_height},
139159
{"\U0001F954", potato, potato_width, potato_height}, // 🥔 Potato
140160
{"\U0001FAB5", wood, wood_width, wood_height}, // 🪵 Wood
161+
#endif // EMOTE_SET_FULL
141162

163+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_FULL
142164
// --- Arrows ---
143165
{"\u2193", downwards_arrow, downwards_arrow_width, downwards_arrow_height}, // ↓ Downwards Arrow
144166
{"\u2193\uFE0E", downwards_arrow, downwards_arrow_width, downwards_arrow_height}, // ↓︎ Downwards Arrow (text)
@@ -172,12 +194,16 @@ const Emote emotes[] = {
172194
{"\u2198", south_east_arrow, south_east_arrow_width, south_east_arrow_height}, // ↘ South East Arrow
173195
{"\u2198\uFE0E", south_east_arrow, south_east_arrow_width, south_east_arrow_height}, // ↘︎ South East Arrow (text)
174196
{"\u2198\uFE0F", south_east_arrow, south_east_arrow_width, south_east_arrow_height}, // ↘️ South East Arrow (emoji)
197+
#endif // EMOTE_SET_FULL
175198

199+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_FULL
176200
// --- Halloween ---
177201
{"\U0001F383", jack_o_lantern, jack_o_lantern_width, jack_o_lantern_height}, // 🎃 Jack-O-Lantern
178202
{"\U0001F47B", ghost, ghost_width, ghost_height}, // 👻 Ghost
179203
{"\U0001F480", skull, skull_width, skull_height}, // 💀 Skull
204+
#endif // EMOTE_SET_FULL
180205

206+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_FULL
181207
// --- Holidays ---
182208
{"\U0001F384", christmas_tree, christmas_tree_width, christmas_tree_height}, // 🎄 Christmas Tree
183209
{"\U0001F381", wrapped_gift, wrapped_gift_width, wrapped_gift_height}, // 🎁 Wrapped Gift
@@ -186,15 +212,23 @@ const Emote emotes[] = {
186212
{"\u2721\uFE0F", star_of_david, star_of_david_width, star_of_david_height}, // ✡️ Star of David
187213
{"\u26C4", snow_man, snow_man_width, snow_man_height}, // ⛄ Snowman
188214
{"\u2603\uFE0F", snow_man, snow_man_width, snow_man_height}, // ☃️ Snowman
215+
#endif // EMOTE_SET_FULL
189216

217+
#if MESHTASTIC_EMOTE_SET >= EMOTE_SET_FULL
190218
// --- Misc ---
191-
{"\U0001F4A8", dashing_away, dashing_away_width, dashing_away_height} // 💨 Dashing Away
192-
#endif
219+
{"\U0001F4A8", dashing_away, dashing_away_width, dashing_away_height}, // 💨 Dashing Away
220+
#endif // EMOTE_SET_FULL
193221
};
194222

195223
const int numEmotes = sizeof(emotes) / sizeof(emotes[0]);
196224

197-
#ifndef EXCLUDE_EMOJI
225+
#if MESHTASTIC_EMOTE_SET > EMOTE_SET_NONE
226+
// A mis-gated section that empties the table above EMOTE_SET_NONE would not fail to
227+
// build - it would ship a picker with nothing in it - so catch it here instead.
228+
static_assert(sizeof(emotes) / sizeof(emotes[0]) > 0, "emote set is non-empty above EMOTE_SET_NONE");
229+
#endif
230+
231+
#if MESHTASTIC_EMOTE_SET > EMOTE_SET_NONE
198232
const unsigned char thumbup[] PROGMEM = {0x00, 0x03, 0x80, 0x04, 0x80, 0x04, 0x40, 0x04, 0x20, 0x02, 0x18,
199233
0x02, 0x06, 0x3F, 0x06, 0x40, 0x06, 0x70, 0x06, 0x40, 0x06, 0x70,
200234
0x06, 0x40, 0x06, 0x30, 0x08, 0x20, 0xF0, 0x1F, 0x00, 0x00};

src/graphics/emotes.h

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,41 @@
11
#pragma once
2+
#include "configuration.h"
3+
#include "memory/FlashClass.h"
24
#include <Arduino.h>
35

6+
// === Emote set ladder ===
7+
// The emote table is pure flash: 16x16 XBM bitmaps in PROGMEM plus a 146-entry
8+
// index. It costs no RAM, so it tiers off MESHTASTIC_FLASH_CLASS (memory/FlashClass.h)
9+
// rather than the RAM ladder in memory/MemClass.h.
10+
//
11+
// EMOTE_SET_NONE no bitmaps; emoji render as their text label
12+
// EMOTE_SET_CORE acknowledgement, alerts, mesh status, heart
13+
// EMOTE_SET_STANDARD + faces, gestures and weather
14+
// EMOTE_SET_FULL + moon phases, objects, arrows, seasonal
15+
//
16+
// Compare ordinally (>=). Each section of the table in emotes.cpp carries its own
17+
// tier gate, so picker order is unchanged as tiers drop out. Dropping entries leaves
18+
// their bitmaps unreferenced and -fdata-sections/--gc-sections discards them, so the
19+
// saving is the index plus the bitmap data plus (at NONE, under LTO) the picker itself.
20+
#define EMOTE_SET_NONE 0
21+
#define EMOTE_SET_CORE 1
22+
#define EMOTE_SET_STANDARD 2
23+
#define EMOTE_SET_FULL 3
24+
25+
#ifndef MESHTASTIC_EMOTE_SET
26+
#ifdef EXCLUDE_EMOJI // long-standing spelling of "no emotes at all"
27+
#define MESHTASTIC_EMOTE_SET EMOTE_SET_NONE
28+
#elif MESHTASTIC_FLASH_CLASS <= FLASH_CLASS_TINY
29+
#define MESHTASTIC_EMOTE_SET EMOTE_SET_NONE
30+
#elif MESHTASTIC_FLASH_CLASS == FLASH_CLASS_SMALL
31+
// nRF52840 is the tightest screen-capable region we ship - rak4631 sits at 97% of it
32+
// on develop - so this class trades the seasonal/decorative tail for headroom.
33+
#define MESHTASTIC_EMOTE_SET EMOTE_SET_STANDARD
34+
#else
35+
#define MESHTASTIC_EMOTE_SET EMOTE_SET_FULL
36+
#endif
37+
#endif // MESHTASTIC_EMOTE_SET
38+
439
namespace graphics
540
{
641

@@ -15,7 +50,7 @@ struct Emote {
1550
extern const Emote emotes[/* numEmotes */];
1651
extern const int numEmotes;
1752

18-
#ifndef EXCLUDE_EMOJI
53+
#if MESHTASTIC_EMOTE_SET > EMOTE_SET_NONE
1954
// === Emote Bitmaps ===
2055
#define thumbs_height 16
2156
#define thumbs_width 16
@@ -425,6 +460,6 @@ extern const unsigned char wood[] PROGMEM;
425460
#define beer_width 16
426461
#define beer_height 16
427462
extern const unsigned char beer[] PROGMEM;
428-
#endif // EXCLUDE_EMOJI
463+
#endif // MESHTASTIC_EMOTE_SET > EMOTE_SET_NONE
429464

430465
} // namespace graphics

src/memory/FlashClass.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#pragma once
2+
3+
// Central flash-class ladder: flash-sized tables key their per-platform tier off
4+
// MESHTASTIC_FLASH_CLASS. Classes rank the *app flash region* a target actually has
5+
// to spend - not raw part size, and deliberately not RAM.
6+
//
7+
// FLASH_CLASS_TINY <256 KB app region STM32WL
8+
// FLASH_CLASS_SMALL ~784 KB nRF52840 (0x26000..0xEA000, warm store reserved)
9+
// FLASH_CLASS_MEDIUM ~1.9-3 MB app part. classic ESP32 / S2 / C3, RP2040/RP2350
10+
// FLASH_CLASS_LARGE 4 MB+ app, or host ESP32-S3 / C6 / P4, portduino
11+
//
12+
// This is the sibling of memory/MemClass.h, and the two ladders disagree on purpose.
13+
// MemClass ranks usable app heap; a chip can be poor in one resource and rich in the
14+
// other. Classic ESP32 and nRF52840 are both MEM_CLASS_SMALL, but the ESP32 has well
15+
// over twice the app flash, so a flash-shaped decision keyed off MESHTASTIC_MEM_CLASS
16+
// would trim the wrong targets. The reverse trap is just as real within a single class:
17+
// rak4631 and nrf52_promicro_diy_tcxo are the same chip and the same FLASH_CLASS_SMALL,
18+
// yet one ships with ~22 KB of headroom and the other does not fit at all - so a class
19+
// is a *default*, never a verdict. Tight variants predefine their own value.
20+
//
21+
// Compare ordinally (>=). An unclassified chip lands in SMALL on purpose: a smaller
22+
// table is a recoverable default, an image that overruns its region is not. Consumer
23+
// ladders stay #ifndef-guarded so a variant can always override. Requires the ARCH_*
24+
// macros, so include after (or via) configuration.h.
25+
26+
#define FLASH_CLASS_TINY 1
27+
#define FLASH_CLASS_SMALL 2
28+
#define FLASH_CLASS_MEDIUM 3
29+
#define FLASH_CLASS_LARGE 4
30+
31+
#ifndef MESHTASTIC_FLASH_CLASS
32+
#if defined(ARCH_STM32WL)
33+
#define MESHTASTIC_FLASH_CLASS FLASH_CLASS_TINY
34+
#elif defined(ARCH_NRF52) || defined(ARCH_NRF54L15)
35+
#define MESHTASTIC_FLASH_CLASS FLASH_CLASS_SMALL
36+
#elif defined(ARCH_PORTDUINO) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || \
37+
defined(CONFIG_IDF_TARGET_ESP32P4)
38+
// S3/C6/P4 boards overwhelmingly ship 8-16 MB. The 4 MB-part S3 variants that run
39+
// close to their app partition predefine MESHTASTIC_FLASH_CLASS instead.
40+
#define MESHTASTIC_FLASH_CLASS FLASH_CLASS_LARGE
41+
#elif defined(ARCH_ESP32) || defined(ARCH_RP2040)
42+
#define MESHTASTIC_FLASH_CLASS FLASH_CLASS_MEDIUM
43+
#else
44+
#define MESHTASTIC_FLASH_CLASS FLASH_CLASS_SMALL
45+
#endif
46+
#endif // MESHTASTIC_FLASH_CLASS

variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ board = promicro-nrf52840
1515
build_flags = ${nrf52840_base.build_flags}
1616
-I variants/nrf52840/diy/nrf52_promicro_diy_tcxo
1717
-D NRF52_PROMICRO_DIY
18-
-D EXCLUDE_EMOJI ; this variant builds 4 radio driver families and is the largest nrf52 image; emote bitmaps don't fit under the 0xEA000 warm-store cap
18+
-D MESHTASTIC_EMOTE_SET=EMOTE_SET_NONE ; this variant builds 4 radio driver families and is the largest nrf52 image; even the CORE emote set doesn't fit under the 0xEA000 warm-store cap
1919
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/diy/nrf52_promicro_diy_tcxo>
2020
debug_tool = jlink
2121

0 commit comments

Comments
 (0)