Add core engine: tarot + astrology reading generator with CLI and i18n

Plain-C, dependency-free engine that produces a personalized daily
Celtic Cross tarot spread and natal-chart/transit astrology reading,
plus a standalone CLI (dist/deck-engine) and run.sh wrapper. Includes
English/German output via a simple key=value translation format, and
docs/diagrams describing the architecture and I/O.
This commit is contained in:
ml
2026-07-04 06:49:18 +02:00
commit e4ea31270f
59 changed files with 17134 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
CC ?= cc
CFLAGS ?= -std=c99 -Wall -Wextra -O2
LDLIBS := -lm
SRC_DIR := src
THIRD_PARTY := third_party/astronomy/astronomy.c
TEST_DIR := tests
BUILD_DIR := build
OBJ_DIR := $(BUILD_DIR)/obj
# Final build output lives in dist/, next to (not inside) engine/ and res/.
DIST_DIR := ../dist
DIST_IMG_DIR := $(DIST_DIR)/img
DIST_I18N_DIR := $(DIST_DIR)/i18n
RES_IMG_DIR := ../res/img
I18N_DIR := i18n
SCRIPTS_DIR := scripts
# Engine logic shared by the CLI and the test binary (no main()).
ENGINE_SRCS := $(SRC_DIR)/rng.c $(SRC_DIR)/tarot.c $(SRC_DIR)/tarot_data.c \
$(SRC_DIR)/astro.c $(SRC_DIR)/reading.c $(SRC_DIR)/i18n.c $(THIRD_PARTY)
ENGINE_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ENGINE_SRCS))
MAIN_OBJ := $(OBJ_DIR)/$(SRC_DIR)/main.o
TEST_OBJ := $(OBJ_DIR)/$(TEST_DIR)/smoke_test.o
BINARY := $(DIST_DIR)/deck-engine
TEST_BINARY := $(BUILD_DIR)/smoke_test
.PHONY: all test clean images scripts i18n
all: $(BINARY) images scripts i18n
$(BINARY): $(ENGINE_OBJS) $(MAIN_OBJ)
@mkdir -p $(DIST_DIR)
$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)
# The HTML report expects card art at img/<file> next to the binary, so
# every build refreshes a copy alongside it (cheap: 22 small JPEGs).
images:
@mkdir -p $(DIST_IMG_DIR)
cp $(RES_IMG_DIR)/*.jpeg $(DIST_IMG_DIR)/
# The CLI expects translation files at i18n/<lang>.lang next to the
# binary (default --i18n-dir), so every build refreshes a copy alongside
# it, same as images/. Add a new language by dropping another <code>.lang
# file into engine/i18n/ - no code or Makefile change needed.
i18n:
@mkdir -p $(DIST_I18N_DIR)
cp $(I18N_DIR)/*.lang $(DIST_I18N_DIR)/
# run.sh is refreshed every build. user.properties is only seeded once
# (from the placeholder template) so a rebuild never clobbers the user's
# own filled-in birth data.
scripts:
@mkdir -p $(DIST_DIR)
cp $(SCRIPTS_DIR)/run.sh $(DIST_DIR)/run.sh
chmod +x $(DIST_DIR)/run.sh
test -f $(DIST_DIR)/user.properties || \
cp $(SCRIPTS_DIR)/user.properties.template $(DIST_DIR)/user.properties
test: $(TEST_BINARY)
./$(TEST_BINARY)
$(TEST_BINARY): $(ENGINE_OBJS) $(TEST_OBJ)
$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)
$(OBJ_DIR)/%.o: %.c
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -rf $(BUILD_DIR) $(BINARY) $(DIST_IMG_DIR) $(DIST_I18N_DIR) $(DIST_DIR)/run.sh
# user.properties holds the user's own data - never removed by clean.