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.
127 lines
3.5 KiB
C
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
|