Upload files to "src/c"
This commit is contained in:
42
src/c/constants.c
Normal file
42
src/c/constants.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#include <pebble.h>
|
||||||
|
#include "constants.h"
|
||||||
|
|
||||||
|
const int DEFAULT_SHAKE_FOR_LOHI = 1; //True - shake to show Lo Hi Temps
|
||||||
|
const int DEFAULT_DISPLAY_LOHI_TIMER = 5000; //length time (milliseconds) to display Lo Hi Temps
|
||||||
|
const int DEFAULT_MIN_SINCE_WEATHER_UPDATE = 0; //weather just updated
|
||||||
|
const char DEFAULT_LAST_WEATHER_UPDATE[16] = "--:--"; //default last update "time" display
|
||||||
|
const char DEFAULT_ERROR_WEATHER_UPDATE[16] = "---"; //default text display upon weather update error
|
||||||
|
const int DEFAULT_CONDITION_CODE = -99; //Invalid condition code to force weather update
|
||||||
|
const int DEFAULT_DISPLAY_WEATHER = 1; //true
|
||||||
|
const int DEFAULT_WEATHER_FREQUENCY = 30; //minutes
|
||||||
|
const int DEFAULT_WEATHER_USE_GPS = 1; //true
|
||||||
|
const int DEFAULT_USE_CELSIUS = 0; //false
|
||||||
|
const int DEFAULT_DISPLAY_O_PREFIX = 0; //false
|
||||||
|
const int DEFAULT_WEATHERDATE_ALIGNMENT = 1; //center
|
||||||
|
const int DEFAULT_HOURMINUTES_ALIGNMENT = 0; //left
|
||||||
|
const int DEFAULT_CHALK_ALIGNMENT = 1; //center
|
||||||
|
const int DEFAULT_TIME_COLOR = 0xFFFFFF; //white
|
||||||
|
const int DEFAULT_HR_COLOR = 0xFFFFFF; //white
|
||||||
|
const int DEFAULT_MIN_COLOR = 0xFFFFFF; //white
|
||||||
|
const int DEFAULT_BACKGROUND_COLOR = 0x000000; //black
|
||||||
|
const int DEFAULT_WEATHERDATE_READABILITY = 0; //use original size
|
||||||
|
const int DEFAULT_MINUTES_READABILITY = 0; //use default size
|
||||||
|
const int DEFAULT_WEATHER_Y_OFFSET_READABILITY = 4; //Y-axis adjustment for increased readability font options
|
||||||
|
const int DEFAULT_DATE_Y_OFFSET_READABILITY = 5; //Y-axis adjustment for increased readability font options
|
||||||
|
const int DEFAULT_VIBRATE_BT_STATUS = 0; //false
|
||||||
|
const int DEFAULT_WD_COLOR = 0xFFFFFF; //white
|
||||||
|
const int DEFAULT_DISPLAY_DATE = 1; //true
|
||||||
|
|
||||||
|
const int DEFAULT_MAX_WEATHER_RETRY_COUNT = 5; //max (seconds) weather retry counts
|
||||||
|
const uint MAX_CHALK_SINGLE_LINE_CONDITIONS_LEN = 6; //max length for weather conditions to display on single line. longer split to two lines
|
||||||
|
const int DEFAULT_CHALK_TIME_X_OFFSET = 20; //X-axis adjustment for time display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_CHALK_WEATHER1_Y_OFFSET = 0; //Y-axis adjustment for weather display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_CHALK_WEATHER2_Y_OFFSET = 15; //Y-axis adjustment for weather display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_CHALK_WEATHER_CENTER_Y_OFFSET = 8; //Y-axis adjustment for weather display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_CHALK_TIME_Y_OFFSET = 10; //Y-axis adjustment for time display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_CHALK_DATE_Y_OFFSET = 5; //Y-axis adjustment for date display on Chalk (Pebble Time Round)
|
||||||
|
|
||||||
|
//watchface time display lines
|
||||||
|
const int HOUR_ROW = 0;
|
||||||
|
const int MINUTE_ROW1 = 1;
|
||||||
|
const int MINUTE_ROW2 = 2;
|
||||||
73
src/c/constants.h
Normal file
73
src/c/constants.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
#define KEY_TEMPERATURE_IN_C 1
|
||||||
|
#define KEY_CONDITIONS 2
|
||||||
|
#define KEY_BACKGROUND_COLOR 3
|
||||||
|
#define KEY_TIME_COLOR 4
|
||||||
|
#define KEY_WEATHER_FREQUENCY 5
|
||||||
|
#define KEY_USE_CELSIUS 6
|
||||||
|
#define KEY_DISPLAY_O_PREFIX 7
|
||||||
|
#define KEY_DISPLAY_WEATHER 8
|
||||||
|
#define KEY_MIN_SINCE_WEATHER_UPDATE 9
|
||||||
|
#define KEY_WEATHERDATE_ALIGNMENT 10
|
||||||
|
#define KEY_HOURMINUTES_ALIGNMENT 11
|
||||||
|
#define KEY_GET_WEATHER 12
|
||||||
|
#define KEY_TEMPERATURE 13
|
||||||
|
#define KEY_WEATHERDATE_READABILITY 14
|
||||||
|
#define KEY_MINUTES_READABILITY 15
|
||||||
|
#define KEY_TEMPERATURE_LO 16
|
||||||
|
#define KEY_TEMPERATURE_HI 17
|
||||||
|
#define KEY_TEMPERATURE_IN_C_LO 18
|
||||||
|
#define KEY_TEMPERATURE_IN_C_HI 19
|
||||||
|
#define KEY_CONDITION_CODE 20
|
||||||
|
#define KEY_SHAKE_FOR_LOHI 21
|
||||||
|
#define KEY_VIBBRATE_BT_STATUS 22
|
||||||
|
#define KEY_WEATHER_USE_GPS 23
|
||||||
|
#define KEY_WEATHER_LOCATION 24
|
||||||
|
#define KEY_JS_READY 25
|
||||||
|
#define KEY_WD_COLOR 26
|
||||||
|
#define KEY_DISPLAY_DATE 27
|
||||||
|
#define KEY_HR_COLOR 28
|
||||||
|
#define KEY_MIN_COLOR 29
|
||||||
|
#define KEY_OPTIONS 99
|
||||||
|
|
||||||
|
extern const int DEFAULT_SHAKE_FOR_LOHI;
|
||||||
|
extern const int DEFAULT_DISPLAY_LOHI_TIMER;
|
||||||
|
extern const int DEFAULT_MIN_SINCE_WEATHER_UPDATE;
|
||||||
|
extern const char DEFAULT_LAST_WEATHER_UPDATE[16];
|
||||||
|
extern const char DEFAULT_ERROR_WEATHER_UPDATE[16];
|
||||||
|
extern const int DEFAULT_CONDITION_CODE;
|
||||||
|
extern const int DEFAULT_DISPLAY_WEATHER;
|
||||||
|
extern const int DEFAULT_WEATHER_FREQUENCY;
|
||||||
|
extern const int DEFAULT_WEATHER_USE_GPS;
|
||||||
|
extern const int DEFAULT_USE_CELSIUS;
|
||||||
|
extern const int DEFAULT_DISPLAY_O_PREFIX;
|
||||||
|
extern const int DEFAULT_WEATHERDATE_ALIGNMENT;
|
||||||
|
extern const int DEFAULT_HOURMINUTES_ALIGNMENT;
|
||||||
|
extern const int DEFAULT_CHALK_ALIGNMENT;
|
||||||
|
extern const int DEFAULT_TIME_COLOR;
|
||||||
|
extern const int DEFAULT_HR_COLOR;
|
||||||
|
extern const int DEFAULT_MIN_COLOR;
|
||||||
|
extern const int DEFAULT_BACKGROUND_COLOR;
|
||||||
|
extern const int DEFAULT_WEATHERDATE_READABILITY;
|
||||||
|
extern const int DEFAULT_MINUTES_READABILITY;
|
||||||
|
extern const int DEFAULT_WEATHER_Y_OFFSET_READABILITY;
|
||||||
|
extern const int DEFAULT_DATE_Y_OFFSET_READABILITY;
|
||||||
|
extern const int DEFAULT_VIBRATE_BT_STATUS;
|
||||||
|
extern const int DEFAULT_WD_COLOR;
|
||||||
|
extern const int DEFAULT_DISPLAY_DATE;
|
||||||
|
|
||||||
|
extern const int DEFAULT_MAX_WEATHER_RETRY_COUNT;
|
||||||
|
extern const uint MAX_CHALK_SINGLE_LINE_CONDITIONS_LEN;
|
||||||
|
extern const int DEFAULT_CHALK_TIME_X_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_WEATHER1_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_WEATHER2_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_WEATHER_CENTER_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_TIME_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_DATE_Y_OFFSET;
|
||||||
|
|
||||||
|
extern const int HOUR_ROW;
|
||||||
|
extern const int MINUTE_ROW1;
|
||||||
|
extern const int MINUTE_ROW2;
|
||||||
224
src/c/messaging.c
Normal file
224
src/c/messaging.c
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
#include <pebble.h>
|
||||||
|
#include "messaging.h"
|
||||||
|
#include "constants.h"
|
||||||
|
#include "weather_date.h"
|
||||||
|
#include "sliding_time_wd.h"
|
||||||
|
|
||||||
|
extern Options s_options;
|
||||||
|
extern SlidingTextData *s_data;
|
||||||
|
|
||||||
|
void send(int key, int value, int key2, int value2, int key3, char value3[64]){
|
||||||
|
#if DEBUG
|
||||||
|
APP_LOG(APP_LOG_LEVEL_DEBUG, "send: s_options.pebble_js_ready: %d", s_options.pebble_js_ready);
|
||||||
|
#endif
|
||||||
|
if (s_options.pebble_js_ready) {
|
||||||
|
|
||||||
|
DictionaryIterator *iterator;
|
||||||
|
app_message_outbox_begin(&iterator);
|
||||||
|
dict_write_int(iterator, key, &value, sizeof(int), true);
|
||||||
|
dict_write_int(iterator, key2, &value2, sizeof(int), true);
|
||||||
|
dict_write_cstring(iterator, key3, value3);
|
||||||
|
|
||||||
|
app_message_outbox_send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void inbox_received_callback(DictionaryIterator *iterator, void *context) {
|
||||||
|
SlidingTextData *data = s_data;
|
||||||
|
SlidingRow *row;
|
||||||
|
|
||||||
|
// Read first item
|
||||||
|
Tuple *t = dict_read_first(iterator);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
int dic_size = (int)dict_size(iterator);
|
||||||
|
APP_LOG(APP_LOG_LEVEL_DEBUG, "***************************** inbox_received_callback dict_size: %d", dic_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// For all items
|
||||||
|
while(t != NULL) {
|
||||||
|
// Which key was received?
|
||||||
|
switch(t->key) {
|
||||||
|
|
||||||
|
case KEY_TEMPERATURE:
|
||||||
|
s_options.tempF = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_TEMPERATURE_LO:
|
||||||
|
s_options.tempFLo = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_TEMPERATURE_HI:
|
||||||
|
s_options.tempFHi = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_TEMPERATURE_IN_C:
|
||||||
|
s_options.tempC = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_TEMPERATURE_IN_C_LO:
|
||||||
|
s_options.tempCLo = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_TEMPERATURE_IN_C_HI:
|
||||||
|
s_options.tempCHi = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_CONDITIONS:
|
||||||
|
snprintf(s_options.conditions, sizeof(s_options.conditions), "%s", t->value->cstring);
|
||||||
|
|
||||||
|
//check if successful weather retrieval
|
||||||
|
if (strlen(s_options.conditions) > 0) {
|
||||||
|
// Get a tm structure
|
||||||
|
time_t temp = time(NULL);
|
||||||
|
struct tm *tick_time = localtime(&temp);
|
||||||
|
//strftime(s_options.last_weather_update, sizeof("00:00"), "%H:%M", tick_time);
|
||||||
|
strftime(s_options.last_weather_update24hr, sizeof("00:00"), "%H:%M", tick_time);
|
||||||
|
strftime(s_options.last_weather_update12hr, sizeof("00:00 pm"), "%l:%M %P", tick_time);
|
||||||
|
s_options.last_update = temp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_CONDITION_CODE:
|
||||||
|
s_options.condition_code = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_DISPLAY_O_PREFIX:
|
||||||
|
s_options.display_prefix = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_DISPLAY_DATE:
|
||||||
|
s_options.display_date = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_SHAKE_FOR_LOHI:
|
||||||
|
s_options.shake_for_lohi = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_USE_CELSIUS:
|
||||||
|
s_options.use_celsius = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_WEATHER_USE_GPS:
|
||||||
|
//force weather update after each config page Save
|
||||||
|
memset(s_options.conditions, 0,sizeof(s_options.conditions));
|
||||||
|
s_options.condition_code = DEFAULT_CONDITION_CODE;
|
||||||
|
|
||||||
|
s_options.weather_use_GPS = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_WEATHER_LOCATION:
|
||||||
|
snprintf(s_options.weather_location, sizeof(s_options.weather_location), "%s", t->value->cstring);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_WEATHER_FREQUENCY:
|
||||||
|
s_options.weather_frequency = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_BACKGROUND_COLOR:
|
||||||
|
s_options.background_color = (int)t->value->int32;
|
||||||
|
window_set_background_color(data->window, GColorFromHEX(s_options.background_color));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_TIME_COLOR:
|
||||||
|
s_options.time_color = (int)t->value->int32;
|
||||||
|
set_time_layers_color(GColorFromHEX(s_options.time_color));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_HR_COLOR:
|
||||||
|
s_options.hr_color = (int)t->value->int32;
|
||||||
|
set_hr_layer_color(GColorFromHEX(s_options.hr_color));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_MIN_COLOR:
|
||||||
|
s_options.min_color = (int)t->value->int32;
|
||||||
|
set_min_layers_color(GColorFromHEX(s_options.min_color));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_WD_COLOR:
|
||||||
|
s_options.wd_color = (int)t->value->int32;
|
||||||
|
set_wd_layers_color(GColorFromHEX(s_options.wd_color));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_WEATHERDATE_ALIGNMENT:
|
||||||
|
s_options.weatherdate_alignment = (int)t->value->int32;
|
||||||
|
#if defined(PBL_RECT)
|
||||||
|
text_layer_set_text_alignment(weather_layer1, row_alignment(s_options.weatherdate_alignment));
|
||||||
|
text_layer_set_text_alignment(date_layer, row_alignment(s_options.weatherdate_alignment));
|
||||||
|
#elif defined(PBL_ROUND)
|
||||||
|
text_layer_set_text_alignment(weather_layer1, row_alignment(DEFAULT_CHALK_ALIGNMENT));
|
||||||
|
text_layer_set_text_alignment(weather_layer2, row_alignment(DEFAULT_CHALK_ALIGNMENT));
|
||||||
|
text_layer_set_text_alignment(weather_layer_center, row_alignment(DEFAULT_CHALK_ALIGNMENT));
|
||||||
|
text_layer_set_text_alignment(date_layer, row_alignment(DEFAULT_CHALK_ALIGNMENT));
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_HOURMINUTES_ALIGNMENT:
|
||||||
|
row = &data->rows[HOUR_ROW];
|
||||||
|
s_options.hourminute_alignment = (int)t->value->int32;
|
||||||
|
text_layer_set_text_alignment(row->label, row_alignment(s_options.hourminute_alignment));
|
||||||
|
row = &data->rows[MINUTE_ROW1];
|
||||||
|
text_layer_set_text_alignment(row->label, row_alignment(s_options.hourminute_alignment));
|
||||||
|
row = &data->rows[MINUTE_ROW2];
|
||||||
|
text_layer_set_text_alignment(row->label, row_alignment(s_options.hourminute_alignment));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_WEATHERDATE_READABILITY:
|
||||||
|
s_options.weatherdate_readability = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_MINUTES_READABILITY:
|
||||||
|
s_options.minutes_readability = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_VIBBRATE_BT_STATUS:
|
||||||
|
s_options.vibrate_bt_status = (int)t->value->int32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_JS_READY:
|
||||||
|
s_options.pebble_js_ready = (int)t->value->int32;
|
||||||
|
#if DEBUG
|
||||||
|
APP_LOG(APP_LOG_LEVEL_DEBUG, "inbox_received_callback: s_options.pebble_js_ready: %d", s_options.pebble_js_ready);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Look for next item
|
||||||
|
t = dict_read_next(iterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
//check update weather & date layers
|
||||||
|
update_date_layer();
|
||||||
|
update_weather_layer();
|
||||||
|
}
|
||||||
|
|
||||||
|
char *translate_error(AppMessageResult result) {
|
||||||
|
switch (result) {
|
||||||
|
case APP_MSG_OK: return "APP_MSG_OK";
|
||||||
|
case APP_MSG_SEND_TIMEOUT: return "APP_MSG_SEND_TIMEOUT";
|
||||||
|
case APP_MSG_SEND_REJECTED: return "APP_MSG_SEND_REJECTED";
|
||||||
|
case APP_MSG_NOT_CONNECTED: return "APP_MSG_NOT_CONNECTED";
|
||||||
|
case APP_MSG_APP_NOT_RUNNING: return "APP_MSG_APP_NOT_RUNNING";
|
||||||
|
case APP_MSG_INVALID_ARGS: return "APP_MSG_INVALID_ARGS";
|
||||||
|
case APP_MSG_BUSY: return "APP_MSG_BUSY";
|
||||||
|
case APP_MSG_BUFFER_OVERFLOW: return "APP_MSG_BUFFER_OVERFLOW";
|
||||||
|
case APP_MSG_ALREADY_RELEASED: return "APP_MSG_ALREADY_RELEASED";
|
||||||
|
case APP_MSG_CALLBACK_ALREADY_REGISTERED: return "APP_MSG_CALLBACK_ALREADY_REGISTERED";
|
||||||
|
case APP_MSG_CALLBACK_NOT_REGISTERED: return "APP_MSG_CALLBACK_NOT_REGISTERED";
|
||||||
|
case APP_MSG_OUT_OF_MEMORY: return "APP_MSG_OUT_OF_MEMORY";
|
||||||
|
case APP_MSG_CLOSED: return "APP_MSG_CLOSED";
|
||||||
|
case APP_MSG_INTERNAL_ERROR: return "APP_MSG_INTERNAL_ERROR";
|
||||||
|
default: return "UNKNOWN ERROR";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void message_dropped(AppMessageResult reason, void *context) {
|
||||||
|
APP_LOG(APP_LOG_LEVEL_ERROR, "Dropped message! Reason given: %s", translate_error(reason));
|
||||||
|
}
|
||||||
|
|
||||||
|
void message_out_success(DictionaryIterator *iter, void *context) {
|
||||||
|
APP_LOG(APP_LOG_LEVEL_DEBUG, "Message sent.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void message_out_failed(DictionaryIterator *iter, AppMessageResult reason, void *context) {
|
||||||
|
APP_LOG(APP_LOG_LEVEL_DEBUG, "Failed to send message. Reason = %s", translate_error(reason));
|
||||||
|
}
|
||||||
7
src/c/messaging.h
Normal file
7
src/c/messaging.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void send(int key, int value, int key2, int value2, int key3, char value3[64]);
|
||||||
|
void inbox_received_callback(DictionaryIterator *iterator, void *context);
|
||||||
|
void message_dropped(AppMessageResult reason, void *context);
|
||||||
|
void message_out_success(DictionaryIterator *iter, void *context);
|
||||||
|
void message_out_failed(DictionaryIterator *iter, AppMessageResult reason, void *context);
|
||||||
217
src/c/num2words.c
Normal file
217
src/c/num2words.c
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
#include "num2words.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static const char* const ONES[] = {
|
||||||
|
"zero",
|
||||||
|
"one",
|
||||||
|
"two",
|
||||||
|
"three",
|
||||||
|
"four",
|
||||||
|
"five",
|
||||||
|
"six",
|
||||||
|
"seven",
|
||||||
|
"eight",
|
||||||
|
"nine"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* const TEENS[] ={
|
||||||
|
"",
|
||||||
|
"eleven",
|
||||||
|
"twelve",
|
||||||
|
"thirteen",
|
||||||
|
"fourteen",
|
||||||
|
"fifteen",
|
||||||
|
"sixteen",
|
||||||
|
"seventeen",
|
||||||
|
"eighteen",
|
||||||
|
"nineteen"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* const TEENS_SPLIT[][2] = {
|
||||||
|
{"", ""},
|
||||||
|
{"eleven",""},
|
||||||
|
{"twelve",""},
|
||||||
|
{"thirteen",""},
|
||||||
|
{"four","teen"},
|
||||||
|
{"fifteen",""},
|
||||||
|
{"sixteen",""},
|
||||||
|
{"seven","teen"},
|
||||||
|
{"eight","teen"},
|
||||||
|
{"nine","teen"}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* const TENS[] = {
|
||||||
|
"",
|
||||||
|
"ten",
|
||||||
|
"twenty",
|
||||||
|
"thirty",
|
||||||
|
"forty",
|
||||||
|
"fifty",
|
||||||
|
"sixty",
|
||||||
|
"seventy",
|
||||||
|
"eighty",
|
||||||
|
"ninety"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* STR_OH_TICK = "o'";
|
||||||
|
static const char* STR_O_TICK = "o";
|
||||||
|
static const char* STR_CLOCK = "clock";
|
||||||
|
static const char* STR_NOON = "noon";
|
||||||
|
static const char* STR_MIDNIGHT = "midnight";
|
||||||
|
static const char* STR_QUARTER = "quarter";
|
||||||
|
static const char* STR_TO = "to";
|
||||||
|
static const char* STR_PAST = "past";
|
||||||
|
static const char* STR_HALF = "half";
|
||||||
|
static const char* STR_AFTER = "after";
|
||||||
|
|
||||||
|
static size_t append_number(char* words, int num) {
|
||||||
|
int tens_val = num / 10 % 10;
|
||||||
|
int ones_val = num % 10;
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (tens_val > 0) {
|
||||||
|
if (tens_val == 1 && num != 10) {
|
||||||
|
strcat(words, TEENS[ones_val]);
|
||||||
|
return strlen(TEENS[ones_val]);
|
||||||
|
}
|
||||||
|
strcat(words, TENS[tens_val]);
|
||||||
|
len += strlen(TENS[tens_val]);
|
||||||
|
if (ones_val > 0) {
|
||||||
|
strcat(words, " ");
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ones_val > 0 || num == 0) {
|
||||||
|
strcat(words, ONES[ones_val]);
|
||||||
|
len += strlen(ONES[ones_val]);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fuzzy_time_to_words(int hours, int minutes, char* words) {
|
||||||
|
int fuzzy_hours = hours;
|
||||||
|
int fuzzy_minutes = ((minutes + 2) / 5) * 5;
|
||||||
|
|
||||||
|
// Handle hour & minute roll-over.
|
||||||
|
if (fuzzy_minutes > 55) {
|
||||||
|
fuzzy_minutes = 0;
|
||||||
|
fuzzy_hours += 1;
|
||||||
|
if (fuzzy_hours > 23) {
|
||||||
|
fuzzy_hours = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
time_to_common_words(fuzzy_hours, fuzzy_minutes, words);
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns number of lines written
|
||||||
|
void time_to_common_words(int hours, int minutes, char *words) {
|
||||||
|
// TODO: make an app-safe assert
|
||||||
|
// PBL_ASSERT(hours >= 0 && hours < 24, "Invalid number of hours");
|
||||||
|
// PBL_ASSERT(minutes >= 0 && minutes < 60, "Invalid number of minutes");
|
||||||
|
|
||||||
|
size_t written = 0;
|
||||||
|
strcpy(words, "");
|
||||||
|
|
||||||
|
if (minutes != 0 && (minutes >= 10 || minutes == 5 || hours == 0 || hours == 12)) {
|
||||||
|
if (minutes == 15) {
|
||||||
|
written += sprintf(words, "%s %s ", STR_QUARTER, STR_AFTER);
|
||||||
|
} else if (minutes == 45) {
|
||||||
|
written += sprintf(words, "%s %s ", STR_QUARTER, STR_TO);
|
||||||
|
hours = (hours + 1) % 24;
|
||||||
|
} else if (minutes == 30) {
|
||||||
|
written += sprintf(words, "%s %s ", STR_HALF, STR_PAST);
|
||||||
|
} else if (minutes < 30) {
|
||||||
|
written += append_number(words, minutes);
|
||||||
|
written += sprintf(words + written, " %s ", STR_AFTER);
|
||||||
|
} else {
|
||||||
|
written += append_number(words, 60 - minutes);
|
||||||
|
written += sprintf(words + written, " %s ", STR_TO);
|
||||||
|
hours = (hours + 1) % 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hours == 0) {
|
||||||
|
written += sprintf(words + written, "%s", STR_MIDNIGHT);
|
||||||
|
} else if (hours == 12) {
|
||||||
|
strcat(words, STR_NOON);
|
||||||
|
written += sprintf(words + written, "%s", STR_NOON);
|
||||||
|
} else {
|
||||||
|
written += append_number(words, hours % 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minutes < 10 && minutes != 5 && !(hours == 0 || hours == 12)) {
|
||||||
|
if (minutes == 0) {
|
||||||
|
sprintf(words + written, " %s%s", STR_OH_TICK, STR_CLOCK);
|
||||||
|
} else {
|
||||||
|
sprintf(words + written, " %s%s", STR_OH_TICK, ONES[minutes]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// o'clock (0) and plain number words (10..)
|
||||||
|
void minute_to_formal_words(int minutes, int displayPrefix, char *first_word, char *second_word) {
|
||||||
|
// PBL_ASSERT(minutes >= 0 && minutes < 60, "Invalid number of minutes");
|
||||||
|
|
||||||
|
strcpy(first_word, "");
|
||||||
|
strcpy(second_word, "");
|
||||||
|
|
||||||
|
|
||||||
|
if (minutes == 0) {
|
||||||
|
strcat(first_word, STR_OH_TICK);
|
||||||
|
strcat(first_word, STR_CLOCK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (minutes < 10) {
|
||||||
|
if (displayPrefix) {
|
||||||
|
strcat(first_word, STR_O_TICK); //add "o"
|
||||||
|
strcat(second_word, ONES[minutes%10]); //new
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strcat(first_word, ONES[minutes%10]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (minutes > 10 && minutes < 20) {
|
||||||
|
strcat(first_word, TEENS_SPLIT[(minutes - 10) % 10][0]);
|
||||||
|
strcat(second_word, TEENS_SPLIT[(minutes - 10) % 10][1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(first_word, TENS[minutes / 10 % 10]);
|
||||||
|
|
||||||
|
int minute_ones = minutes % 10;
|
||||||
|
if (minute_ones) {
|
||||||
|
strcat(second_word, ONES[minute_ones]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hour_to_12h_word(int hours, char *word) {
|
||||||
|
// PBL_ASSERT(hours >= 0 && hours < 24, "Invalid number of hours");
|
||||||
|
hours = hours % 12;
|
||||||
|
|
||||||
|
if (hours == 0) {
|
||||||
|
hours = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(word, "");
|
||||||
|
|
||||||
|
append_number(word, hours);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void hour_to_24h_word(int hours, char *words) {
|
||||||
|
// PBL_ASSERT(hours >= 0 && hours < 24, "Invalid number of hours");
|
||||||
|
|
||||||
|
hours = hours % 24;
|
||||||
|
|
||||||
|
strcpy(words, "");
|
||||||
|
|
||||||
|
append_number(words, hours);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user