1a654da3e9
build / build (push) Successful in 30s
shows the daily tarot/astrology reading on-device: persistence, reading computation, and UI screens, driven by the existing engine/interpreter code linked in unchanged where possible. Required engine-side changes to make that linking work: - A compact low-precision ephemeris (lowprec_ephemeris.c) replacing the vendored ~127KB Astronomy Engine, which doesn't fit the watch's ~64KB app budget. - Hand-rolled sqrt/atan2/sin/cos replacements for that ephemeris and astro.c's Ascendant calculation - Pebble's statically-linked libm hard-faults on real hardware under this app's -fPIE link for all four. - narrative.c/guidance.c refactored from FILE*/fprintf onto snprintf- based buffers, since Pebble's SDK blocks fprintf at compile time.
74 lines
3.8 KiB
C
74 lines
3.8 KiB
C
#ifndef DECK_GUIDANCE_H
|
|
#define DECK_GUIDANCE_H
|
|
|
|
#include <stddef.h>
|
|
|
|
/* Header-only dependency on the engine for struct/enum *definitions*,
|
|
* same policy as narrative.h/significance.h - see their comments for
|
|
* why. Unlike those, though, the root Makefile *does* link
|
|
* engine/src/tarot_data.c's *implementation* (tarot_card_name()/
|
|
* tarot_card_meaning()) into the interpreter binary - a deliberate,
|
|
* narrow exception; see the Makefile's own comment on
|
|
* INTERP_TAROT_TEXT_OBJS for why that doesn't compromise this module's
|
|
* independent testability. */
|
|
#include "../../engine/src/tarot.h"
|
|
#include "significance.h"
|
|
|
|
/* Generous upper bound on guidance_write()'s output (intro/stance line
|
|
* + Attitude line + Outcome line, each ending in a newline, including
|
|
* the longest tarot_card_meaning() strings) across every language this
|
|
* project ships a translation for - see narrative.h's NARRATIVE_TEXT_MAX
|
|
* for the same reasoning. */
|
|
#define GUIDANCE_TEXT_MAX 1024
|
|
|
|
/* Ties the day's single most significant transit
|
|
* (interp->top_items[0]) to the Celtic Cross spread, and prints a short
|
|
* paragraph of concrete guidance on how to meet the day - the "combined
|
|
* storytelling" piece docs/reading.md flags as future work, now built.
|
|
* Prints on every day, quiet or major, tailored to interp->day_level -
|
|
* callers can invoke it unconditionally after every
|
|
* interpret_daily_reading() call.
|
|
*
|
|
* The core guidance keys off two things: the character of the top
|
|
* transit's aspect (harmonious/discordant/neutral, same classification
|
|
* narrative.c uses) and whether the spread's Attitude position - Waite's
|
|
* "Himself: his position or attitude in the circumstances", the
|
|
* position most directly about how the reader is meeting the day - fell
|
|
* upright or reversed. That crossing (3 x 2 = 6 combinations) is
|
|
* original text written for this project, not drawn from Waite or
|
|
* Sepharial, since neither source discusses combining astrology and
|
|
* tarot; it stays valid regardless of the day's intensity. What *does*
|
|
* vary with interp->day_level is only the sentence introducing the top
|
|
* transit (e.g. "With Saturn as today's dominant influence" on a Major
|
|
* day vs. "Saturn is only faintly active today, but for what it's
|
|
* worth" on a Quiet one). A day with no aspects in orb at all
|
|
* (interp->top_item_count == 0, always DAY_QUIET) has no transiting
|
|
* planet to introduce, so it falls back to a stance keyed on the
|
|
* Attitude card's orientation alone.
|
|
*
|
|
* The paragraph also names the Attitude and Outcome cards and, via
|
|
* tarot_card_meaning(), states their actual Waite meaning for the
|
|
* orientation they landed in (e.g. what Wheel of Fortune reversed
|
|
* means) - not a duplicated table, the real thing, since tarot_data.c
|
|
* is linked (see above).
|
|
*
|
|
* Every piece of this module's own text (stance/intro/no-transit/label
|
|
* strings) is looked up via i18n_get() under "guidance.*" keys
|
|
* (engine/i18n's .lang files) before falling back to the English text baked
|
|
* into guidance.c, so it respects whatever --lang the caller loaded
|
|
* with i18n_load()/i18n_load_table() (main.c does so before calling
|
|
* this). The German guidance.intro.* templates are deliberately phrased
|
|
* so the planet name placeholder is always the sentence's grammatical
|
|
* subject (nominative case) across all four day levels - see
|
|
* guidance.c's own comment on k_intro_fallback.
|
|
*
|
|
* Writes into `buf` (a caller-supplied buffer of `buf_size` bytes,
|
|
* always left null-terminated - GUIDANCE_TEXT_MAX is a safe size)
|
|
* instead of a FILE*, using only snprintf() internally (never
|
|
* fprintf/sprintf/vsnprintf, all of which Pebble's SDK blocks at compile
|
|
* time), so this function links into the watch app unchanged. */
|
|
void guidance_write(char *buf, size_t buf_size, const char *indent, const DailyInterpretation *interp,
|
|
const CelticCrossSpread *spread);
|
|
|
|
#endif
|