From b94c55e5b54f0ac26fb624e51a2ee700357b65e6 Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sat, 22 Nov 2025 14:28:36 -0500 Subject: [PATCH 01/13] first commit --- movement_faces.h | 1 + watch-faces.mk | 1 + .../complication/tcg_life_counter_face.c | 114 ++++++++++++++++++ .../complication/tcg_life_counter_face.h | 68 +++++++++++ 4 files changed, 184 insertions(+) create mode 100644 watch-faces/complication/tcg_life_counter_face.c create mode 100644 watch-faces/complication/tcg_life_counter_face.h diff --git a/movement_faces.h b/movement_faces.h index eef0e3acd..2b08a11f4 100644 --- a/movement_faces.h +++ b/movement_faces.h @@ -78,4 +78,5 @@ #include "higher_lower_game_face.h" #include "lander_face.h" #include "simon_face.h" +#include "tcg_life_counter_face.h" // New includes go above this line. diff --git a/watch-faces.mk b/watch-faces.mk index 3c4249237..a9a9e2733 100644 --- a/watch-faces.mk +++ b/watch-faces.mk @@ -53,4 +53,5 @@ SRCS += \ ./watch-faces/complication/higher_lower_game_face.c \ ./watch-faces/complication/lander_face.c \ ./watch-faces/complication/simon_face.c \ + ./watch-faces/complication/tcg_life_counter_face.c \ # New watch faces go above this line. diff --git a/watch-faces/complication/tcg_life_counter_face.c b/watch-faces/complication/tcg_life_counter_face.c new file mode 100644 index 000000000..8ad119cfb --- /dev/null +++ b/watch-faces/complication/tcg_life_counter_face.c @@ -0,0 +1,114 @@ +/* + * MIT License + * + * Copyright (c) 2025 Mark Schlosser + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include "tcg_life_counter_face.h" + +void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr) { + (void) watch_face_index; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(tcg_life_counter_state_t)); + memset(*context_ptr, 0, sizeof(tcg_life_counter_state_t)); + tcg_life_counter_state_t *state = (tcg_life_counter_state_t *)*context_ptr; + for (size_t i = 0; i < TCG_LIFE_COUNTER_NUM_LIFE_VALUES; i++) + state->life_values[i] = TCG_LIFE_COUNTER_DEFAULT_LIFE_VALUE; + state->increment_mode_on = false; + } +} + +void tcg_life_counter_face_activate(void *context) { + tcg_life_counter_state_t *state = (tcg_life_counter_state_t *)context; + watch_set_pixel(1, 16); // set colon indicator +} + +bool tcg_life_counter_face_loop(movement_event_t event, void *context) { + + tcg_life_counter_state_t *state = (tcg_life_counter_state_t *)context; + + switch (event.event_type) { + case EVENT_LIGHT_BUTTON_DOWN: + break; + case EVENT_LIGHT_BUTTON_UP: + if (!state->increment_mode_on) { + if (state->life_values[0] > 0) { + state->life_values[0]--; // decrement counter index 0 + } + } else { + if (state->life_values[0] < 99) { + state->life_values[0]++; // increment counter index 0 + } + } + print_tcg_life_counter(state); + break; + case EVENT_LIGHT_LONG_PRESS: + state->increment_mode_on = !state->increment_mode_on; + print_tcg_life_counter(state); + case EVENT_ALARM_BUTTON_DOWN: + break; + case EVENT_ALARM_BUTTON_UP: + if (!state->increment_mode_on) { + if (state->life_values[1] > 0) { + state->life_values[1]--; // decrement counter index 1 + } + } else { + if (state->life_values[1] < 99) { + state->life_values[1]++; // increment counter index 1 + } + } + print_tcg_life_counter(state); + break; + case EVENT_ALARM_LONG_PRESS: + // reset all life counters + for (size_t i = 0; i < TCG_LIFE_COUNTER_NUM_LIFE_VALUES; i++) + state->life_values[i] = TCG_LIFE_COUNTER_DEFAULT_LIFE_VALUE; + state->increment_mode_on = false; + print_tcg_life_counter(state); + break; + case EVENT_ACTIVATE: + print_tcg_life_counter(state); + break; + case EVENT_TIMEOUT: + // ignore timeout + break; + default: + movement_default_loop_handler(event); + break; + } + + return true; +} + +void print_tcg_life_counter(tcg_life_counter_state_t *state) { + char buf[14]; + watch_display_text(WATCH_POSITION_TOP, "TC"); + watch_display_text(WATCH_POSITION_TOP_RIGHT, state->increment_mode_on ? " I" : " d"); + sprintf(buf, "%02d%02d", state->life_values[0], state->life_values[1]); + watch_display_text(WATCH_POSITION_BOTTOM, buf); + +} + +void tcg_life_counter_face_resign(void *context) { + (void) context; +} diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h new file mode 100644 index 000000000..a71e7fd2a --- /dev/null +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -0,0 +1,68 @@ +/* + * MIT License + * + * Copyright (c) 2025 Mark Schlosser + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef TCG_LIFE_COUNTER_FACE_H_ +#define TCG_LIFE_COUNTER_FACE_H_ + +/* + * TCG_LIFE_COUNTER face + * + * TCG Life Counter face is designed to track player life totals in a two-player trading card game. Two life totals will be displayed on the screen, separated by a colon. The left counter is controlled by short-pressing LIGHT. The right counter is controlled by short-pressing ALARM. + * Life counters each begin at twenty and the face begins in decrement mode. This means the associated player's life total will decrement by a value of one each time LIGHT or ALARM is pressed. Once the face is changed to increment mode, the associated player's life total will increase by one each time LIGHT or ALARM is pressed. + * + * Usage: + * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Caps at 0 and 99. + * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Caps at 0 and 99. + * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "I" character in the top right of LCD. + * Long-press ALARM to reset mode to decrement mode and both life counters to twenty. + */ + +#include "movement.h" + +#define TCG_LIFE_COUNTER_NUM_LIFE_VALUES 2 +#define TCG_LIFE_COUNTER_DEFAULT_LIFE_VALUE 20 + +typedef struct { + uint8_t life_values[2]; + bool increment_mode_on; +} tcg_life_counter_state_t; + + +void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr); +void tcg_life_counter_face_activate(void *context); +bool tcg_life_counter_face_loop(movement_event_t event, void *context); +void tcg_life_counter_face_resign(void *context); + +void print_tcg_life_counter(tcg_life_counter_state_t *state); +void beep_tcg_life_counter(tcg_life_counter_state_t *state); + +#define tcg_life_counter_face ((const watch_face_t){ \ + tcg_life_counter_face_setup, \ + tcg_life_counter_face_activate, \ + tcg_life_counter_face_loop, \ + tcg_life_counter_face_resign, \ + NULL, \ +}) + +#endif // TCG_LIFE_COUNTER_FACE_H_ From de6ca5368867a14c94715bb29c1970e6091c8415 Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sat, 22 Nov 2025 14:48:30 -0500 Subject: [PATCH 02/13] removed unused prototype and clarify comment. --- watch-faces/complication/tcg_life_counter_face.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index a71e7fd2a..87cdd0a00 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -32,8 +32,8 @@ * Life counters each begin at twenty and the face begins in decrement mode. This means the associated player's life total will decrement by a value of one each time LIGHT or ALARM is pressed. Once the face is changed to increment mode, the associated player's life total will increase by one each time LIGHT or ALARM is pressed. * * Usage: - * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Caps at 0 and 99. - * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Caps at 0 and 99. + * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to 0-99. + * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to 0-99. * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "I" character in the top right of LCD. * Long-press ALARM to reset mode to decrement mode and both life counters to twenty. */ @@ -48,14 +48,12 @@ typedef struct { bool increment_mode_on; } tcg_life_counter_state_t; - void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr); void tcg_life_counter_face_activate(void *context); bool tcg_life_counter_face_loop(movement_event_t event, void *context); void tcg_life_counter_face_resign(void *context); void print_tcg_life_counter(tcg_life_counter_state_t *state); -void beep_tcg_life_counter(tcg_life_counter_state_t *state); #define tcg_life_counter_face ((const watch_face_t){ \ tcg_life_counter_face_setup, \ From 6294655ca17e45b8c749d8c57d7764470fd3f679 Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sat, 22 Nov 2025 19:26:04 -0500 Subject: [PATCH 03/13] 999 max --- watch-faces/complication/tcg_life_counter_face.c | 8 ++++---- watch-faces/complication/tcg_life_counter_face.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/watch-faces/complication/tcg_life_counter_face.c b/watch-faces/complication/tcg_life_counter_face.c index 8ad119cfb..1ac66000c 100644 --- a/watch-faces/complication/tcg_life_counter_face.c +++ b/watch-faces/complication/tcg_life_counter_face.c @@ -40,7 +40,7 @@ void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr) void tcg_life_counter_face_activate(void *context) { tcg_life_counter_state_t *state = (tcg_life_counter_state_t *)context; - watch_set_pixel(1, 16); // set colon indicator + // watch_set_pixel(1, 16); // set colon indicator } bool tcg_life_counter_face_loop(movement_event_t event, void *context) { @@ -56,7 +56,7 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { state->life_values[0]--; // decrement counter index 0 } } else { - if (state->life_values[0] < 99) { + if (state->life_values[0] < 999) { state->life_values[0]++; // increment counter index 0 } } @@ -73,7 +73,7 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { state->life_values[1]--; // decrement counter index 1 } } else { - if (state->life_values[1] < 99) { + if (state->life_values[1] < 999) { state->life_values[1]++; // increment counter index 1 } } @@ -104,7 +104,7 @@ void print_tcg_life_counter(tcg_life_counter_state_t *state) { char buf[14]; watch_display_text(WATCH_POSITION_TOP, "TC"); watch_display_text(WATCH_POSITION_TOP_RIGHT, state->increment_mode_on ? " I" : " d"); - sprintf(buf, "%02d%02d", state->life_values[0], state->life_values[1]); + sprintf(buf, "%3d%3d", state->life_values[0], state->life_values[1]); watch_display_text(WATCH_POSITION_BOTTOM, buf); } diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index 87cdd0a00..d72846b06 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -32,8 +32,8 @@ * Life counters each begin at twenty and the face begins in decrement mode. This means the associated player's life total will decrement by a value of one each time LIGHT or ALARM is pressed. Once the face is changed to increment mode, the associated player's life total will increase by one each time LIGHT or ALARM is pressed. * * Usage: - * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to 0-99. - * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to 0-99. + * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to 0-999. + * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to 0-999. * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "I" character in the top right of LCD. * Long-press ALARM to reset mode to decrement mode and both life counters to twenty. */ @@ -44,7 +44,7 @@ #define TCG_LIFE_COUNTER_DEFAULT_LIFE_VALUE 20 typedef struct { - uint8_t life_values[2]; + uint16_t life_values[2]; bool increment_mode_on; } tcg_life_counter_state_t; From 4e62f5c010e2fb5a6c38f3453dc6cbc5197ab82d Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sat, 22 Nov 2025 19:48:15 -0500 Subject: [PATCH 04/13] use + and - to signify modes, not I and d --- watch-faces/complication/tcg_life_counter_face.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch-faces/complication/tcg_life_counter_face.c b/watch-faces/complication/tcg_life_counter_face.c index 1ac66000c..a17eb8059 100644 --- a/watch-faces/complication/tcg_life_counter_face.c +++ b/watch-faces/complication/tcg_life_counter_face.c @@ -103,7 +103,7 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { void print_tcg_life_counter(tcg_life_counter_state_t *state) { char buf[14]; watch_display_text(WATCH_POSITION_TOP, "TC"); - watch_display_text(WATCH_POSITION_TOP_RIGHT, state->increment_mode_on ? " I" : " d"); + watch_display_text(WATCH_POSITION_TOP_RIGHT, state->increment_mode_on ? " +" : " -"); sprintf(buf, "%3d%3d", state->life_values[0], state->life_values[1]); watch_display_text(WATCH_POSITION_BOTTOM, buf); From 173f7469e22947497d4521c7a98c229257e403d4 Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sat, 22 Nov 2025 20:24:36 -0500 Subject: [PATCH 05/13] advance through a series of default values, if desired --- .../complication/tcg_life_counter_face.c | 21 +++++++++++++++++-- .../complication/tcg_life_counter_face.h | 6 ++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/watch-faces/complication/tcg_life_counter_face.c b/watch-faces/complication/tcg_life_counter_face.c index a17eb8059..c0097bcb4 100644 --- a/watch-faces/complication/tcg_life_counter_face.c +++ b/watch-faces/complication/tcg_life_counter_face.c @@ -26,14 +26,23 @@ #include #include "tcg_life_counter_face.h" +#define TCG_LIFE_COUNTER_NUM_LIFE_VALUES 2 + +static const int16_t _tcg_life_counter_defaults[] = { + 20, + 40 +}; +#define TCG_LIFE_COUNTER_DEFAULT_SIZE() (sizeof(_tcg_life_counter_defaults) / sizeof(int16_t)) + void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr) { (void) watch_face_index; if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(tcg_life_counter_state_t)); memset(*context_ptr, 0, sizeof(tcg_life_counter_state_t)); tcg_life_counter_state_t *state = (tcg_life_counter_state_t *)*context_ptr; + state->default_idx = 0; for (size_t i = 0; i < TCG_LIFE_COUNTER_NUM_LIFE_VALUES; i++) - state->life_values[i] = TCG_LIFE_COUNTER_DEFAULT_LIFE_VALUE; + state->life_values[i] = _tcg_life_counter_defaults[state->default_idx]; state->increment_mode_on = false; } } @@ -80,9 +89,17 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { print_tcg_life_counter(state); break; case EVENT_ALARM_LONG_PRESS: + // possibly advance to next set of default values + if (_tcg_life_counter_defaults[state->default_idx] == state->life_values[0] && + _tcg_life_counter_defaults[state->default_idx] == state->life_values[1] && + false == state->increment_mode_on) { + state->default_idx++; + if (state->default_idx >= TCG_LIFE_COUNTER_DEFAULT_SIZE()) + state->default_idx = 0; + } // reset all life counters for (size_t i = 0; i < TCG_LIFE_COUNTER_NUM_LIFE_VALUES; i++) - state->life_values[i] = TCG_LIFE_COUNTER_DEFAULT_LIFE_VALUE; + state->life_values[i] = _tcg_life_counter_defaults[state->default_idx]; state->increment_mode_on = false; print_tcg_life_counter(state); break; diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index d72846b06..6ae7e8c5d 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -35,17 +35,15 @@ * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to 0-999. * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to 0-999. * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "I" character in the top right of LCD. - * Long-press ALARM to reset mode to decrement mode and both life counters to twenty. + * Long-press ALARM to reset mode to decrement mode and both life counters to current default value. If the life values displayed by the face are each equal to the current default life value, and the face is also set to decrement mode, this action will advance to the next set of default life values (currently twenty or forty). The initial default life value is configured to twenty. */ #include "movement.h" -#define TCG_LIFE_COUNTER_NUM_LIFE_VALUES 2 -#define TCG_LIFE_COUNTER_DEFAULT_LIFE_VALUE 20 - typedef struct { uint16_t life_values[2]; bool increment_mode_on; + uint8_t default_idx; } tcg_life_counter_state_t; void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr); From b147fea4981445f74ddb5a6f0e81a943125ac294 Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sat, 22 Nov 2025 20:28:35 -0500 Subject: [PATCH 06/13] correct comment --- watch-faces/complication/tcg_life_counter_face.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index 6ae7e8c5d..740265fec 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -28,7 +28,7 @@ /* * TCG_LIFE_COUNTER face * - * TCG Life Counter face is designed to track player life totals in a two-player trading card game. Two life totals will be displayed on the screen, separated by a colon. The left counter is controlled by short-pressing LIGHT. The right counter is controlled by short-pressing ALARM. + * TCG Life Counter face is designed to track player life totals in a two-player trading card game. Two life totals will be displayed on the screen. The left counter is controlled by short-pressing LIGHT. The right counter is controlled by short-pressing ALARM. * Life counters each begin at twenty and the face begins in decrement mode. This means the associated player's life total will decrement by a value of one each time LIGHT or ALARM is pressed. Once the face is changed to increment mode, the associated player's life total will increase by one each time LIGHT or ALARM is pressed. * * Usage: From 4defff04e06958d3cfe2ba70a63401b9fb4aca7e Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sun, 23 Nov 2025 15:13:12 -0500 Subject: [PATCH 07/13] incr/decr amounts, change reset --- .../complication/tcg_life_counter_face.c | 75 +++++++++++++++---- .../complication/tcg_life_counter_face.h | 8 +- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/watch-faces/complication/tcg_life_counter_face.c b/watch-faces/complication/tcg_life_counter_face.c index c0097bcb4..9687bfae4 100644 --- a/watch-faces/complication/tcg_life_counter_face.c +++ b/watch-faces/complication/tcg_life_counter_face.c @@ -34,6 +34,12 @@ static const int16_t _tcg_life_counter_defaults[] = { }; #define TCG_LIFE_COUNTER_DEFAULT_SIZE() (sizeof(_tcg_life_counter_defaults) / sizeof(int16_t)) +static const int8_t _tcg_life_counter_increment_amts[] = { + 1, + 5 +}; +#define TCG_LIFE_COUNTER_INCREMENT_AMTS_SIZE() (sizeof(_tcg_life_counter_increment_amts) / sizeof(int8_t)) + void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr) { (void) watch_face_index; if (*context_ptr == NULL) { @@ -44,12 +50,19 @@ void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr) for (size_t i = 0; i < TCG_LIFE_COUNTER_NUM_LIFE_VALUES; i++) state->life_values[i] = _tcg_life_counter_defaults[state->default_idx]; state->increment_mode_on = false; + state->increment_idx = 0; } } void tcg_life_counter_face_activate(void *context) { tcg_life_counter_state_t *state = (tcg_life_counter_state_t *)context; - // watch_set_pixel(1, 16); // set colon indicator +} + +static bool _tcg_life_counter_is_initial_default_values(tcg_life_counter_state_t *state) { + return (_tcg_life_counter_defaults[state->default_idx] == state->life_values[0] && + _tcg_life_counter_defaults[state->default_idx] == state->life_values[1] && + 0 == state->increment_idx && + false == state->increment_mode_on); } bool tcg_life_counter_face_loop(movement_event_t event, void *context) { @@ -62,11 +75,18 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { case EVENT_LIGHT_BUTTON_UP: if (!state->increment_mode_on) { if (state->life_values[0] > 0) { - state->life_values[0]--; // decrement counter index 0 + int16_t temp; + temp = (int16_t)state->life_values[0]; + temp -= _tcg_life_counter_increment_amts[state->increment_idx]; // decrement counter index 0 + if (temp < 0) + temp = 0; + state->life_values[0] = (uint16_t)temp; } } else { if (state->life_values[0] < 999) { - state->life_values[0]++; // increment counter index 0 + state->life_values[0] += _tcg_life_counter_increment_amts[state->increment_idx]; // increment counter index 0 + if (state->life_values[0] > 999) + state->life_values[0] = 999; } } print_tcg_life_counter(state); @@ -79,29 +99,51 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { case EVENT_ALARM_BUTTON_UP: if (!state->increment_mode_on) { if (state->life_values[1] > 0) { - state->life_values[1]--; // decrement counter index 1 + int16_t temp; + temp = (int16_t)state->life_values[1]; + temp -= _tcg_life_counter_increment_amts[state->increment_idx]; // decrement counter index 0 + if (temp < 0) + temp = 0; + state->life_values[1] = (uint16_t)temp; } } else { if (state->life_values[1] < 999) { - state->life_values[1]++; // increment counter index 1 + state->life_values[1] += _tcg_life_counter_increment_amts[state->increment_idx]; // increment counter index 1 + if (state->life_values[1] > 999) + state->life_values[1] = 999; } } print_tcg_life_counter(state); break; case EVENT_ALARM_LONG_PRESS: // possibly advance to next set of default values - if (_tcg_life_counter_defaults[state->default_idx] == state->life_values[0] && - _tcg_life_counter_defaults[state->default_idx] == state->life_values[1] && - false == state->increment_mode_on) { + if (_tcg_life_counter_is_initial_default_values(state)) { state->default_idx++; if (state->default_idx >= TCG_LIFE_COUNTER_DEFAULT_SIZE()) state->default_idx = 0; + // reset all life counters + for (size_t i = 0; i < TCG_LIFE_COUNTER_NUM_LIFE_VALUES; i++) + state->life_values[i] = _tcg_life_counter_defaults[state->default_idx]; + state->increment_mode_on = false; + state->increment_idx = 0; + } else { + state->increment_idx++; + if (state->increment_idx >= TCG_LIFE_COUNTER_INCREMENT_AMTS_SIZE()) + state->increment_idx = 0; + } + print_tcg_life_counter(state); + break; + case EVENT_MODE_LONG_PRESS: + if (_tcg_life_counter_is_initial_default_values(state)) { + movement_move_to_face(0); + } else { + // reset all life counters + for (size_t i = 0; i < TCG_LIFE_COUNTER_NUM_LIFE_VALUES; i++) + state->life_values[i] = _tcg_life_counter_defaults[state->default_idx]; + state->increment_mode_on = false; + state->increment_idx = 0; + print_tcg_life_counter(state); } - // reset all life counters - for (size_t i = 0; i < TCG_LIFE_COUNTER_NUM_LIFE_VALUES; i++) - state->life_values[i] = _tcg_life_counter_defaults[state->default_idx]; - state->increment_mode_on = false; - print_tcg_life_counter(state); break; case EVENT_ACTIVATE: print_tcg_life_counter(state); @@ -118,12 +160,13 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { } void print_tcg_life_counter(tcg_life_counter_state_t *state) { - char buf[14]; + char buf[7]; + char buf2[3]; watch_display_text(WATCH_POSITION_TOP, "TC"); - watch_display_text(WATCH_POSITION_TOP_RIGHT, state->increment_mode_on ? " +" : " -"); + sprintf(buf2, state->increment_mode_on ? "i%1d" : "d%1d", _tcg_life_counter_increment_amts[state->increment_idx]); + watch_display_text(WATCH_POSITION_TOP_RIGHT, buf2); sprintf(buf, "%3d%3d", state->life_values[0], state->life_values[1]); watch_display_text(WATCH_POSITION_BOTTOM, buf); - } void tcg_life_counter_face_resign(void *context) { diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index 740265fec..3520b1583 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -29,13 +29,14 @@ * TCG_LIFE_COUNTER face * * TCG Life Counter face is designed to track player life totals in a two-player trading card game. Two life totals will be displayed on the screen. The left counter is controlled by short-pressing LIGHT. The right counter is controlled by short-pressing ALARM. - * Life counters each begin at twenty and the face begins in decrement mode. This means the associated player's life total will decrement by a value of one each time LIGHT or ALARM is pressed. Once the face is changed to increment mode, the associated player's life total will increase by one each time LIGHT or ALARM is pressed. + * Life counters each begin at twenty and the face begins in decrement mode with a decrement value of one. This means the associated player's life total will decrement by a value of one each time LIGHT or ALARM is pressed. Once the face is changed to increment mode, the associated player's life total will increase by one each time LIGHT or ALARM is pressed. * * Usage: * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to 0-999. * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to 0-999. - * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "I" character in the top right of LCD. - * Long-press ALARM to reset mode to decrement mode and both life counters to current default value. If the life values displayed by the face are each equal to the current default life value, and the face is also set to decrement mode, this action will advance to the next set of default life values (currently twenty or forty). The initial default life value is configured to twenty. + * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "i" character in the top right of LCD. + * Long-press MODE to reset TCG life counter to decrement mode, decrement amount to 1, and both life counters to the current default value. If the life values displayed by the face are each equal to the current default life value and the face is also set to decrement mode with a decrement amount of 1, this action will instead return to the watch's first face. + * Long-press ALARM to advance to the next set of increment/decrement values (1 and 5). The initial increment/decrement value is configured to 1. If the life values displayed by the face are each equal to the current default life value and the face is also set to decrement mode with a decrement amount of 1, this action will instead advance to the next set of default life values (20 and 40). The initial default life value is configured to 20. */ #include "movement.h" @@ -44,6 +45,7 @@ typedef struct { uint16_t life_values[2]; bool increment_mode_on; uint8_t default_idx; + uint8_t increment_idx; } tcg_life_counter_state_t; void tcg_life_counter_face_setup(uint8_t watch_face_index, void ** context_ptr); From a25df4173d8ab272a8130bdd0a5d7e1777b9dc60 Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sun, 23 Nov 2025 15:17:38 -0500 Subject: [PATCH 08/13] comment --- watch-faces/complication/tcg_life_counter_face.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index 3520b1583..a59196b26 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -34,7 +34,7 @@ * Usage: * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to 0-999. * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to 0-999. - * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "i" character in the top right of LCD. + * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "i" character in the top right of LCD. The number 1 or 5 will be visible next to this character, indicating the current increment/decrement amount. * Long-press MODE to reset TCG life counter to decrement mode, decrement amount to 1, and both life counters to the current default value. If the life values displayed by the face are each equal to the current default life value and the face is also set to decrement mode with a decrement amount of 1, this action will instead return to the watch's first face. * Long-press ALARM to advance to the next set of increment/decrement values (1 and 5). The initial increment/decrement value is configured to 1. If the life values displayed by the face are each equal to the current default life value and the face is also set to decrement mode with a decrement amount of 1, this action will instead advance to the next set of default life values (20 and 40). The initial default life value is configured to 20. */ From 4fcd16578dbda99d2b49426c08fcc76a1fc221da Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Tue, 25 Nov 2025 07:45:43 -0500 Subject: [PATCH 09/13] cleanup docs --- watch-faces/complication/tcg_life_counter_face.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index a59196b26..560a1aebe 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -29,14 +29,14 @@ * TCG_LIFE_COUNTER face * * TCG Life Counter face is designed to track player life totals in a two-player trading card game. Two life totals will be displayed on the screen. The left counter is controlled by short-pressing LIGHT. The right counter is controlled by short-pressing ALARM. - * Life counters each begin at twenty and the face begins in decrement mode with a decrement value of one. This means the associated player's life total will decrement by a value of one each time LIGHT or ALARM is pressed. Once the face is changed to increment mode, the associated player's life total will increase by one each time LIGHT or ALARM is pressed. + * Life counters each begin at `20` and the face begins in decrement mode with a decrement value of `1`. This means the associated player's life total will decrement by a value of `1` each time LIGHT or ALARM is pressed. Once the face is changed to increment mode, the associated player's life total will increase by `1` each time LIGHT or ALARM is pressed. * * Usage: - * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to 0-999. - * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to 0-999. - * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a "d" or "i" character in the top right of LCD. The number 1 or 5 will be visible next to this character, indicating the current increment/decrement amount. - * Long-press MODE to reset TCG life counter to decrement mode, decrement amount to 1, and both life counters to the current default value. If the life values displayed by the face are each equal to the current default life value and the face is also set to decrement mode with a decrement amount of 1, this action will instead return to the watch's first face. - * Long-press ALARM to advance to the next set of increment/decrement values (1 and 5). The initial increment/decrement value is configured to 1. If the life values displayed by the face are each equal to the current default life value and the face is also set to decrement mode with a decrement amount of 1, this action will instead advance to the next set of default life values (20 and 40). The initial default life value is configured to 20. + * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to `0`-`999`. + * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to `0`-`999`. + * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a `d` or `i` character in the top right of LCD. The number `1` or `5` will be visible next to this character, indicating the current increment/decrement amount. + * Long-press MODE to reset TCG life counter to decrement mode, decrement amount to `1`, and both life counters to the current initial value. If the face is displaying initial values, this action will instead return to the watch's first face. + * Long-press ALARM to advance to the next set of increment/decrement values (`1` and `5`). The initial increment/decrement value is configured to `1`. If the face is displaying initial values, this action will instead advance to the next set of initial life values (`20` and `40`). The face starts with an initial life value of `20`. */ #include "movement.h" From 02887bf40451bf0e446feb5fd101ae86b46682fe Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:31:51 -0500 Subject: [PATCH 10/13] led works --- watch-faces/complication/tcg_life_counter_face.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index 560a1aebe..3585ef5ed 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -34,7 +34,7 @@ * Usage: * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to `0`-`999`. * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to `0`-`999`. - * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a `d` or `i` character in the top right of LCD. The number `1` or `5` will be visible next to this character, indicating the current increment/decrement amount. + * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a `d` or `i` character in the top right of LCD. The number `1` or `5` will be visible next to this character, indicating the current increment/decrement amount. This action will also illuminate the watch's LED. * Long-press MODE to reset TCG life counter to decrement mode, decrement amount to `1`, and both life counters to the current initial value. If the face is displaying initial values, this action will instead return to the watch's first face. * Long-press ALARM to advance to the next set of increment/decrement values (`1` and `5`). The initial increment/decrement value is configured to `1`. If the face is displaying initial values, this action will instead advance to the next set of initial life values (`20` and `40`). The face starts with an initial life value of `20`. */ From 772a14602eb85a878be56202ec3084af332478cc Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:33:07 -0500 Subject: [PATCH 11/13] led works --- watch-faces/complication/tcg_life_counter_face.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/watch-faces/complication/tcg_life_counter_face.c b/watch-faces/complication/tcg_life_counter_face.c index 9687bfae4..97312e87d 100644 --- a/watch-faces/complication/tcg_life_counter_face.c +++ b/watch-faces/complication/tcg_life_counter_face.c @@ -92,8 +92,10 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { print_tcg_life_counter(state); break; case EVENT_LIGHT_LONG_PRESS: + movement_illuminate_led(); state->increment_mode_on = !state->increment_mode_on; print_tcg_life_counter(state); + break; case EVENT_ALARM_BUTTON_DOWN: break; case EVENT_ALARM_BUTTON_UP: From 8394fa5250fd9bb7c6133cd06e349b654e68b4e7 Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Wed, 26 Nov 2025 11:12:42 -0500 Subject: [PATCH 12/13] optionally disable LED --- watch-faces/complication/tcg_life_counter_face.c | 2 ++ watch-faces/complication/tcg_life_counter_face.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/watch-faces/complication/tcg_life_counter_face.c b/watch-faces/complication/tcg_life_counter_face.c index 97312e87d..1559c1fac 100644 --- a/watch-faces/complication/tcg_life_counter_face.c +++ b/watch-faces/complication/tcg_life_counter_face.c @@ -92,7 +92,9 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { print_tcg_life_counter(state); break; case EVENT_LIGHT_LONG_PRESS: +#ifndef TCG_LIFE_COUNTER_FACE_DISABLE_LED movement_illuminate_led(); +#endif state->increment_mode_on = !state->increment_mode_on; print_tcg_life_counter(state); break; diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index 3585ef5ed..2304ad6f5 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -41,6 +41,9 @@ #include "movement.h" +// Uncomment the following to disable the LED lighting upon holding LIGHT. +// #define TCG_LIFE_COUNTER_FACE_DISABLE_LED + typedef struct { uint16_t life_values[2]; bool increment_mode_on; From 0000ae69a7fdd3ba763579c7c11e0665c4f7b83d Mon Sep 17 00:00:00 2001 From: Mark Schlosser <21339323+markschlosser@users.noreply.github.com> Date: Sat, 29 Nov 2025 08:59:18 -0500 Subject: [PATCH 13/13] reverse LED behavior --- watch-faces/complication/tcg_life_counter_face.c | 2 +- watch-faces/complication/tcg_life_counter_face.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/watch-faces/complication/tcg_life_counter_face.c b/watch-faces/complication/tcg_life_counter_face.c index 1559c1fac..c98533673 100644 --- a/watch-faces/complication/tcg_life_counter_face.c +++ b/watch-faces/complication/tcg_life_counter_face.c @@ -92,7 +92,7 @@ bool tcg_life_counter_face_loop(movement_event_t event, void *context) { print_tcg_life_counter(state); break; case EVENT_LIGHT_LONG_PRESS: -#ifndef TCG_LIFE_COUNTER_FACE_DISABLE_LED +#ifdef TCG_LIFE_COUNTER_FACE_ENABLE_LED movement_illuminate_led(); #endif state->increment_mode_on = !state->increment_mode_on; diff --git a/watch-faces/complication/tcg_life_counter_face.h b/watch-faces/complication/tcg_life_counter_face.h index 2304ad6f5..a31efce15 100644 --- a/watch-faces/complication/tcg_life_counter_face.h +++ b/watch-faces/complication/tcg_life_counter_face.h @@ -34,15 +34,15 @@ * Usage: * Short-press LIGHT to decrement or increment (determined by mode) left counter (player 1). Clamps to `0`-`999`. * Short-press ALARM to decrement or increment (determined by mode) right counter (player 2). Clamps to `0`-`999`. - * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a `d` or `i` character in the top right of LCD. The number `1` or `5` will be visible next to this character, indicating the current increment/decrement amount. This action will also illuminate the watch's LED. + * Long-press LIGHT to toggle mode to decrement or increment mode, indicated by a `d` or `i` character in the top right of LCD. The number `1` or `5` will be visible next to this character, indicating the current increment/decrement amount. * Long-press MODE to reset TCG life counter to decrement mode, decrement amount to `1`, and both life counters to the current initial value. If the face is displaying initial values, this action will instead return to the watch's first face. * Long-press ALARM to advance to the next set of increment/decrement values (`1` and `5`). The initial increment/decrement value is configured to `1`. If the face is displaying initial values, this action will instead advance to the next set of initial life values (`20` and `40`). The face starts with an initial life value of `20`. */ #include "movement.h" -// Uncomment the following to disable the LED lighting upon holding LIGHT. -// #define TCG_LIFE_COUNTER_FACE_DISABLE_LED +// Uncomment the following to enable the LED lighting upon holding LIGHT. +// #define TCG_LIFE_COUNTER_FACE_ENABLE_LED typedef struct { uint16_t life_values[2];