]> git.earman.xyz Git - sensor-watch.git/commitdiff
tarot: add full tarot deck as an option
authorJeremy O'Brien <neutral@fastmail.com>
Fri, 13 Jan 2023 02:49:04 +0000 (21:49 -0500)
committerJeremy O'Brien <neutral@fastmail.com>
Fri, 13 Jan 2023 03:33:01 +0000 (22:33 -0500)
movement/watch_faces/complication/tarot_face.c
movement/watch_faces/complication/tarot_face.h

index e583763c36f51ae6ae4c2e55eeae1da7f6d97c8d..04fcddef6efe1c012eac9bd5f91b6996367bbef8 100644 (file)
@@ -65,9 +65,19 @@ static char *major_arcana[] = {
     "Jdgmnt",
     " World",
 };
-#define NUM_TAROT_CARDS (sizeof(major_arcana) / sizeof(*major_arcana))
+#define NUM_MAJOR_ARCANA (sizeof(major_arcana) / sizeof(*major_arcana))
 
-#define WORLD_CARD_INDEX (NUM_TAROT_CARDS - 1)
+static char *suits[] = {
+    " wands",
+    "  cups",
+    "swords",
+    " coins",
+};
+
+#define NUM_MINOR_ARCANA 56
+#define NUM_CARDS_PER_SUIT 14
+
+#define NUM_TAROT_CARDS (NUM_MAJOR_ARCANA + NUM_MINOR_ARCANA)
 
 static void init_deck(tarot_state_t *state) {
     memset(state->drawn_cards, 0xff, sizeof(state->drawn_cards));
@@ -75,28 +85,58 @@ static void init_deck(tarot_state_t *state) {
 }
 
 static void tarot_display(tarot_state_t *state) {
-    char buf[10];
+    char buf[12];
     uint8_t card;
     bool flipped;
 
+    // deck is initialized; show current draw mode and return
     if (state->drawn_cards[0] == 0xff) {
-        /* deck is initialized; show current draw mode */
         watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
-        sprintf(buf, "%2d draWW", state->num_cards_to_draw);
-        watch_display_string(buf, 2);
-        watch_clear_pixel(2, 3);
-        watch_clear_pixel(1, 4);
+        if (state->major_arcana_only) {
+            sprintf(buf, "TA%2dn&ajor", state->num_cards_to_draw);
+        } else {
+            sprintf(buf, "TA%2d   All", state->num_cards_to_draw);
+        }
+        watch_display_string(buf, 0);
         return;
     }
 
-    sprintf(buf, "%2d", state->current_card + 1);
-    watch_display_string(buf, 2);
+    // show a special status if we're looking at the first or last card in the spread
+    if (state->current_card == 0) {
+        sprintf(buf, "St");
+    } else if (state->current_card == state->num_cards_to_draw - 1) {
+        sprintf(buf, "En");
+    } else {
+        sprintf(buf, "  ");
+    }
+    watch_display_string(buf, 0);
 
+    // now display the actual card
     card = state->drawn_cards[state->current_card];
     flipped = (card & FLIPPED_MASK) ? true : false; // check flipped bit
     card &= ~FLIPPED_MASK; // remove the flipped bit
-    sprintf(buf, "%s", major_arcana[card]);
-    watch_display_string(buf, 4);
+    if (card < NUM_MAJOR_ARCANA) {
+        // major arcana
+        // make sure we're not showing a rank
+        watch_display_string("  ", 2);
+
+        // card name
+        sprintf(buf, "%s", major_arcana[card]);
+        watch_display_string(buf, 4);
+    } else {
+        // minor arcana
+        uint8_t suit = (card - NUM_MAJOR_ARCANA) / NUM_CARDS_PER_SUIT;
+        uint8_t num = ((card - NUM_MAJOR_ARCANA) % NUM_CARDS_PER_SUIT) + 1;
+
+        // show rank
+        sprintf(buf, "%2d", num);
+        watch_display_string(buf, 2);
+
+        // suit
+        sprintf(buf, "%s", suits[suit]);
+        watch_display_string(buf, 4);
+    }
+
     if (flipped) {
         watch_set_indicator(WATCH_INDICATOR_SIGNAL);
     } else {
@@ -113,8 +153,12 @@ static uint8_t get_rand_num(uint8_t num_values) {
 #endif
 }
 
-static uint8_t draw_one_card(void) {
-    return get_rand_num(NUM_TAROT_CARDS);
+static uint8_t draw_one_card(tarot_state_t *state) {
+    if (state->major_arcana_only) {
+        return get_rand_num(NUM_MAJOR_ARCANA);
+    } else {
+        return get_rand_num(NUM_TAROT_CARDS);
+    }
 }
 
 static bool already_drawn(tarot_state_t *state, uint8_t drawn_card) {
@@ -131,9 +175,9 @@ static void pick_cards(tarot_state_t *state) {
     uint8_t card;
 
     for (int i = 0; i < state->num_cards_to_draw; i++) {
-        card = draw_one_card();
+        card = draw_one_card(state);
         while (already_drawn(state, card)) {
-            card = draw_one_card();
+            card = draw_one_card(state);
         }
         card |= get_rand_num(2) << FLIPPED_BIT_POS; // randomly flip the card
         state->drawn_cards[i] = card;
@@ -192,6 +236,7 @@ void tarot_face_activate(movement_settings_t *settings, void *context) {
     watch_display_string("TA", 0);
     init_deck(state);
     state->num_cards_to_draw = 3;
+    state->major_arcana_only = true;
 }
 
 bool tarot_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
@@ -226,7 +271,13 @@ bool tarot_face_loop(movement_event_t event, movement_settings_t *settings, void
             tarot_display(state);
             break;
         case EVENT_LIGHT_LONG_PRESS:
-            init_deck(state);
+            if (state->drawn_cards[0] == 0xff) {
+                // at main screen; cycle major arcana mode
+                state->major_arcana_only = !state->major_arcana_only;
+            } else {
+                // at card view screen; go back to draw screen
+                init_deck(state);
+            }
             tarot_display(state);
             break;
         case EVENT_ALARM_BUTTON_UP:
index 3de5d0199126a9c6cc2342086dac2efd962540f1..00d08ff14eea6c450ba561cfaffe5a8781302e5d 100644 (file)
 /*
  * Tarot card watch face
  *
- * Draw from a deck of the 22 major arcana tarot cards.
+ * Draw from a deck of tarot cards. Can choose between major arcana only or
+ * entire deck.
  *
  * In tarot reading, a card orientation can be upright or inverted, and the
  * interpertation of the card can change depending on this state. This face
  * lights the alarm indicator to show when a card is inverted. Just ignore it
  * if you prefer not to deal with card inversions.
  *
- * When "Draw" is shown:
+ * This face uses the terms "Wands", "Cups", "Swords" and "Coins" for the four
+ * suits, and numbers to represent the 14 ranked cards, with the cards 11-14
+ * representing the Page, the Knight, the Queen, and King respectively.
+ *
+ * Default draw is a 3-card major arcana spread.
+ *
+ * To make it easier to keep track of where you are in the list of drawn cards,
+ * after drawing, "St" is shown for the 1st card in the spread and "En" is
+ * shown for the last card.
+ *
+ * When "Major" or "All" is shown:
  * - Light button: cycle # of cards to draw
+ * - Light button (long press): toggle between major arcana and all cards
  * - Alarm button: shuffle deck and draw cards
  *
  * After cards are drawn/showing:
  * - Light button: view the next drawn card
  * - Alarm button: shuffle and re-draw new cards
- * - Light button (long press): go back to Draw screen,
- *   for choosing different # of cards to draw.
+ * - Light button (long press): go back to Draw screen, for choosing different draw parameters.
  */
 
 #define MAX_CARDS_TO_DRAW 10
@@ -55,6 +66,7 @@ typedef struct {
     uint8_t current_card;
     uint8_t animation_frame;
     uint8_t num_cards_to_draw;
+    bool major_arcana_only;
     bool is_picking;
 } tarot_state_t;