Introduces watch/, a real Pebble watchapp (built via pebble build) that
build / build (push) Successful in 30s
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.
This commit is contained in:
+25
-20
@@ -1,5 +1,3 @@
|
||||
#define _POSIX_C_SOURCE 200809L /* for open_memstream */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -156,27 +154,28 @@ static void print_body_in_sign_text(FILE *out, const PlanetPosition *pos) {
|
||||
fprintf(out, " %s", buf);
|
||||
}
|
||||
|
||||
/* Captures narrative_print()/guidance_print()'s output (they only know
|
||||
* how to write to a FILE*) into a heap string, for embedding into JSON -
|
||||
* avoids changing either module's public API just for this one caller.
|
||||
* Strips a single trailing newline; caller must free() the result. */
|
||||
/* Captures narrative_write()/guidance_write()'s output into a heap
|
||||
* string, for embedding into JSON - a stack buffer plus a single
|
||||
* malloc()+memcpy() copy, since main.c doesn't need to stream this
|
||||
* anywhere. Strips a single trailing newline; caller must free() the
|
||||
* result. */
|
||||
static char *capture_narrative(const Aspect *aspect, int house) {
|
||||
char *buf = NULL;
|
||||
size_t size = 0;
|
||||
FILE *mem = open_memstream(&buf, &size);
|
||||
narrative_print(mem, "", aspect, house);
|
||||
fclose(mem);
|
||||
if (size > 0 && buf[size - 1] == '\n') buf[size - 1] = '\0';
|
||||
char stack_buf[NARRATIVE_TEXT_MAX];
|
||||
narrative_write(stack_buf, sizeof stack_buf, "", aspect, house);
|
||||
size_t len = strlen(stack_buf);
|
||||
if (len > 0 && stack_buf[len - 1] == '\n') stack_buf[--len] = '\0';
|
||||
char *buf = malloc(len + 1);
|
||||
memcpy(buf, stack_buf, len + 1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char *capture_guidance(const DailyInterpretation *interp, const CelticCrossSpread *spread) {
|
||||
char *buf = NULL;
|
||||
size_t size = 0;
|
||||
FILE *mem = open_memstream(&buf, &size);
|
||||
guidance_print(mem, "", interp, spread);
|
||||
fclose(mem);
|
||||
if (size > 0 && buf[size - 1] == '\n') buf[size - 1] = '\0';
|
||||
char stack_buf[GUIDANCE_TEXT_MAX];
|
||||
guidance_write(stack_buf, sizeof stack_buf, "", interp, spread);
|
||||
size_t len = strlen(stack_buf);
|
||||
if (len > 0 && stack_buf[len - 1] == '\n') stack_buf[--len] = '\0';
|
||||
char *buf = malloc(len + 1);
|
||||
memcpy(buf, stack_buf, len + 1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -228,7 +227,11 @@ static void interp_print_text(FILE *out, const DailyReading *reading, const Dail
|
||||
print_body_in_sign_text(out, &reading->natal.bodies[a->natal_planet]);
|
||||
fprintf(out, " (%s %.1f\xc2\xb0, %s %.2f)\n", ui("ui.orb", "orb"), a->orb,
|
||||
ui("interp.score", "score"), item->score);
|
||||
narrative_print(out, " ", a, reading->transits.bodies[a->transiting_planet].house);
|
||||
|
||||
char narrative_buf[NARRATIVE_TEXT_MAX];
|
||||
narrative_write(narrative_buf, sizeof narrative_buf, " ", a,
|
||||
reading->transits.bodies[a->transiting_planet].house);
|
||||
fputs(narrative_buf, out);
|
||||
}
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
@@ -236,7 +239,9 @@ static void interp_print_text(FILE *out, const DailyReading *reading, const Dail
|
||||
print_celtic_cross_text(out, &reading->spread);
|
||||
fprintf(out, "\n");
|
||||
|
||||
guidance_print(out, "", interp, &reading->spread);
|
||||
char guidance_buf[GUIDANCE_TEXT_MAX];
|
||||
guidance_write(guidance_buf, sizeof guidance_buf, "", interp, &reading->spread);
|
||||
fputs(guidance_buf, out);
|
||||
}
|
||||
|
||||
/* ===== --format html ===== */
|
||||
|
||||
Reference in New Issue
Block a user