diff --git a/appinfo.json b/appinfo.json index 3e15139..258adac 100644 --- a/appinfo.json +++ b/appinfo.json @@ -22,9 +22,11 @@ "weekday": 18 }, "capabilities": [ - "configurable" + "configurable", + "health" ], "companyName": "lastfuture", + "enableMultiJS": false, "longName": "Squared 4.0", "projectType": "native", "resources": { @@ -38,7 +40,7 @@ "chalk" ], "uuid": "793bab03-9464-48a2-b63f-3f779c473db8", - "versionLabel": "4.11", + "versionLabel": "4.12", "watchapp": { "watchface": true } diff --git a/src/squared.c b/src/squared.c index 3381196..e8b81d1 100644 --- a/src/squared.c +++ b/src/squared.c @@ -2,7 +2,7 @@ * Original source code by lastfuture * SDK 2.0beta4 port by Jnm * SDK 3.0 port and colorizing by hexahedria - * adaptations for Chalk and Aplite as well as continued development by lastfuture + * adaptations for Chalk and Aplite as well as continued development since SDK 3.8.2 by lastfuture */ #include @@ -35,25 +35,31 @@ typedef struct { Preferences curPrefs; enum { - KEY_LARGE_MODE, - KEY_EU_DATE, - KEY_QUICK_START, - KEY_LEADING_ZERO, - KEY_BACKGROUND_COLOR, - KEY_NUMBER_BASE_COLOR, - KEY_NUMBER_VARIATION, - KEY_ORNAMENT_BASE_COLOR, - KEY_ORNAMENT_VARIATION, - KEY_INVERT, - KEY_MONOCHROME, - KEY_CENTER, - KEY_BTVIBE, - KEY_CONTRAST, - KEY_NIGHTSAVER, - KEY_NS_START, - KEY_NS_STOP, - KEY_BACKLIGHT, - KEY_WEEKDAY, + KEY_LARGE_MODE, + KEY_EU_DATE, + KEY_QUICK_START, + KEY_LEADING_ZERO, + KEY_BACKGROUND_COLOR, + KEY_NUMBER_BASE_COLOR, + KEY_NUMBER_VARIATION, + KEY_ORNAMENT_BASE_COLOR, + KEY_ORNAMENT_VARIATION, + KEY_INVERT, + KEY_MONOCHROME, + KEY_CENTER, + KEY_BTVIBE, + KEY_CONTRAST, + KEY_NIGHTSAVER, + KEY_NS_START, + KEY_NS_STOP, + KEY_BACKLIGHT, + KEY_WEEKDAY, +}; + +enum { + SLOT_TYPE_DIGIT, + SLOT_TYPE_ALPHA, + SLOT_TYPE_PROGRESS, }; #define KEY_DEBUGWATCH 50 @@ -68,6 +74,14 @@ enum { #define EU_DATE (curPrefs.eu_date) // true == MM/DD, false == DD/MM #define WEEKDAY (curPrefs.weekday) + +#define BATTERY_PERCENTAGE false +#define STEP_PERCENTAGE (BATTERY_PERCENTAGE ? false : true) // replace "true" with pref +#define PROGRESS (BATTERY_PERCENTAGE || STEP_PERCENTAGE) +#define PROGRESS_MIRROR false // TODO: this needs to work without mirroring the previous digits +#define PROGRESS_ON_SHAKE true +#define STEP_GOAL 10000 + #define CENTER_DATE (curPrefs.center) #define DISCONNECT_VIBRATION (curPrefs.btvibe) #define CONTRAST_WHILE_CHARGING PBL_IF_BW_ELSE(false, (curPrefs.contrast)) @@ -91,17 +105,30 @@ enum { #define ORNAMENT_ADD_VARIATION (curPrefs.ornament_variation) #define BACKGROUND_COLOR PBL_IF_BW_ELSE((INVERT ? GColorWhite : GColorBlack), ((GColor8) { .argb = curPrefs.background_color })) -#define FONT blocks -#define ALPHAFONT alphablocks +#define FONT_WIDTH_BLOCKS 5 +#define FONT_HEIGHT_BLOCKS 5 +#define TOTALBLOCKS FONT_WIDTH_BLOCKS*FONT_HEIGHT_BLOCKS +#define FONT_HEIGHT FONT_WIDTH_BLOCKS*TILE_SIZE +#define FONT_WIDTH FONT_HEIGHT_BLOCKS*TILE_SIZE + +#define TILES_X ( \ + FONT_WIDTH + SPACING_X + FONT_WIDTH) +#define TILES_Y ( \ + FONT_HEIGHT + SPACING_Y + FONT_HEIGHT) + +#define ORIGIN_X PBL_IF_RECT_ELSE(((144 - TILES_X)/2), ((180 - TILES_X)/2)) +#define ORIGIN_Y PBL_IF_RECT_ELSE((curPrefs.large_mode ? 1 : TILE_SIZE*1.5), (TILE_SIZE*2.2)) + + typedef struct { - Layer *layer; - uint8_t prevDigit; - uint8_t curDigit; - bool isalpha; - uint8_t divider; + Layer *layer; + bool mirror; + uint8_t prevDigit; + uint8_t curDigit; + uint8_t divider; AnimationProgress normTime; - uint8_t slotIndex; + uint8_t slotIndex; } digitSlot; digitSlot slot[NUMSLOTS]; @@ -110,7 +137,8 @@ static char weekday_buffer[2]; AnimationImplementation animImpl; Animation *anim; -static bool splashEnded = false, debug = false; +static bool splashEnded = false, debug = false, in_shake_mode = false; +static uint8_t progress = 0; static const char * locales[6] = {"en", "de", "es", "fr", "it", "pt"}; static const char * weekdays[6][7] = { @@ -122,261 +150,347 @@ static const char * weekdays[6][7] = { { "DO","SG","TE","QA","QI","SX","SA" } // PT - from http://www.brazil-help.com/week.htm (is this correct?) }; // required Letters: ADEFGHIJLMOQRSTUVWX -static const uint8_t alphablocks[][5][5] = { -[65] = { // A - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,0,2,0,1} -}, -[68] = { // D - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,0,2,0,1}, - {1,0,0,0,1}, - {1,1,1,1,0} -}, -[69] = { // E - {1,1,1,1,1}, - {1,0,0,0,0}, - {1,1,1,1,0}, - {1,0,0,0,0}, - {1,1,1,1,1} -}, -[70] = { // F - {1,1,1,1,1}, - {1,0,0,0,0}, - {1,1,1,1,0}, - {1,0,0,0,0}, - {1,0,2,2,2} -}, -[71] = { // G - {1,1,1,1,1}, - {1,0,0,0,0}, - {1,0,1,1,1}, - {1,0,0,0,1}, - {1,1,1,1,1} -}, -[72] = { // H - {1,0,2,0,1}, - {1,0,0,0,1}, - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,0,2,0,1} -}, -[73] = { // I - {1,1,1,1,1}, - {0,0,1,0,0}, - {2,0,1,0,2}, - {0,0,1,0,0}, - {1,1,1,1,1} -}, -[74] = { // J - {2,0,1,1,1}, - {0,0,0,0,1}, - {2,2,2,0,1}, - {0,0,0,0,1}, - {1,1,1,1,1} -}, -[76] = { // L - {1,0,2,0,2}, - {1,0,2,0,2}, - {1,0,2,0,2}, - {1,0,0,0,0}, - {1,1,1,1,1} -}, -[77] = { // M - {1,1,1,1,1}, - {1,0,1,0,1}, - {1,0,1,0,1}, - {1,0,0,0,1}, - {1,0,2,0,1} -}, -[79] = { // O - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,0,2,0,1}, - {1,0,0,0,1}, - {1,1,1,1,1} -}, -[81] = { // Q - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,0,0,0,1}, - {1,0,1,0,1}, - {1,1,1,1,1} -}, -[82] = { // R - {1,1,1,1,1}, - {0,0,0,0,1}, - {1,1,1,1,1}, - {1,0,0,1,0}, - {1,0,2,0,1} -}, -[83] = { // S - {1,1,1,1,1}, - {1,0,0,0,0}, - {1,1,1,1,1}, - {0,0,0,0,1}, - {1,1,1,1,1} -}, -[84] = { // T - {1,1,1,1,1}, - {0,0,1,0,0}, - {2,0,1,0,2}, - {2,0,1,0,2}, - {2,0,1,0,2} -}, -[85] = { // U - {1,0,2,0,1}, - {1,0,2,0,1}, - {1,0,2,0,1}, - {1,0,0,0,1}, - {1,1,1,1,1} -}, -[86] = { // V - {1,0,2,0,1}, - {1,0,2,0,1}, - {1,0,2,0,1}, - {1,0,0,0,1}, - {1,1,1,1,0} -}, -[87] = { // W - {1,0,2,0,1}, - {1,0,0,0,1}, - {1,0,1,0,1}, - {1,0,1,0,1}, - {1,1,1,1,1} -}, -[88] = { // X - {1,0,0,0,1}, - {0,1,0,1,0}, - {0,0,1,0,0}, - {0,1,0,1,0}, - {1,0,0,0,1} -}, -[10] = { - {2,2,2,2,2}, - {0,0,0,0,0}, - {2,2,2,2,2}, - {0,0,0,0,0}, - {2,2,2,2,2} -}, -[11] = { - {2,0,2,0,2}, - {2,0,2,0,2}, - {2,0,2,0,2}, - {2,0,2,0,2}, - {2,0,2,0,2} -}, -[12] = { - {1,1,1,1,1}, - {0,0,0,0,0}, - {1,1,1,1,1}, - {0,0,0,0,0}, - {1,1,1,1,1} -}, -[13] = { - {1,0,1,0,1}, - {1,0,1,0,1}, - {1,0,1,0,1}, - {1,0,1,0,1}, - {1,0,1,0,1} -}}; +// character_map[] maps 0-9 (digits), 10-13 (ornaments), ascii codes of uppercase letters and 100-109 (progress indicators) to characters[] +static const uint8_t character_map[] = { +// DIGITS +[0] = 0, +[1] = 1, +[2] = 2, +[3] = 3, +[4] = 4, +[5] = 5, +[6] = 6, +[7] = 7, +[8] = 8, +[9] = 9, +// ORNAMENTS +[10] = 10, +[11] = 11, +[12] = 12, +[13] = 13, +// UPPERCASE ASCII CHARACTERS +[65] = 14, +[68] = 15, +[69] = 16, +[70] = 17, +[71] = 18, +[72] = 19, +[73] = 20, +[74] = 21, +[76] = 22, +[77] = 23, +[79] = 0, // same as 0 +[81] = 24, +[82] = 25, +[83] = 26, +[84] = 27, +[85] = 28, +[86] = 29, +[87] = 30, +[88] = 31, +// PROGRESS +[100] = 10, // same as ornament 10 +[101] = 32, +[102] = 33, +[103] = 34, +[104] = 35, +[105] = 36, +[106] = 37, +[107] = 38, +[108] = 39, +[109] = 13 // same as ornament 13 +}; -static const uint8_t blocks[][5][5] = {{ - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,0,2,0,1}, - {1,0,0,0,1}, - {1,1,1,1,1} -}, { - {2,2,0,1,1}, - {0,0,0,0,1}, - {2,2,2,0,1}, - {0,0,0,0,1}, - {2,2,2,0,1} -}, { - {1,1,1,1,1}, - {0,0,0,0,1}, - {1,1,1,1,1}, - {1,0,0,0,0}, - {1,1,1,1,1} -}, { - {1,1,1,1,1}, - {0,0,0,0,1}, - {0,1,1,1,1}, - {0,0,0,0,1}, - {1,1,1,1,1} -}, { - {1,0,2,0,1}, - {1,0,0,0,1}, - {1,1,1,1,1}, - {0,0,0,0,1}, - {2,2,2,0,1} -}, { - {1,1,1,1,1}, - {1,0,0,0,0}, - {1,1,1,1,1}, - {0,0,0,0,1}, - {1,1,1,1,1} -}, { - {1,1,1,1,1}, - {1,0,0,0,0}, - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,1,1,1,1} -}, { - {1,1,1,1,1}, - {0,0,0,0,1}, - {2,0,2,0,1}, - {2,0,2,0,1}, - {2,0,2,0,1} -}, { - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,1,1,1,1} -}, { - {1,1,1,1,1}, - {1,0,0,0,1}, - {1,1,1,1,1}, - {0,0,0,0,1}, - {1,1,1,1,1} -}, { - {2,2,2,2,2}, - {0,0,0,0,0}, - {2,2,2,2,2}, - {0,0,0,0,0}, - {2,2,2,2,2} -}, { - {2,0,2,0,2}, - {2,0,2,0,2}, - {2,0,2,0,2}, - {2,0,2,0,2}, - {2,0,2,0,2} -}, { - {1,1,1,1,1}, - {0,0,0,0,0}, - {1,1,1,1,1}, - {0,0,0,0,0}, - {1,1,1,1,1} -}, { - {1,0,1,0,1}, - {1,0,1,0,1}, - {1,0,1,0,1}, - {1,0,1,0,1}, - {1,0,1,0,1} +// left column is digit color, right column is ornament color +static const uint8_t characters[][10] = { +// DIGITS +{ + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b10001, 0b00100, + 0b10001, 0b00000, + 0b11111, 0b00000 }, -[99] = { - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1} -}}; +{ + 0b00011, 0b11000, + 0b00001, 0b00000, + 0b00001, 0b11100, + 0b00001, 0b00000, + 0b00001, 0b11100 +}, +{ + 0b11111, 0b00000, + 0b00001, 0b00000, + 0b11111, 0b00000, + 0b10000, 0b00000, + 0b11111, 0b00000 +}, +{ + 0b11111, 0b00000, + 0b00001, 0b00000, + 0b01111, 0b00000, + 0b00001, 0b00000, + 0b11111, 0b00000 +}, +{ + 0b10001, 0b00100, + 0b10001, 0b00000, + 0b11111, 0b00000, + 0b00001, 0b00000, + 0b00001, 0b11100 +}, +{ + 0b11111, 0b00000, + 0b10000, 0b00000, + 0b11111, 0b00000, + 0b00001, 0b00000, + 0b11111, 0b00000 +}, +{ + 0b11111, 0b00000, + 0b10000, 0b00000, + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b11111, 0b00000 +}, +{ + 0b11111, 0b00000, + 0b00001, 0b00000, + 0b00001, 0b10100, + 0b00001, 0b10100, + 0b00001, 0b10100 +}, +{ + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b11111, 0b00000 +}, +{ + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b11111, 0b00000, + 0b00001, 0b00000, + 0b11111, 0b00000 +}, +// ORNAMENTS +{ + 0b00000, 0b11111, + 0b00000, 0b00000, + 0b00000, 0b11111, + 0b00000, 0b00000, + 0b00000, 0b11111 +}, +{ + 0b00000, 0b10101, + 0b00000, 0b10101, + 0b00000, 0b10101, + 0b00000, 0b10101, + 0b00000, 0b10101 +}, +{ + 0b11111, 0b00000, + 0b00000, 0b00000, + 0b11111, 0b00000, + 0b00000, 0b00000, + 0b11111, 0b00000 +}, +{ + 0b10101, 0b00000, + 0b10101, 0b00000, + 0b10101, 0b00000, + 0b10101, 0b00000, + 0b10101, 0b00000 +}, +// UPPERCASE ASCII CHARACTERS +{ // A + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b10001, 0b00100 +}, +{ // D + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b10001, 0b00100, + 0b10001, 0b00000, + 0b11110, 0b00000 +}, +{ // E + 0b11111, 0b00000, + 0b10000, 0b00000, + 0b11110, 0b00000, + 0b10000, 0b00000, + 0b11111, 0b00000 +}, +{ // F + 0b11111, 0b00000, + 0b10000, 0b00000, + 0b11110, 0b00000, + 0b10000, 0b00000, + 0b10000, 0b00111 +}, +{ // G + 0b11111, 0b00000, + 0b10000, 0b00000, + 0b10111, 0b00000, + 0b10001, 0b00000, + 0b11111, 0b00000 +}, +{ // H + 0b10001, 0b00100, + 0b10001, 0b00000, + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b10001, 0b00100 +}, +{ // I + 0b11111, 0b00000, + 0b00100, 0b00000, + 0b00100, 0b10001, + 0b00100, 0b00000, + 0b11111, 0b00000 +}, +{ // J + 0b00111, 0b10000, + 0b00001, 0b00000, + 0b00001, 0b11100, + 0b00001, 0b00000, + 0b11111, 0b00000 +}, +{ // L + 0b10000, 0b00101, + 0b10000, 0b00101, + 0b10000, 0b00101, + 0b10000, 0b00000, + 0b11111, 0b00000 +}, +{ // M + 0b11111, 0b00000, + 0b10101, 0b00000, + 0b10101, 0b00000, + 0b10001, 0b00000, + 0b10001, 0b00100 +}, +// O is same as 0 +{ // Q + 0b11111, 0b00000, + 0b10001, 0b00000, + 0b10001, 0b00000, + 0b10101, 0b00000, + 0b11111, 0b00000 +}, +{ // R + 0b11111, 0b00000, + 0b00001, 0b00000, + 0b11111, 0b00000, + 0b10010, 0b00000, + 0b10001, 0b00100 +}, +{ // S + 0b11111, 0b00000, + 0b10000, 0b00000, + 0b11111, 0b00000, + 0b00001, 0b00000, + 0b11111, 0b00000 +}, +{ // T + 0b11111, 0b00000, + 0b00100, 0b00000, + 0b00100, 0b10001, + 0b00100, 0b10001, + 0b00100, 0b10001 +}, +{ // U + 0b10001, 0b00100, + 0b10001, 0b00100, + 0b10001, 0b00100, + 0b10001, 0b00000, + 0b11111, 0b00000 +}, +{ // V + 0b10001, 0b00100, + 0b10001, 0b00100, + 0b10001, 0b00100, + 0b10001, 0b00000, + 0b11110, 0b00000 +}, +{ // W + 0b10001, 0b00100, + 0b10001, 0b00000, + 0b10101, 0b00000, + 0b10101, 0b00000, + 0b11111, 0b00000 +}, +{ // X + 0b10001, 0b00000, + 0b01010, 0b00000, + 0b00100, 0b00000, + 0b01010, 0b00000, + 0b10001, 0b00000 +}, +// PROGRESS +// 01% is same as ornament 10 +{ // 12% + 0b00000, 0b11111, + 0b00000, 0b00000, + 0b00000, 0b11111, + 0b00000, 0b00000, + 0b10000, 0b00111 +}, +{ // 23% + 0b00000, 0b11111, + 0b00000, 0b00000, + 0b10000, 0b00111, + 0b10000, 0b00000, + 0b10000, 0b00111 +}, +{ // 34% + 0b10000, 0b00111, + 0b10000, 0b00000, + 0b10000, 0b00111, + 0b10000, 0b00000, + 0b10000, 0b00111 +}, +{ // 45% + 0b10000, 0b00111, + 0b10000, 0b00000, + 0b10000, 0b00111, + 0b10000, 0b00000, + 0b10100, 0b00001 +}, +{ // 56% + 0b10000, 0b00111, + 0b10000, 0b00000, + 0b10100, 0b00001, + 0b10100, 0b00000, + 0b10100, 0b00001 +}, +{ // 67% + 0b10100, 0b00001, + 0b10100, 0b00000, + 0b10100, 0b00001, + 0b10100, 0b00000, + 0b10100, 0b00001 +}, +{ // 78% + 0b10100, 0b00001, + 0b10100, 0b00000, + 0b10100, 0b00001, + 0b10100, 0b00000, + 0b10101, 0b00000 +}, +{ // 89% + 0b10100, 0b00001, + 0b10100, 0b00000, + 0b10101, 0b00000, + 0b10101, 0b00000, + 0b10101, 0b00000 +}, +// 100% is same as ornament 13 +}; static const uint8_t startDigit[18] = { 11,12,12,11,11,12,10,13,12,11,12,11,11,12,10,13,12,10 // 2x h, 2x m, 4x date, 2x filler top, 4x filler sides, 2x filler bottom, 2x filler bottom sides @@ -426,27 +540,11 @@ static const uint8_t shadowtable[256] = { // alpha should only be 0b??111111 where ?? = 00 (full shade), 01 (much shade), 10 (some shade), 11 (none shade) static const uint8_t alpha = 0b10111111; -/* -uint8_t combine_colors(uint8_t fg_color, uint8_t bg_color) { - return (shadowtable[((~fg_color)&0b11000000) + (bg_color&63)]&63) + shadowtable[fg_color]; -} -*/ +static bool contrastmode = false, allow_animate = true, initial_anim = false; -#define FONT_HEIGHT_BLOCKS (sizeof *FONT / sizeof **FONT) -#define FONT_WIDTH_BLOCKS (sizeof **FONT) -#define TOTALBLOCKS FONT_HEIGHT_BLOCKS * FONT_WIDTH_BLOCKS -#define FONT_HEIGHT FONT_HEIGHT_BLOCKS*TILE_SIZE -#define FONT_WIDTH FONT_WIDTH_BLOCKS*TILE_SIZE - -#define TILES_X ( \ - FONT_WIDTH + SPACING_X + FONT_WIDTH) -#define TILES_Y ( \ - FONT_HEIGHT + SPACING_Y + FONT_HEIGHT) - -#define ORIGIN_X PBL_IF_RECT_ELSE(((144 - TILES_X)/2), ((180 - TILES_X)/2)) -#define ORIGIN_Y PBL_IF_RECT_ELSE((curPrefs.large_mode ? 1 : TILE_SIZE*1.5), (TILE_SIZE*2.2)) - -static bool contrastmode = false, previous_contrastmode = false, allow_animate = true, initial_anim = false; +#if defined(PBL_COLOR) +static bool previous_contrastmode = false; +#endif static void handle_bluetooth(bool connected) { if (DISCONNECT_VIBRATION && !connected) { @@ -520,15 +618,29 @@ static GRect slotFrame(int8_t i) { return GRect(x, y, w, h); } -static GColor8 getSlotColor(uint8_t x, uint8_t y, uint8_t digit, uint8_t pos, bool isalpha) { +static uint8_t fetchrect(uint8_t digit, uint8_t x, uint8_t y, bool mirror) { + // character_map maps 0-9 (digits), 10-13 (ornaments), ascii codes of uppercase letters and 100-109 (progress) to characters[] + uint8_t color1 = characters[character_map[digit]][(y*2)]; // get one row of digit colors + uint8_t color2 = characters[character_map[digit]][(y*2)+1]; // get one row of ornament colors + uint8_t mask = 0b10000 >> x; + if (mirror) { + mask = 0b00001 << x; + } + if (color1 & mask) { // check column of row + return 1; + } else if (color2 & mask) { + return 2; + } else { + return 0; + } +} + +static GColor8 getSlotColor(uint8_t x, uint8_t y, uint8_t digit, uint8_t pos, bool mirror) { static uint8_t argb; static bool should_add_var = false; - uint8_t thisrect = FONT[digit][y][x]; - if (isalpha) { - thisrect = ALPHAFONT[digit][y][x]; - } + uint8_t thisrect = fetchrect(digit, x, y, mirror); if (SCREENSHOTMODE) { - thisrect = FONT[99][y][x]; + thisrect = 1; } if (thisrect == 0) { if (contrastmode) { @@ -606,8 +718,8 @@ static void updateSlot(Layer *layer, GContext *ctx) { ty = t / FONT_HEIGHT_BLOCKS; shift = 0-(t-ty); - GColor8 oldColor = getSlotColor(tx, ty, slot->prevDigit, slot->slotIndex, slot->isalpha); - GColor8 newColor = getSlotColor(tx, ty, slot->curDigit, slot->slotIndex, slot->isalpha); + GColor8 oldColor = getSlotColor(tx, ty, slot->prevDigit, slot->slotIndex, slot->mirror); + GColor8 newColor = getSlotColor(tx, ty, slot->curDigit, slot->slotIndex, slot->mirror); graphics_context_set_fill_color(ctx, oldColor); graphics_fill_rect(ctx, GRect((tx*tilesize)-(tx*widthadjust), ty*tilesize-(ty*widthadjust), tilesize-widthadjust, tilesize-widthadjust), 0, GCornerNone); @@ -652,8 +764,89 @@ static void destroyAnimation() { anim = NULL; } +static void setProgressSlots(uint8_t progress, bool showgoal, bool mirrored) { + uint8_t mappedProgress = (((progress+3)*0.95*40)/100); + if (showgoal && progress == 100) { + slot[4].curDigit = 'G'; + slot[5].curDigit = 'O'; + slot[6].curDigit = 'A'; + slot[7].curDigit = 'L'; + } else { + slot[4].curDigit = 100; + slot[5].curDigit = 100; + slot[6].curDigit = 100; + slot[7].curDigit = 100; + uint8_t partialSegment = 100+mappedProgress%10; + if (!mirrored) { + slot[4].curDigit = partialSegment; + if (mappedProgress >= 10) { + slot[4].curDigit = 109; + slot[5].curDigit = partialSegment; + } + if (mappedProgress >= 20) { + slot[5].curDigit = 109; + slot[6].curDigit = partialSegment; + } + if (mappedProgress >= 30) { + slot[6].curDigit = 109; + slot[7].curDigit = partialSegment; + } + if (mappedProgress >= 40) { + slot[7].curDigit = 109; + } + } else { + slot[4].mirror = true; + slot[5].mirror = true; + slot[6].mirror = true; + slot[7].mirror = true; + slot[7].curDigit = partialSegment; + if (mappedProgress >= 10) { + slot[7].curDigit = 109; + slot[6].curDigit = partialSegment; + } + if (mappedProgress >= 20) { + slot[6].curDigit = 109; + slot[5].curDigit = partialSegment; + } + if (mappedProgress >= 30) { + slot[5].curDigit = 109; + slot[4].curDigit = partialSegment; + } + if (mappedProgress >= 40) { + slot[4].curDigit = 109; + } + } + } +} + +static void update_step_goal() { + #if defined(PBL_HEALTH) + HealthMetric metric = HealthMetricStepCount; + time_t start = time_start_of_today(); + time_t end = time(NULL); + + // Check the metric has data available for today + HealthServiceAccessibilityMask mask = health_service_metric_accessible(metric, + start, end); + + if(mask & HealthServiceAccessibilityMaskAvailable) { + // Data is available! + progress = (int)(((float)health_service_sum_today(metric)/(float)STEP_GOAL)*100); + APP_LOG(APP_LOG_LEVEL_INFO, "Step progress: %d%%", progress); + } else { + // No data recorded yet today + APP_LOG(APP_LOG_LEVEL_ERROR, "Data unavailable!"); + progress = 0; + } + #endif +} + static void handle_tick(struct tm *t, TimeUnits units_changed) { static uint8_t ho, mi, da, mo; + + if (STEP_PERCENTAGE && !PROGRESS_ON_SHAKE) { + update_step_goal(); + } if (splashEnded && !initial_anim) { if (animation_is_scheduled(anim)){ @@ -718,15 +911,8 @@ static void handle_tick(struct tm *t, TimeUnits units_changed) { slot[2].curDigit = mi/10; slot[3].curDigit = mi%10; - slot[4].isalpha = false; - slot[5].isalpha = false; - slot[6].isalpha = false; - slot[7].isalpha = false; - if (!EU_DATE) { if (WEEKDAY) { - slot[4].isalpha = true; - slot[5].isalpha = true; slot[4].curDigit = (uint8_t) weekdayname[0]; slot[5].curDigit = (uint8_t) weekdayname[1]; } else { @@ -748,8 +934,6 @@ static void handle_tick(struct tm *t, TimeUnits units_changed) { slot[4].curDigit = da/10; slot[5].curDigit = da%10; if (WEEKDAY) { - slot[6].isalpha = true; - slot[7].isalpha = true; slot[6].curDigit = (uint8_t) weekdayname[0]; slot[7].curDigit = (uint8_t) weekdayname[1]; } else { @@ -767,42 +951,51 @@ static void handle_tick(struct tm *t, TimeUnits units_changed) { } } - if (NO_ZERO) { - if (slot[0].curDigit == 0) { - if (NUMSLOTS > 8) { - if (slot[10].prevDigit != 10 && slot[10].prevDigit != 12) { - slot[0].curDigit = 11; + if (!in_shake_mode) { + if (NO_ZERO) { + if (slot[0].curDigit == 0) { + if (NUMSLOTS > 8) { + if (slot[10].prevDigit != 10 && slot[10].prevDigit != 12) { + slot[0].curDigit = 11; + } else { + slot[0].curDigit = 10; + } } else { - slot[0].curDigit = 10; + if (slot[0].prevDigit == 10) { + slot[0].curDigit = 11; + } else { + slot[0].curDigit = 10; + } } - } else { - if (slot[0].prevDigit == 10) { - slot[0].curDigit = 11; - } else { - slot[0].curDigit = 10; + } + if (slot[4].curDigit == 0) { + slot[4].curDigit = 10; + if (slot[4].prevDigit == 10) { + slot[4].curDigit++; + } + } + if (slot[6].curDigit == 0) { + slot[6].curDigit = 10; + if (slot[6].prevDigit == 10) { + slot[6].curDigit++; } } } - if (slot[4].curDigit == 0) { - slot[4].curDigit = 10; - if (slot[4].prevDigit == 10) { - slot[4].curDigit++; + if (NUMSLOTS > 8) { + for(int dig = 8; dig < NUMSLOTS; dig++) { + if (slot[dig].prevDigit == 10 || slot[dig].prevDigit == 12) { + slot[dig].curDigit = 11; + } else { + slot[dig].curDigit = 10; + } } } - if (slot[6].curDigit == 0) { - slot[6].curDigit = 10; - if (slot[6].prevDigit == 10) { - slot[6].curDigit++; - } + } else { + for(int dig = 0; dig < 4; dig++) { + slot[dig].curDigit = slot[dig].prevDigit; } - } - if (NUMSLOTS > 8) { for(int dig = 8; dig < NUMSLOTS; dig++) { - if (slot[dig].prevDigit == 10 || slot[dig].prevDigit == 12) { - slot[dig].curDigit = 11; - } else { - slot[dig].curDigit = 10; - } + slot[dig].curDigit = slot[dig].prevDigit; } } setupAnimation(); @@ -815,20 +1008,35 @@ static void initialAnimationDone() { } void handle_timer(void *data) { - time_t curTime; - splashEnded = true; - - curTime = time(NULL); + time_t curTime = time(NULL); handle_tick(localtime(&curTime), SECOND_UNIT|MINUTE_UNIT|HOUR_UNIT|DAY_UNIT|MONTH_UNIT|YEAR_UNIT); + in_shake_mode = false; initial_anim = true; if (initial_anim) { app_timer_register(contrastmode ? 500 : DIGIT_CHANGE_ANIM_DURATION, initialAnimationDone, NULL); } - - } +static void tap_handler(AccelAxisType axis, int32_t direction) { + if (!in_shake_mode) { + for (uint8_t i=0; i