Files
deck_in_a_dash/engine/src/astro.h
T
ml 1a654da3e9
build / build (push) Successful in 30s
Introduces watch/, a real Pebble watchapp (built via pebble build) that
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.
2026-07-14 17:10:22 +02:00

127 lines
3.5 KiB
C

#ifndef DECK_ASTRO_H
#define DECK_ASTRO_H
/* Pebble's SDK pre-defines <time.h>'s own include guard (so a real
* #include <time.h> is a silent no-op) and instead declares struct
* tm/time_t/gmtime()/etc. itself, inside pebble.h - see PBL_SDK_3,
* predefined by the Pebble build for every target platform. Desktop
* builds (deck-engine, the interpreter, and this file's own tests) use
* plain <time.h> as normal. */
#ifdef PBL_SDK_3
#include <pebble.h>
#else
#include <time.h>
#endif
#define NUM_BODIES 10
#define MAX_ASPECTS 100
/* Named distinctly from Astronomy Engine's own astro_body_t constants
* (BODY_SUN, BODY_MOON, ...) to avoid colliding with them in astro.c,
* which includes both headers. */
typedef enum {
PLANET_SUN = 0,
PLANET_MOON,
PLANET_MERCURY,
PLANET_VENUS,
PLANET_MARS,
PLANET_JUPITER,
PLANET_SATURN,
PLANET_URANUS,
PLANET_NEPTUNE,
PLANET_PLUTO
} Body;
typedef enum {
SIGN_ARIES = 0,
SIGN_TAURUS,
SIGN_GEMINI,
SIGN_CANCER,
SIGN_LEO,
SIGN_VIRGO,
SIGN_LIBRA,
SIGN_SCORPIO,
SIGN_SAGITTARIUS,
SIGN_CAPRICORN,
SIGN_AQUARIUS,
SIGN_PISCES
} ZodiacSign;
typedef enum {
MOON_NEW = 0,
MOON_WAXING_CRESCENT,
MOON_FIRST_QUARTER,
MOON_WAXING_GIBBOUS,
MOON_FULL,
MOON_WANING_GIBBOUS,
MOON_LAST_QUARTER,
MOON_WANING_CRESCENT
} MoonPhaseName;
typedef enum {
ASPECT_CONJUNCTION = 0,
ASPECT_SEXTILE,
ASPECT_SQUARE,
ASPECT_TRINE,
ASPECT_OPPOSITION
} AspectType;
typedef struct {
double ecliptic_longitude; /* geocentric, degrees, [0, 360) */
ZodiacSign sign;
double degree_in_sign; /* [0, 30) */
int house; /* 1-12, whole-sign, always relative to the natal Ascendant -
* for DailyTransits.bodies this places today's transiting
* planets in the natal chart's own houses (the standard,
* personalized way to read transits), not a fresh "houses
* for right now" chart. */
} PlanetPosition;
typedef struct {
int year, month, day; /* birth date, local calendar */
int hour, minute; /* birth time, local clock */
double utc_offset_hours; /* local time = UTC + utc_offset_hours */
double latitude; /* degrees north positive */
double longitude; /* degrees east positive */
} BirthData;
typedef struct {
PlanetPosition bodies[NUM_BODIES];
double ascendant_longitude;
ZodiacSign houses[12]; /* houses[0] = sign of house 1 (whole-sign system) */
} NatalChart;
typedef struct {
Body transiting_planet;
Body natal_planet;
AspectType type;
double orb; /* how many degrees off exact, always >= 0 */
} Aspect;
typedef struct {
PlanetPosition bodies[NUM_BODIES];
MoonPhaseName moon_phase;
Aspect aspects[MAX_ASPECTS];
int aspect_count;
} DailyTransits;
void astro_compute_natal_chart(const BirthData *birth, NatalChart *out);
void astro_compute_daily_transits(time_t utc_moment, const NatalChart *natal,
DailyTransits *out);
const char *astro_body_name(Body body);
const char *astro_sign_name(ZodiacSign sign);
const char *astro_moon_phase_name(MoonPhaseName phase);
const char *astro_aspect_name(AspectType type);
/* Stable, language-independent identifiers (e.g. "sun", "waxing_crescent",
* "square") - the same strings i18n.c's lookup keys are built from. Used
* for machine-readable output (reading_print_json) that must stay
* identical regardless of --lang, unlike astro_*_name() above. */
const char *astro_body_slug(Body body);
const char *astro_sign_slug(ZodiacSign sign);
const char *astro_moon_phase_slug(MoonPhaseName phase);
const char *astro_aspect_slug(AspectType type);
#endif