@typecad/cuttlefish 1.0.0-alpha.6 → 1.0.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/dist/api/config.d.ts +32 -0
  2. package/dist/api/index.d.ts +1 -1
  3. package/dist/api/schema/types.d.ts +15 -0
  4. package/dist/api/shared/async-runtime-static.d.ts +12 -1
  5. package/dist/api/shared/async-runtime-static.js +69 -24
  6. package/dist/api/shared/async-symbol-detector.d.ts +11 -0
  7. package/dist/api/shared/async-symbol-detector.js +140 -0
  8. package/dist/api/shared/async-types.d.ts +24 -0
  9. package/dist/api/shared/coop-scheduler.d.ts +60 -0
  10. package/dist/api/shared/coop-scheduler.js +149 -0
  11. package/dist/api/shared/display-adapter.d.ts +4 -3
  12. package/dist/api/shared/display-adapter.js +15 -118
  13. package/dist/api/shared/display-adapters/sdl.js +38 -31
  14. package/dist/api/shared/display-profile.d.ts +47 -25
  15. package/dist/api/shared/display-profile.js +31 -164
  16. package/dist/api/shared/framework-manifest-registry.d.ts +9 -0
  17. package/dist/api/shared/framework-manifest-registry.js +27 -0
  18. package/dist/api/shared/framework-manifest.d.ts +581 -0
  19. package/dist/api/shared/framework-manifest.js +182 -0
  20. package/dist/api/shared/glcdfont.d.ts +12 -0
  21. package/dist/api/shared/glcdfont.js +124 -0
  22. package/dist/api/shared/graphics-strategy.d.ts +37 -0
  23. package/dist/api/shared/hal-op-ir.d.ts +755 -1
  24. package/dist/api/shared/hal-op-ir.js +129 -1
  25. package/dist/api/shared/index.d.ts +20 -2
  26. package/dist/api/shared/index.js +25 -1
  27. package/dist/api/shared/ir-core.d.ts +4 -0
  28. package/dist/api/shared/ir-declarations.d.ts +6 -0
  29. package/dist/api/shared/native-display-op-resolver.d.ts +10 -0
  30. package/dist/api/shared/native-display-op-resolver.js +64 -0
  31. package/dist/api/shared/platform-strategy.d.ts +113 -2
  32. package/dist/api/shared/polyfill-helper-registry.js +18 -1
  33. package/dist/api/shared/promise-runtime.d.ts +1 -1
  34. package/dist/api/shared/promise-runtime.js +95 -13
  35. package/dist/api/shared/toolchain-types.d.ts +17 -0
  36. package/dist/api/shared/validate-framework-manifest.d.ts +28 -0
  37. package/dist/api/shared/validate-framework-manifest.js +494 -0
  38. package/dist/api/shared/worker-runtime-polyfill.d.ts +22 -0
  39. package/dist/api/shared/worker-runtime-polyfill.js +34 -0
  40. package/dist/api/shared/worker-runtime.d.ts +69 -0
  41. package/dist/api/shared/worker-runtime.js +163 -0
  42. package/dist/cli.js +186 -82
  43. package/dist/config-loader.d.ts +7 -2
  44. package/dist/config-loader.js +23 -3
  45. package/dist/config-schema.d.ts +112 -70
  46. package/dist/config-schema.js +14 -0
  47. package/dist/contract/board-generator.d.ts +17 -0
  48. package/dist/contract/board-generator.js +57 -0
  49. package/dist/contract/contract-parser.d.ts +217 -0
  50. package/dist/contract/contract-parser.js +224 -0
  51. package/dist/contract/index.d.ts +22 -0
  52. package/dist/contract/index.js +68 -0
  53. package/dist/create/board-codegen.js +4 -4
  54. package/dist/create/board-generators.js +4 -5
  55. package/dist/create/board-spec.d.ts +72 -75
  56. package/dist/create/board-spec.js +0 -1
  57. package/dist/create/init-scaffold.d.ts +9 -2
  58. package/dist/create/init-scaffold.js +0 -14
  59. package/dist/create/init-templates.d.ts +2 -0
  60. package/dist/create/init-templates.js +74 -8
  61. package/dist/create/init-wizard.js +31 -7
  62. package/dist/debug/preprocessor.js +178 -39
  63. package/dist/debug/types.d.ts +23 -0
  64. package/dist/diagnostics/mermaid-builder.d.ts +1 -1
  65. package/dist/diagnostics/mermaid-builder.js +34 -24
  66. package/dist/emit/compliance/arxml-writer.d.ts +11 -0
  67. package/dist/emit/compliance/arxml-writer.js +34 -0
  68. package/dist/emit/compliance/compliance-context.d.ts +57 -0
  69. package/dist/emit/compliance/compliance-context.js +113 -0
  70. package/dist/emit/compliance/deviation-ledger.d.ts +27 -0
  71. package/dist/emit/compliance/deviation-ledger.js +47 -0
  72. package/dist/emit/compliance/deviation-writer.d.ts +30 -0
  73. package/dist/emit/compliance/deviation-writer.js +37 -0
  74. package/dist/emit/compliance/index.d.ts +7 -0
  75. package/dist/emit/compliance/index.js +6 -0
  76. package/dist/emit/compliance/rule-engine.d.ts +13 -0
  77. package/dist/emit/compliance/rule-engine.js +101 -0
  78. package/dist/emit/compliance/rules.d.ts +16 -0
  79. package/dist/emit/compliance/rules.js +191 -0
  80. package/dist/emit/compliance/types.d.ts +59 -0
  81. package/dist/emit/compliance/types.js +8 -0
  82. package/dist/emit/cpp-emitter.js +4 -3
  83. package/dist/emit/emitters/class-emitter.js +6 -1
  84. package/dist/emit/emitters/emitter-context.d.ts +28 -1
  85. package/dist/emit/emitters/function-emitter-impl.js +153 -53
  86. package/dist/emit/emitters/line-appender.js +19 -0
  87. package/dist/emit/emitters/line-marker.d.ts +38 -0
  88. package/dist/emit/emitters/line-marker.js +39 -0
  89. package/dist/emit/emitters/output-finalizer.d.ts +6 -0
  90. package/dist/emit/emitters/output-finalizer.js +101 -12
  91. package/dist/emit/emitters/setup.d.ts +17 -0
  92. package/dist/emit/emitters/setup.js +257 -36
  93. package/dist/emit/emitters/top-level-prep.js +8 -0
  94. package/dist/emit/emitters/type-decl-emitter.js +28 -3
  95. package/dist/emit/emitters/ui-emitter.js +33 -9
  96. package/dist/emit/expression-renderer.d.ts +1 -1
  97. package/dist/emit/expression-renderer.js +91 -6
  98. package/dist/emit/route-hal-op.js +18 -5
  99. package/dist/emit/snprintf-helpers.js +15 -4
  100. package/dist/emit/statement-renderer.d.ts +10 -0
  101. package/dist/emit/statement-renderer.js +34 -5
  102. package/dist/emit/utils/async-state-machine.js +221 -125
  103. package/dist/emit/utils/hal-op-cpp-type.d.ts +6 -0
  104. package/dist/emit/utils/hal-op-cpp-type.js +40 -0
  105. package/dist/framework-package.js +2 -0
  106. package/dist/framework-registry.d.ts +17 -0
  107. package/dist/ir/adc-range-validation.js +14 -1
  108. package/dist/ir/build-ir-state.d.ts +1 -0
  109. package/dist/ir/build-ir-state.js +14 -0
  110. package/dist/ir/build-ir.js +9 -5
  111. package/dist/ir/call-graph.js +16 -0
  112. package/dist/ir/expression-to-ir.js +164 -0
  113. package/dist/ir/feature-registry.js +7 -25
  114. package/dist/ir/function-builder.js +22 -0
  115. package/dist/ir/hal/hal-emitter.d.ts +5 -2
  116. package/dist/ir/hal/hal-emitter.js +50 -18
  117. package/dist/ir/hal/hal-parser.d.ts +6 -0
  118. package/dist/ir/hal/hal-parser.js +81 -0
  119. package/dist/ir/hal/hal-plugins.js +723 -1
  120. package/dist/ir/identifier-collector.js +35 -0
  121. package/dist/ir/interrupt-analysis.d.ts +5 -1
  122. package/dist/ir/interrupt-analysis.js +8 -16
  123. package/dist/ir/network-validation.d.ts +4 -0
  124. package/dist/ir/network-validation.js +184 -0
  125. package/dist/ir/ownership-analysis.js +20 -1
  126. package/dist/ir/pin-capability-validation.js +37 -0
  127. package/dist/ir/pin-mode-validation.d.ts +2 -2
  128. package/dist/ir/pin-mode-validation.js +49 -18
  129. package/dist/ir/program-analysis.d.ts +65 -0
  130. package/dist/ir/program-analysis.js +318 -2
  131. package/dist/ir/render-expr.js +11 -0
  132. package/dist/ir/timing-validation.d.ts +6 -1
  133. package/dist/ir/timing-validation.js +60 -13
  134. package/dist/ir/transformers/call-statement.js +105 -0
  135. package/dist/ir/transformers/expressions.js +62 -0
  136. package/dist/ir/transformers/hal-call-resolver.js +21 -0
  137. package/dist/ir/transformers/hal-emit-helpers.js +1 -1
  138. package/dist/ir/transformers/namespace-methods.js +17 -12
  139. package/dist/ir/transformers/ui-reactive.js +2 -2
  140. package/dist/ir/transformers/variables.js +92 -3
  141. package/dist/ir/type-resolution.js +18 -0
  142. package/dist/ir/ui-element-auto-wire.js +7 -5
  143. package/dist/ir/utils/map-statements.d.ts +4 -0
  144. package/dist/ir/utils/map-statements.js +79 -0
  145. package/dist/ir/validation-orchestrator.js +9 -2
  146. package/dist/ir/worker-analysis.d.ts +10 -0
  147. package/dist/ir/worker-analysis.js +261 -0
  148. package/dist/libdef/c-to-decl.d.ts +27 -0
  149. package/dist/libdef/c-to-decl.js +397 -0
  150. package/dist/libdef/component-decls.d.ts +2 -0
  151. package/dist/libdef/component-decls.js +6 -0
  152. package/dist/libdef/component-discovery.d.ts +43 -0
  153. package/dist/libdef/component-discovery.js +83 -0
  154. package/dist/libdef/cpp-to-decl.d.ts +9 -0
  155. package/dist/libdef/cpp-to-decl.js +72 -0
  156. package/dist/libdef/registry.js +5 -2
  157. package/dist/lint-cache.d.ts +59 -0
  158. package/dist/lint-cache.js +257 -0
  159. package/dist/orchestrator/graph-builder.js +14 -9
  160. package/dist/platform/coop-scheduler-runtime.d.ts +19 -0
  161. package/dist/platform/coop-scheduler-runtime.js +41 -0
  162. package/dist/platform/generic-strategy.d.ts +15 -3
  163. package/dist/platform/generic-strategy.js +49 -4
  164. package/dist/safety/safety-bridge.d.ts +11 -0
  165. package/dist/safety/safety-bridge.js +48 -0
  166. package/dist/safety/sidecar-bridge.d.ts +5 -0
  167. package/dist/safety/sidecar-bridge.js +22 -0
  168. package/dist/safety-hook.d.ts +79 -0
  169. package/dist/safety-hook.js +35 -0
  170. package/dist/testing.d.ts +7 -1
  171. package/dist/testing.js +8 -1
  172. package/dist/transpile.d.ts +3 -0
  173. package/dist/transpile.js +175 -41
  174. package/dist/types.d.ts +13 -2
  175. package/dist/ui-hook.d.ts +17 -3
  176. package/dist/utils/cli.js +78 -4
  177. package/dist/utils/fs.d.ts +13 -0
  178. package/dist/utils/fs.js +50 -0
  179. package/package.json +24 -5
  180. package/dist/api/shared/display-adapters/eink-mono.d.ts +0 -2
  181. package/dist/api/shared/display-adapters/eink-mono.js +0 -53
  182. package/dist/api/shared/display-adapters/ssd1309.d.ts +0 -2
  183. package/dist/api/shared/display-adapters/ssd1309.js +0 -136
  184. package/dist/api/shared/display-adapters/st7796.d.ts +0 -2
  185. package/dist/api/shared/display-adapters/st7796.js +0 -132
  186. package/dist/licenses.d.ts +0 -185
  187. package/dist/licenses.js +0 -963
@@ -14,7 +14,15 @@ const adapters = new Map();
14
14
  export function registerDisplayAdapter(driver, gen) {
15
15
  adapters.set(driver, gen);
16
16
  }
17
- export function generateDisplayAdapter(display) {
17
+ export function generateDisplayAdapter(display, strategy) {
18
+ // Strategy-owned adapters take precedence (frameworks supply their own
19
+ // display driver code). Falls through to cuttlefish's generic built-in
20
+ // registry (e.g. the SDL native driver) when no strategy provides one.
21
+ if (strategy?.providesDisplayAdapter?.() && strategy.resolveDisplayAdapter) {
22
+ const code = strategy.resolveDisplayAdapter(display);
23
+ if (code)
24
+ return code;
25
+ }
18
26
  const driver = display.driver;
19
27
  const gen = adapters.get(driver);
20
28
  if (!gen) {
@@ -23,123 +31,12 @@ export function generateDisplayAdapter(display) {
23
31
  }
24
32
  return gen(display);
25
33
  }
26
- // ── ST7796S adapter (RGB565 + RGB666 modes) ─────────────────────────────────
27
- import { st7796Adapter } from "./display-adapters/st7796.js";
28
- registerDisplayAdapter("st7796", st7796Adapter);
29
- // ── eink-mono adapter (SSD1680-class, 1-bit, deferred partial refresh) ───────
30
- import { einkMonoAdapter } from "./display-adapters/eink-mono.js";
31
- registerDisplayAdapter("ssd1680", einkMonoAdapter);
32
- // ── SSD1309 OLED adapter (1-bit mono, I2C, page-buffered) ───────────────────
33
- import { ssd1309Adapter } from "./display-adapters/ssd1309.js";
34
- registerDisplayAdapter("ssd1309", ssd1309Adapter);
35
34
  // ── SDL2 adapter (native desktop window, RGB888) ────────────────────────────
36
35
  import { sdlAdapter } from "./display-adapters/sdl.js";
37
36
  registerDisplayAdapter("sdl", sdlAdapter);
38
- // ── ILI9341 adapter ─────────────────────────────────────────────────────────
39
- // The first built-in adapter. Mirrors the code previously hardcoded in
40
- // ui-emitter.ts and runtime-header.ts.
41
- registerDisplayAdapter("ili9341", (display) => {
42
- const cs = display._mountCs;
43
- const dc = display._mountDc;
44
- const rst = display._mountRst;
45
- const rotation = display.rotation ?? 1;
46
- const spiFreq = display.spiFrequency;
47
- return {
48
- includes: [
49
- `#define CuttlefishDisplayTarget Adafruit_GFX`,
50
- `#define CuttlefishCanvas16 GFXcanvas16`,
51
- `#include <Adafruit_GFX.h>`,
52
- `#include <Adafruit_ILI9341.h>`,
53
- ].join("\n"),
54
- declaration: `Adafruit_ILI9341 __tc_display = Adafruit_ILI9341(${cs}, ${dc}, ${rst});`,
55
- functions: [
56
- `// --- Display adapter: ILI9341 ---`,
57
- ``,
58
- `static inline void display_init() {`,
59
- spiFreq
60
- ? ` __tc_display.begin(${spiFreq});`
61
- : ` __tc_display.begin();`,
62
- ` __tc_display.setRotation(${rotation});`,
63
- ` __tc_display.fillScreen(0x0000);`,
64
- `}`,
65
- ``,
66
- `static inline void display_fillScreen(uint16_t color) {`,
67
- ` __tc_display.fillScreen(color);`,
68
- `}`,
69
- ``,
70
- `static inline CuttlefishDisplayTarget* display_defaultTarget() { return &__tc_display; }`,
71
- `static inline int16_t display_width() { return __tc_display.width(); }`,
72
- `static inline int16_t display_height() { return __tc_display.height(); }`,
73
- ``,
74
- `static inline void display_startWrite() { __tc_display.startWrite(); }`,
75
- `static inline void display_endWrite() { __tc_display.endWrite(); }`,
76
- `static inline void display_setAddrWindow(int16_t x, int16_t y, int16_t w, int16_t h) {`,
77
- ` __tc_display.setAddrWindow(x, y, w, h);`,
78
- `}`,
79
- `static inline void display_writePixels(uint16_t* pixels, uint32_t count) {`,
80
- ` __tc_display.writePixels(pixels, count);`,
81
- `}`,
82
- ``,
83
- `static inline CuttlefishCanvas16* display_createCanvas(int16_t w, int16_t h) {`,
84
- ` return new GFXcanvas16(w, h);`,
85
- `}`,
86
- `static inline CuttlefishCanvas16* display_createCanvasPsram(int16_t w, int16_t h) {`,
87
- `#if defined(ESP32) && defined(BOARD_HAS_PSRAM)`,
88
- ` return new (ps_malloc(sizeof(GFXcanvas16))) GFXcanvas16(w, h);`,
89
- `#else`,
90
- ` (void)w; (void)h;`,
91
- ` return nullptr;`,
92
- `#endif`,
93
- `}`,
94
- `static inline void display_deleteCanvas(CuttlefishCanvas16* canvas) { delete canvas; }`,
95
- `static inline int16_t display_canvasWidth(CuttlefishCanvas16* canvas) { return canvas->width(); }`,
96
- `static inline int16_t display_canvasHeight(CuttlefishCanvas16* canvas) { return canvas->height(); }`,
97
- `static inline uint16_t* display_canvasBuffer(CuttlefishCanvas16* canvas) { return canvas->getBuffer(); }`,
98
- `static inline uint16_t display_canvasGetPixel(CuttlefishCanvas16* canvas, int16_t x, int16_t y) { return canvas->getPixel(x, y); }`,
99
- `static inline void display_canvasFillScreen(CuttlefishCanvas16* canvas, UI_COLOR_T color) { canvas->fillScreen((uint16_t)color); }`,
100
- `static inline void display_canvasFillRect(CuttlefishCanvas16* canvas, int16_t x, int16_t y, int16_t w, int16_t h, UI_COLOR_T color) {`,
101
- ` canvas->fillRect(x, y, w, h, (uint16_t)color);`,
102
- `}`,
103
- ``,
104
- `static inline void display_targetDrawPixel(CuttlefishDisplayTarget* target, int16_t x, int16_t y, UI_COLOR_T color) { target->drawPixel(x, y, (uint16_t)color); }`,
105
- `static inline int16_t display_targetWidth(CuttlefishDisplayTarget* target) { return target->width(); }`,
106
- `static inline int16_t display_targetHeight(CuttlefishDisplayTarget* target) { return target->height(); }`,
107
- `static inline void display_targetDrawRGBBitmap(CuttlefishDisplayTarget* target, int16_t x, int16_t y, const uint16_t* bitmap, int16_t w, int16_t h) {`,
108
- ` target->drawRGBBitmap(x, y, bitmap, w, h);`,
109
- `}`,
110
- `static inline void display_targetFillRect(CuttlefishDisplayTarget* target, int16_t x, int16_t y, int16_t w, int16_t h, UI_COLOR_T color) {`,
111
- ` target->fillRect(x, y, w, h, (uint16_t)color);`,
112
- `}`,
113
- `static inline void display_targetDrawFastHLine(CuttlefishDisplayTarget* target, int16_t x, int16_t y, int16_t w, UI_COLOR_T color) {`,
114
- ` target->drawFastHLine(x, y, w, (uint16_t)color);`,
115
- `}`,
116
- `static inline void display_targetDrawFastVLine(CuttlefishDisplayTarget* target, int16_t x, int16_t y, int16_t h, UI_COLOR_T color) {`,
117
- ` target->drawFastVLine(x, y, h, (uint16_t)color);`,
118
- `}`,
119
- `static inline void display_targetFillRoundRect(CuttlefishDisplayTarget* target, int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, UI_COLOR_T color) {`,
120
- ` target->fillRoundRect(x, y, w, h, r, (uint16_t)color);`,
121
- `}`,
122
- `static inline void display_targetDrawRect(CuttlefishDisplayTarget* target, int16_t x, int16_t y, int16_t w, int16_t h, UI_COLOR_T color) {`,
123
- ` target->drawRect(x, y, w, h, (uint16_t)color);`,
124
- `}`,
125
- `static inline void display_targetDrawRoundRect(CuttlefishDisplayTarget* target, int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, UI_COLOR_T color) {`,
126
- ` target->drawRoundRect(x, y, w, h, r, (uint16_t)color);`,
127
- `}`,
128
- `static inline void display_targetDrawLine(CuttlefishDisplayTarget* target, int16_t x0, int16_t y0, int16_t x1, int16_t y1, UI_COLOR_T color) {`,
129
- ` target->drawLine(x0, y0, x1, y1, (uint16_t)color);`,
130
- `}`,
131
- `static inline void display_targetFillCircle(CuttlefishDisplayTarget* target, int16_t x, int16_t y, int16_t r, UI_COLOR_T color) {`,
132
- ` target->fillCircle(x, y, r, (uint16_t)color);`,
133
- `}`,
134
- `static inline void display_targetDrawCircle(CuttlefishDisplayTarget* target, int16_t x, int16_t y, int16_t r, UI_COLOR_T color) {`,
135
- ` target->drawCircle(x, y, r, (uint16_t)color);`,
136
- `}`,
137
- `static inline void display_targetSetCursor(CuttlefishDisplayTarget* target, int16_t x, int16_t y) { target->setCursor(x, y); }`,
138
- `static inline void display_targetSetTextColor(CuttlefishDisplayTarget* target, UI_COLOR_T fg) { target->setTextColor((uint16_t)fg); }`,
139
- `static inline void display_targetSetTextColorBg(CuttlefishDisplayTarget* target, UI_COLOR_T fg, UI_COLOR_T bg) { target->setTextColor((uint16_t)fg, (uint16_t)bg); }`,
140
- `static inline void display_targetSetTextSize(CuttlefishDisplayTarget* target, uint8_t size) { target->setTextSize(size); }`,
141
- `static inline void display_targetSetTextWrap(CuttlefishDisplayTarget* target, bool wrap) { target->setTextWrap(wrap); }`,
142
- `static inline void display_targetPrint(CuttlefishDisplayTarget* target, const char* text) { target->print(text); }`,
143
- ].join("\n"),
144
- };
145
- });
37
+ // NOTE: The Adafruit_GFX-based adapters (ili9341, st7796, ssd1309, ssd1680
38
+ // eink) were moved to @typecad/framework-arduino (src/displays/
39
+ // adafruit-adapters.ts). They are now strategy-owned: ArduinoStrategy.
40
+ // providesDisplayAdapter() returns true and resolveDisplayAdapter() dispatches
41
+ // to them by driver name. Cuttlefish keeps only the generic adapter registry
42
+ // infrastructure + the framework-agnostic sdl driver for native desktop.
@@ -62,33 +62,33 @@ export const sdlAdapter = (display) => {
62
62
  ` uint32_t fg = 0xFFFFFFu, bg = 0x000000u;`,
63
63
  ` uint8_t textSize = 1;`,
64
64
  ` bool wrap = true;`,
65
- ` explicit SdlGfxCanvas(int16_t w, int16_t h) : w_(w), h_(h), buf(new uint32_t[(size_t)w * h]()) {}`,
65
+ ` explicit SdlGfxCanvas(int16_t w, int16_t h) : w_(w), h_(h), buf(new uint32_t[static_cast<size_t>(w) * h]()) {}`,
66
66
  ` virtual ~SdlGfxCanvas() { delete[] buf; }`,
67
67
  ` int16_t width() const { return w_; }`,
68
68
  ` int16_t height() const { return h_; }`,
69
69
  ` inline void put(int16_t x, int16_t y, uint32_t rgba) {`,
70
70
  ` if (x < 0 || y < 0 || x >= w_ || y >= h_) return;`,
71
- ` buf[(size_t)y * w_ + x] = rgba;`,
71
+ ` buf[static_cast<size_t>(y) * w_ + x] = rgba;`,
72
72
  ` }`,
73
73
  ` inline uint32_t get(int16_t x, int16_t y) const {`,
74
74
  ` if (x < 0 || y < 0 || x >= w_ || y >= h_) return 0;`,
75
- ` return buf[(size_t)y * w_ + x];`,
75
+ ` return buf[static_cast<size_t>(y) * w_ + x];`,
76
76
  ` }`,
77
- ` void drawPixel(int16_t x, int16_t y, UI_COLOR_T color) { put(x, y, (uint32_t)color); }`,
77
+ ` void drawPixel(int16_t x, int16_t y, UI_COLOR_T color) { put(x, y, static_cast<uint32_t>(color)); }`,
78
78
  ` void fillRect(int16_t x, int16_t y, int16_t rw, int16_t rh, UI_COLOR_T color) {`,
79
79
  ` if (rw <= 0 || rh <= 0) return;`,
80
- ` uint32_t rgba = (uint32_t)color;`,
80
+ ` uint32_t rgba = static_cast<uint32_t>(color);`,
81
81
  ` int16_t x0 = x < 0 ? 0 : x;`,
82
82
  ` int16_t y0 = y < 0 ? 0 : y;`,
83
83
  ` int16_t x1 = x + rw; if (x1 > w_) x1 = w_;`,
84
84
  ` int16_t y1 = y + rh; if (y1 > h_) y1 = h_;`,
85
85
  ` if (x0 >= x1 || y0 >= y1) return;`,
86
86
  ` for (int16_t j = y0; j < y1; j++)`,
87
- ` for (int16_t i = x0; i < x1; i++) buf[(size_t)j * w_ + i] = rgba;`,
87
+ ` for (int16_t i = x0; i < x1; i++) buf[static_cast<size_t>(j) * w_ + i] = rgba;`,
88
88
  ` }`,
89
89
  ` void fillScreen(UI_COLOR_T color) {`,
90
- ` uint32_t rgba = (uint32_t)color;`,
91
- ` for (size_t i = 0; i < (size_t)w_ * h_; i++) buf[i] = rgba;`,
90
+ ` uint32_t rgba = static_cast<uint32_t>(color);`,
91
+ ` for (size_t i = 0; i < static_cast<size_t>(w_) * h_; i++) buf[i] = rgba;`,
92
92
  ` }`,
93
93
  ` void drawFastHLine(int16_t x, int16_t y, int16_t len, UI_COLOR_T c) { fillRect(x, y, len, 1, c); }`,
94
94
  ` void drawFastVLine(int16_t x, int16_t y, int16_t len, UI_COLOR_T c) { fillRect(x, y, 1, len, c); }`,
@@ -108,7 +108,7 @@ export const sdlAdapter = (display) => {
108
108
  ` int16_t err = dx / 2;`,
109
109
  ` int16_t ystep = (y0 < y1) ? 1 : -1;`,
110
110
  ` for (; x0 <= x1; x0++) {`,
111
- ` if (steep) put(y0, x0, (uint32_t)c); else put(x0, y0, (uint32_t)c);`,
111
+ ` if (steep) put(y0, x0, static_cast<uint32_t>(c)); else put(x0, y0, static_cast<uint32_t>(c));`,
112
112
  ` err -= dy; if (err < 0) { y0 += ystep; err += dx; }`,
113
113
  ` }`,
114
114
  ` }`,
@@ -117,10 +117,10 @@ export const sdlAdapter = (display) => {
117
117
  ` while (x < y) {`,
118
118
  ` if (f >= 0) { y--; ddFy += 2; f += ddFy; }`,
119
119
  ` x++; ddFx += 2; f += ddFx;`,
120
- ` if (cn & 0x4) { put(x0 + x, y0 + y, (uint32_t)c); put(x0 + y, y0 + x, (uint32_t)c); }`,
121
- ` if (cn & 0x2) { put(x0 + x, y0 - y, (uint32_t)c); put(x0 + y, y0 - x, (uint32_t)c); }`,
122
- ` if (cn & 0x8) { put(x0 - y, y0 + x, (uint32_t)c); put(x0 - x, y0 + y, (uint32_t)c); }`,
123
- ` if (cn & 0x1) { put(x0 - y, y0 - x, (uint32_t)c); put(x0 - x, y0 - y, (uint32_t)c); }`,
120
+ ` if (cn & 0x4) { put(x0 + x, y0 + y, static_cast<uint32_t>(c)); put(x0 + y, y0 + x, static_cast<uint32_t>(c)); }`,
121
+ ` if (cn & 0x2) { put(x0 + x, y0 - y, static_cast<uint32_t>(c)); put(x0 + y, y0 - x, static_cast<uint32_t>(c)); }`,
122
+ ` if (cn & 0x8) { put(x0 - y, y0 + x, static_cast<uint32_t>(c)); put(x0 - x, y0 + y, static_cast<uint32_t>(c)); }`,
123
+ ` if (cn & 0x1) { put(x0 - y, y0 - x, static_cast<uint32_t>(c)); put(x0 - x, y0 - y, static_cast<uint32_t>(c)); }`,
124
124
  ` }`,
125
125
  ` }`,
126
126
  ` void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t corners, int16_t delta, UI_COLOR_T c) {`,
@@ -143,15 +143,15 @@ export const sdlAdapter = (display) => {
143
143
  ` }`,
144
144
  ` void drawCircle(int16_t x0, int16_t y0, int16_t r, UI_COLOR_T c) {`,
145
145
  ` int16_t f = 1 - r, ddFx = 1, ddFy = -2 * r, x = 0, y = r;`,
146
- ` put(x0, y0 + r, (uint32_t)c); put(x0, y0 - r, (uint32_t)c);`,
147
- ` put(x0 + r, y0, (uint32_t)c); put(x0 - r, y0, (uint32_t)c);`,
146
+ ` put(x0, y0 + r, static_cast<uint32_t>(c)); put(x0, y0 - r, static_cast<uint32_t>(c));`,
147
+ ` put(x0 + r, y0, static_cast<uint32_t>(c)); put(x0 - r, y0, static_cast<uint32_t>(c));`,
148
148
  ` while (x < y) {`,
149
149
  ` if (f >= 0) { y--; ddFy += 2; f += ddFy; }`,
150
150
  ` x++; ddFx += 2; f += ddFx;`,
151
- ` put(x0 + x, y0 + y, (uint32_t)c); put(x0 - x, y0 + y, (uint32_t)c);`,
152
- ` put(x0 + x, y0 - y, (uint32_t)c); put(x0 - x, y0 - y, (uint32_t)c);`,
153
- ` put(x0 + y, y0 + x, (uint32_t)c); put(x0 - y, y0 + x, (uint32_t)c);`,
154
- ` put(x0 + y, y0 - x, (uint32_t)c); put(x0 - y, y0 - x, (uint32_t)c);`,
151
+ ` put(x0 + x, y0 + y, static_cast<uint32_t>(c)); put(x0 - x, y0 + y, static_cast<uint32_t>(c));`,
152
+ ` put(x0 + x, y0 - y, static_cast<uint32_t>(c)); put(x0 - x, y0 - y, static_cast<uint32_t>(c));`,
153
+ ` put(x0 + y, y0 + x, static_cast<uint32_t>(c)); put(x0 - y, y0 + x, static_cast<uint32_t>(c));`,
154
+ ` put(x0 + y, y0 - x, static_cast<uint32_t>(c)); put(x0 - y, y0 - x, static_cast<uint32_t>(c));`,
155
155
  ` }`,
156
156
  ` }`,
157
157
  ` void fillCircle(int16_t x0, int16_t y0, int16_t r, UI_COLOR_T c) {`,
@@ -183,12 +183,12 @@ export const sdlAdapter = (display) => {
183
183
  ` void drawRGBBitmap(int16_t x, int16_t y, const UI_COLOR_T* b, int16_t bw, int16_t bh) {`,
184
184
  ` for (int16_t j = 0; j < bh; j++)`,
185
185
  ` for (int16_t i = 0; i < bw; i++) {`,
186
- ` put(x + i, y + j, (uint32_t)b[(size_t)j * bw + i]);`,
186
+ ` put(x + i, y + j, static_cast<uint32_t>(b[static_cast<size_t>(j) * bw + i]));`,
187
187
  ` }`,
188
188
  ` }`,
189
189
  ` void setCursor(int16_t x, int16_t y) { cx = x; cy = y; }`,
190
- ` void setTextColor(UI_COLOR_T c) { fg = (uint32_t)c; bg = fg; }`,
191
- ` void setTextColorBg(UI_COLOR_T c, UI_COLOR_T b) { fg = (uint32_t)c; bg = (uint32_t)b; }`,
190
+ ` void setTextColor(UI_COLOR_T c) { fg = static_cast<uint32_t>(c); bg = fg; }`,
191
+ ` void setTextColorBg(UI_COLOR_T c, UI_COLOR_T b) { fg = static_cast<uint32_t>(c); bg = static_cast<uint32_t>(b); }`,
192
192
  ` void setTextSize(uint8_t s) { textSize = s; }`,
193
193
  ` void setTextWrap(bool wp) { wrap = wp; }`,
194
194
  ` // print() uses the 5x8 glcd font (same bytes as Adafruit_GFX / the`,
@@ -206,7 +206,7 @@ export const sdlAdapter = (display) => {
206
206
  ``,
207
207
  `void SdlGfxCanvas::drawChar(int16_t x, int16_t y, unsigned char ch, uint32_t fgc, uint32_t bgc, uint8_t size) {`,
208
208
  ` if (ch >= 176 && ch < 255) ch++;`,
209
- ` const uint8_t* glyph = &__sdl_glcdfont[(size_t)ch * 5];`,
209
+ ` const uint8_t* glyph = &__sdl_glcdfont[static_cast<size_t>(ch) * 5];`,
210
210
  ` for (int8_t i = 0; i < 5; i++) {`,
211
211
  ` uint8_t line = glyph[i];`,
212
212
  ` for (int8_t j = 0; j < 8; j++, line >>= 1) {`,
@@ -229,7 +229,7 @@ export const sdlAdapter = (display) => {
229
229
  ` if (*s == '\\n') { cx = 0; cy += 8 * textSize; s++; continue; }`,
230
230
  ` if (*s == '\\r') { s++; continue; }`,
231
231
  ` if (wrap && cx + 6 * textSize > w_) { cx = 0; cy += 8 * textSize; }`,
232
- ` drawChar(cx, cy, (unsigned char)*s, fg, bg, textSize);`,
232
+ ` drawChar(cx, cy, static_cast<unsigned char>(*s), fg, bg, textSize);`,
233
233
  ` cx += 6 * textSize;`,
234
234
  ` s++;`,
235
235
  ` }`,
@@ -247,10 +247,10 @@ export const sdlAdapter = (display) => {
247
247
  ` // ARGB8888, so set opaque alpha (0xFF) per pixel at present time.`,
248
248
  ` static uint32_t* _presentBuf = nullptr;`,
249
249
  ` static size_t _presentBufLen = 0;`,
250
- ` size_t n = (size_t)w_ * h_;`,
250
+ ` size_t n = static_cast<size_t>(w_) * h_;`,
251
251
  ` if (!_presentBuf || _presentBufLen < n) { delete[] _presentBuf; _presentBuf = new uint32_t[n]; _presentBufLen = n; }`,
252
252
  ` for (size_t i = 0; i < n; i++) _presentBuf[i] = 0xFF000000u | buf[i];`,
253
- ` SDL_UpdateTexture(tex, nullptr, _presentBuf, w_ * (int)sizeof(uint32_t));`,
253
+ ` SDL_UpdateTexture(tex, nullptr, _presentBuf, w_ * static_cast<int>(sizeof(uint32_t)));`,
254
254
  ` SDL_RenderClear(ren);`,
255
255
  ` SDL_RenderCopy(ren, tex, nullptr, nullptr);`,
256
256
  ` SDL_RenderPresent(ren);`,
@@ -316,10 +316,10 @@ export const sdlAdapter = (display) => {
316
316
  `}`,
317
317
  `static inline void display_writePixels(uint32_t* pixels, uint32_t count) {`,
318
318
  ` if (!pixels || __sdl_addr_w <= 0 || __sdl_addr_h <= 0) return;`,
319
- ` uint32_t max = (uint32_t)__sdl_addr_w * (uint32_t)__sdl_addr_h;`,
319
+ ` uint32_t max = static_cast<uint32_t>(__sdl_addr_w) * static_cast<uint32_t>(__sdl_addr_h);`,
320
320
  ` for (uint32_t i = 0; i < count && __sdl_write_pos < max; i++, __sdl_write_pos++) {`,
321
- ` int16_t dx = (int16_t)(__sdl_addr_x + (__sdl_write_pos % (uint32_t)__sdl_addr_w));`,
322
- ` int16_t dy = (int16_t)(__sdl_addr_y + (__sdl_write_pos / (uint32_t)__sdl_addr_w));`,
321
+ ` int16_t dx = static_cast<int16_t>(__sdl_addr_x + (__sdl_write_pos % static_cast<uint32_t>(__sdl_addr_w)));`,
322
+ ` int16_t dy = static_cast<int16_t>(__sdl_addr_y + (__sdl_write_pos / static_cast<uint32_t>(__sdl_addr_w)));`,
323
323
  ` __tc_display.put(dx, dy, pixels[i]);`,
324
324
  ` }`,
325
325
  `}`,
@@ -366,8 +366,15 @@ function glcdfontBytes() {
366
366
  }
367
367
  return lines;
368
368
  }
369
- // Canonical Adafruit GFX 5x7 glcdfont. Public domain.
370
- // Source: Adafruit_GFX library glcdfont.c.
369
+ // Adafruit GFX 5x7 glcdfont the 'classic' fixed-space bitmap font shipped
370
+ // with Adafruit_GFX since 1.0. BSD-3-Clause as part of the Adafruit_GFX
371
+ // library (the file carries no per-file license statement; an earlier
372
+ // revision of this comment claimed "public domain" but that could not be
373
+ // verified). See packages/cuttlefish/src/api/shared/glcdfont.ts for the
374
+ // canonical attribution header; this array is the same bytes, retained
375
+ // here to keep the SDL preview self-contained.
376
+ // Source: Adafruit_GFX library glcdfont.c
377
+ // Upstream: https://github.com/adafruit/Adafruit-GFX-Library/blob/master/glcdfont.c
371
378
  const GLCDFONT_BYTES = [
372
379
  0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x5b, 0x4f, 0x5b, 0x3e, 0x3e, 0x6b, 0x4f, 0x6b, 0x3e, 0x1c,
373
380
  0x3e, 0x7c, 0x3e, 0x1c, 0x18, 0x3c, 0x7e, 0x3c, 0x18, 0x1c, 0x57, 0x7d, 0x57, 0x1c, 0x1c, 0x5e,
@@ -1,5 +1,5 @@
1
1
  import type { DisplayCapabilities } from "./display-capabilities.js";
2
- export type TouchLibrary = "XPT2046_Touchscreen" | "Adafruit_TouchScreen" | "Adafruit_STMPE610" | "FT6336U" | "sdl";
2
+ export type TouchLibrary = "XPT2046_Touchscreen" | "Adafruit_TouchScreen" | "Adafruit_STMPE610" | "FT6336U" | "GT911" | "CST816S" | "sdl";
3
3
  export interface TouchProfile {
4
4
  /**
5
5
  * Either a built-in library name OR a path to a custom TypeScript adapter
@@ -37,6 +37,10 @@ export interface TouchProfile {
37
37
  /** Reset pin for touch controllers requiring a hardware-reset sequence
38
38
  * before begin() (FT6336U on boards with a reset GPIO tied to the chip). */
39
39
  resetPin?: number;
40
+ /** I2C SDA pin (Zephyr: used to configure the I2C bus pinctrl in the DT overlay). */
41
+ sda?: number;
42
+ /** I2C SCL pin (Zephyr: used to configure the I2C bus pinctrl in the DT overlay). */
43
+ scl?: number;
40
44
  /** Raw ADC calibration — maps touch controller raw values to display pixels. */
41
45
  calibration: {
42
46
  xMin: number;
@@ -75,6 +79,13 @@ export interface DisplayProfile {
75
79
  /** Optional explicit display inversion override. Some controller libraries
76
80
  * use panel-specific defaults that do not match every module. */
77
81
  invertDisplay?: boolean;
82
+ /**
83
+ * Experimental dirty-rectangle synchronization using the controller's
84
+ * GET_SCANLINE (0x45) readback command. This is opt-in: many ST7796S
85
+ * modules expose SDO but return unreliable data or stop scanning when 0x45
86
+ * is read, so a missing/unsafe readback path must not affect normal drawing.
87
+ */
88
+ scanlineSync?: boolean;
78
89
  touch?: TouchProfile;
79
90
  /** Enable antialiased rendering for circles, lines, rounded corners, and text
80
91
  * unless a node opts out with font-smoothing:none.
@@ -105,8 +116,10 @@ export interface ResolvedDisplay extends DisplayProfile {
105
116
  _mountBus: string;
106
117
  _mountAddress: number;
107
118
  _mountReset: number;
108
- /** Arduino FQBN (e.g. "esp32:esp32:esp32s3:PSRAM=opi"), used to derive PSRAM
109
- * availability for the scroll-canvas-memory budget. Optional. */
119
+ /** Framework build target string (e.g. an Arduino FQBN like
120
+ * "esp32:esp32:esp32s3:PSRAM=opi" or an IDF target). Carried through for
121
+ * framework-side toolchain/compile use; cuttlefish itself does not parse it.
122
+ * Optional. */
110
123
  _buildTarget?: string;
111
124
  }
112
125
  export interface DisplayConfig {
@@ -122,7 +135,13 @@ export interface DisplayConfig {
122
135
  displayClass?: "tft" | "eink" | "oled";
123
136
  capabilities?: DisplayCapabilities;
124
137
  rotation?: number;
138
+ /** Arduino framework: GPIO pin driving the panel backlight (set high at init). */
125
139
  backlight?: number;
140
+ /** Zephyr framework: GPIO pin driving the panel backlight. When set, the
141
+ * framework emits a gpio-leds DT node + `backlight` alias so the display
142
+ * adapter drives it high at init. Omit when the backlight is hardwired to
143
+ * power (e.g. tied to 3.3V) — no node or alias is emitted in that case. */
144
+ backlightPin?: number;
126
145
  spiFrequency?: number;
127
146
  spiPins?: {
128
147
  mosi: number;
@@ -133,6 +152,12 @@ export interface DisplayConfig {
133
152
  colorOrder?: "rgb" | "bgr";
134
153
  /** Optional explicit display inversion override. */
135
154
  invertDisplay?: boolean;
155
+ /**
156
+ * Opt in to experimental GET_SCANLINE (0x45) dirty-rectangle synchronization
157
+ * on adapters that have a verified controller readback path. Disabled by
158
+ * default because some ST7796S modules misbehave when this command is read.
159
+ */
160
+ scanlineSync?: boolean;
136
161
  touch?: TouchProfile | false;
137
162
  cs?: number;
138
163
  dc?: number;
@@ -201,9 +226,6 @@ export interface ScrollConfig {
201
226
  /** Emit per-frame scroll/canvas telemetry over Serial (UI_SCROLL_DEBUG). Off by
202
227
  * default — enable temporarily to diagnose scroll/canvas draw skips on-device. */
203
228
  debug?: boolean;
204
- /** Max RGB565 scroll viewport canvas size (w×h×2 bytes) assumed to fit in heap
205
- * for Mode B smooth scrolling on the target. Default ~88 KB (ESP32 no PSRAM). */
206
- scrollCanvasBudgetBytes?: number;
207
229
  }
208
230
  /** Fully-resolved scroll config — every field populated, ready for emit. */
209
231
  export interface ResolvedScrollConfig {
@@ -216,22 +238,7 @@ export interface ResolvedScrollConfig {
216
238
  inputSmoothing: number;
217
239
  overrideProbes: boolean;
218
240
  debug: boolean;
219
- scrollCanvasBudgetBytes: number;
220
241
  }
221
- /** Default RGB565 scroll viewport canvas budget (~88 KB, ESP32-class SRAM). */
222
- export declare const DEFAULT_SCROLL_CANVAS_BUDGET_BYTES = 88000;
223
- /** PSRAM scroll canvas budget (~2 MB). ESP32-S3 with OPI/QSPI PSRAM exposes
224
- * ~8 MB external RAM; a full-width scroll viewport canvas (e.g. 460×266×2 ≈
225
- * 239 KB) is trivial there, so the transpile-time scroll-canvas-memory
226
- * diagnostic should use a PSRAM-appropriate budget rather than the no-PSRAM
227
- * SRAM default — otherwise every PSRAM target emits stale "exceeds budget"
228
- * warnings for canvases the runtime allocates without issue. */
229
- export declare const PSRAM_SCROLL_CANVAS_BUDGET_BYTES = 2000000;
230
- /** Detect PSRAM from an Arduino FQBN buildTarget (e.g. "esp32:esp32:esp32s3:PSRAM=opi").
231
- * Returns true for any PSRAM=<value> option whose value indicates PSRAM is
232
- * enabled (opi, io, qspi, enabled, true). Returns false when absent or set
233
- * to a disabled-looking value (disabled, false, none). */
234
- export declare function buildTargetHasPsram(buildTarget: string | undefined): boolean;
235
242
  /**
236
243
  * Resolve scroll config from a display profile. Declared overrides win;
237
244
  * otherwise derive the input tier from the touch library (resistive chips →
@@ -241,8 +248,6 @@ export declare function buildTargetHasPsram(buildTarget: string | undefined): bo
241
248
  export declare function resolveScrollConfig(display: {
242
249
  touch?: TouchProfile | false;
243
250
  scroll?: ScrollConfig;
244
- }, ctx?: {
245
- buildTarget?: string;
246
251
  }): ResolvedScrollConfig;
247
252
  export declare function resolveDisplayProfile(config: DisplayConfig, registry: Map<string, DisplayProfile>): {
248
253
  profile: DisplayProfile;
@@ -261,5 +266,22 @@ export interface TouchAdapterCodegen {
261
266
  /** C++ static inline shim functions: touch_init, touch_isTouched, touch_readRaw. */
262
267
  functions: string;
263
268
  }
264
- /** Generate C++ code for a built-in touch library adapter. */
265
- export declare function generateTouchAdapter(touch: TouchProfile): TouchAdapterCodegen;
269
+ /** Generate C++ code for a built-in touch library adapter.
270
+ *
271
+ * Strategy-owned touch adapters take precedence: when the strategy's
272
+ * `providesTouchAdapter()` returns true and `resolveTouchAdapter` returns
273
+ * non-null, that codegen wins. The Arduino-ecosystem libraries
274
+ * (XPT2046_Touchscreen, Adafruit_TouchScreen, Adafruit_STMPE610, FT6336U)
275
+ * are strategy-owned — they live in @typecad/framework-arduino
276
+ * (src/displays/touch-adapters-codegen.ts) and ArduinoStrategy dispatches to
277
+ * them. Cuttlefish keeps only the framework-agnostic `sdl` path here.
278
+ *
279
+ * Passing `undefined` for the strategy (or a strategy whose
280
+ * resolveTouchAdapter returns undefined for the given library) falls through
281
+ * to the `sdl` branch below; any other library without a strategy-provided
282
+ * adapter throws.
283
+ */
284
+ export declare function generateTouchAdapter(touch: TouchProfile, strategy?: {
285
+ providesTouchAdapter?(): boolean;
286
+ resolveTouchAdapter?(touch: TouchProfile): TouchAdapterCodegen | undefined;
287
+ }): TouchAdapterCodegen;