Skip to content

Commit f128727

Browse files
Tom SvobodaTom Svoboda
Tom Svoboda
authored and
Tom Svoboda
committed
Initial commit
1 parent 5013c36 commit f128727

26 files changed

+399
-0
lines changed

resources/src/images/0.png

1.12 KB
Loading

resources/src/images/1.png

1005 Bytes
Loading

resources/src/images/2.png

1.17 KB
Loading

resources/src/images/3.png

1.17 KB
Loading

resources/src/images/4.png

1.08 KB
Loading

resources/src/images/5.png

1.13 KB
Loading

resources/src/images/6.png

1.19 KB
Loading

resources/src/images/7.png

1.08 KB
Loading

resources/src/images/8.png

1.17 KB
Loading

resources/src/images/9.png

1.2 KB
Loading
2.86 KB
Loading

resources/src/images/t0.png

1.13 KB
Loading

resources/src/images/t1.png

1016 Bytes
Loading

resources/src/images/t2.png

1.19 KB
Loading

resources/src/images/t3.png

1.18 KB
Loading

resources/src/images/t4.png

1.13 KB
Loading

resources/src/images/t5.png

1.14 KB
Loading

resources/src/images/t6.png

1.2 KB
Loading

resources/src/images/t7.png

1.1 KB
Loading

resources/src/images/t8.png

1.2 KB
Loading

resources/src/images/t9.png

1.19 KB
Loading

resources/src/resource_map.json

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
{
2+
"media": [
3+
{
4+
"defName": "IMAGE_THIN_9",
5+
"type": "png",
6+
"file": "images/t9.png"
7+
},
8+
{
9+
"defName": "IMAGE_THIN_8",
10+
"type": "png",
11+
"file": "images/t8.png"
12+
},
13+
{
14+
"defName": "IMAGE_THIN_7",
15+
"type": "png",
16+
"file": "images/t7.png"
17+
},
18+
{
19+
"defName": "IMAGE_THIN_6",
20+
"type": "png",
21+
"file": "images/t6.png"
22+
},
23+
{
24+
"defName": "IMAGE_THIN_5",
25+
"type": "png",
26+
"file": "images/t5.png"
27+
},
28+
{
29+
"defName": "IMAGE_THIN_4",
30+
"type": "png",
31+
"file": "images/t4.png"
32+
},
33+
{
34+
"defName": "IMAGE_THIN_3",
35+
"type": "png",
36+
"file": "images/t3.png"
37+
},
38+
{
39+
"defName": "IMAGE_THIN_2",
40+
"type": "png",
41+
"file": "images/t2.png"
42+
},
43+
{
44+
"defName": "IMAGE_THIN_1",
45+
"type": "png",
46+
"file": "images/t1.png"
47+
},
48+
{
49+
"defName": "IMAGE_BOLD_9",
50+
"type": "png",
51+
"file": "images/9.png"
52+
},
53+
{
54+
"defName": "IMAGE_BOLD_8",
55+
"type": "png",
56+
"file": "images/8.png"
57+
},
58+
{
59+
"defName": "IMAGE_BOLD_7",
60+
"type": "png",
61+
"file": "images/7.png"
62+
},
63+
{
64+
"defName": "IMAGE_BOLD_6",
65+
"type": "png",
66+
"file": "images/6.png"
67+
},
68+
{
69+
"defName": "IMAGE_BOLD_5",
70+
"type": "png",
71+
"file": "images/5.png"
72+
},
73+
{
74+
"defName": "IMAGE_BOLD_4",
75+
"type": "png",
76+
"file": "images/4.png"
77+
},
78+
{
79+
"defName": "IMAGE_BOLD_3",
80+
"type": "png",
81+
"file": "images/3.png"
82+
},
83+
{
84+
"defName": "IMAGE_BOLD_2",
85+
"type": "png",
86+
"file": "images/2.png"
87+
},
88+
{
89+
"defName": "IMAGE_BOLD_1",
90+
"type": "png",
91+
"file": "images/1.png"
92+
},
93+
{
94+
"defName": "IMAGE_THIN_0",
95+
"type": "png",
96+
"file": "images/t0.png"
97+
},
98+
{
99+
"defName": "IMAGE_BOLD_0",
100+
"type": "png",
101+
"file": "images/0.png"
102+
},
103+
{
104+
"defName": "IMAGE_MENU_ICON",
105+
"type": "png",
106+
"file": "images/menu_icon_roboto_big.png"
107+
}
108+
],
109+
"friendlyVersion": "VERSION",
110+
"versionDefName": "APP_RESOURCES"
111+
}

src/commons.h

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "pebble_os.h"
2+
#include "pebble_app.h"
3+
4+
Window window;
5+
6+
#define WIDTH_IMAGE 60
7+
#define HEIGHT_IMAGE 84

src/main.c

+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
//this app uses basic logic from "BigTime" watchface made by Pebble Technology to display big numbers
2+
//#include "pebble_fonts.h"
3+
#include "commons.h"
4+
#include "seconds.h"
5+
6+
#include "resource_ids.auto.h"
7+
8+
#define MY_UUID { 0xBE, 0x94, 0xEE, 0xE9, 0xB2, 0xAF, 0x47, 0xF5, 0x86, 0xC7, 0x5E, 0x44, 0xC2, 0xDA, 0x0F, 0xC5 }
9+
PBL_APP_INFO(MY_UUID, "Roboto Big", "Tom Svoboda", 0, 1, RESOURCE_ID_IMAGE_MENU_ICON, APP_INFO_WATCH_FACE);
10+
11+
12+
13+
14+
//
15+
// There's only enough memory to load about 6 of 10 required images
16+
// so we have to swap them in & out...
17+
//
18+
// We have one "slot" per digit location on screen.
19+
//
20+
// Because layers can only have one parent we load a digit for each
21+
// slot--even if the digit image is already in another slot.
22+
//
23+
// Slot on-screen layout:
24+
// 0 1
25+
// 2 3
26+
//
27+
28+
#define TOTAL_IMAGE_SLOTS 4
29+
30+
#define NUMBER_OF_IMAGES 20
31+
32+
const int IMAGE_RESOURCE_IDS[NUMBER_OF_IMAGES] = {
33+
RESOURCE_ID_IMAGE_BOLD_0, RESOURCE_ID_IMAGE_BOLD_1, RESOURCE_ID_IMAGE_BOLD_2,
34+
RESOURCE_ID_IMAGE_BOLD_3, RESOURCE_ID_IMAGE_BOLD_4, RESOURCE_ID_IMAGE_BOLD_5,
35+
RESOURCE_ID_IMAGE_BOLD_6, RESOURCE_ID_IMAGE_BOLD_7, RESOURCE_ID_IMAGE_BOLD_8,
36+
RESOURCE_ID_IMAGE_BOLD_9,
37+
RESOURCE_ID_IMAGE_THIN_0, RESOURCE_ID_IMAGE_THIN_1, RESOURCE_ID_IMAGE_THIN_2,
38+
RESOURCE_ID_IMAGE_THIN_3, RESOURCE_ID_IMAGE_THIN_4, RESOURCE_ID_IMAGE_THIN_5,
39+
RESOURCE_ID_IMAGE_THIN_6, RESOURCE_ID_IMAGE_THIN_7, RESOURCE_ID_IMAGE_THIN_8,
40+
RESOURCE_ID_IMAGE_THIN_9
41+
};
42+
43+
BmpContainer image_containers[TOTAL_IMAGE_SLOTS];
44+
45+
#define EMPTY_SLOT -1
46+
47+
// The state is either "empty" or the digit of the image currently in
48+
// the slot--which was going to be used to assist with de-duplication
49+
// but we're not doing that due to the one parent-per-layer
50+
// restriction mentioned above.
51+
int image_slot_state[TOTAL_IMAGE_SLOTS] = {EMPTY_SLOT, EMPTY_SLOT, EMPTY_SLOT, EMPTY_SLOT};
52+
53+
54+
void load_digit_image_into_slot(int slot_number, int digit_value) {
55+
/*
56+
57+
Loads the digit image from the application's resources and
58+
displays it on-screen in the correct location.
59+
60+
Each slot is a quarter of the screen.
61+
62+
*/
63+
64+
// TODO: Signal these error(s)?
65+
66+
if ((slot_number < 0) || (slot_number >= TOTAL_IMAGE_SLOTS)) {
67+
return;
68+
}
69+
70+
if ((digit_value < 0) || (digit_value > 19)) {
71+
return;
72+
}
73+
74+
if (image_slot_state[slot_number] != EMPTY_SLOT) {
75+
return;
76+
}
77+
78+
image_slot_state[slot_number] = digit_value;
79+
bmp_init_container(IMAGE_RESOURCE_IDS[digit_value], &image_containers[slot_number]);
80+
image_containers[slot_number].layer.layer.frame.origin.x = (slot_number % 2) * WIDTH_IMAGE;
81+
image_containers[slot_number].layer.layer.frame.origin.y = (slot_number / 2) * HEIGHT_IMAGE;
82+
layer_add_child(&window.layer, &image_containers[slot_number].layer.layer);
83+
84+
}
85+
86+
87+
void unload_digit_image_from_slot(int slot_number) {
88+
/*
89+
90+
Removes the digit from the display and unloads the image resource
91+
to free up RAM.
92+
93+
Can handle being called on an already empty slot.
94+
95+
*/
96+
97+
if (image_slot_state[slot_number] != EMPTY_SLOT) {
98+
layer_remove_from_parent(&image_containers[slot_number].layer.layer);
99+
bmp_deinit_container(&image_containers[slot_number]);
100+
image_slot_state[slot_number] = EMPTY_SLOT;
101+
}
102+
103+
}
104+
105+
void check_and_change(unsigned short digit, unsigned short slot_number, bool hide) {
106+
if (hide && (image_slot_state[slot_number] != EMPTY_SLOT)) {
107+
unload_digit_image_from_slot(slot_number);
108+
return;
109+
}
110+
else if (image_slot_state[slot_number] != digit) {
111+
unload_digit_image_from_slot(slot_number);
112+
load_digit_image_into_slot(slot_number, digit);
113+
return;
114+
}
115+
else {
116+
return;
117+
}
118+
}
119+
120+
void display_value(unsigned short value, unsigned short row_number, bool show_first_leading_zero) {
121+
/*
122+
123+
Displays a numeric value between 0 and 99 on screen.
124+
125+
Rows are ordered on screen as:
126+
127+
Row 0
128+
Row 1
129+
130+
Includes optional blanking of first leading zero,
131+
i.e. displays ' 0' rather than '00'.
132+
133+
*/
134+
value = value % 100; // Maximum of two digits per row.
135+
136+
// Column order is: | Column 0 | Column 1 |
137+
// (We process the columns in reverse order because that makes
138+
// extracting the digits from the value easier.)
139+
for (int column_number = 1; column_number >= 0; column_number--) {
140+
int slot_number = (row_number * 2) + column_number;
141+
if ((value == 0) && (column_number == 0) && !show_first_leading_zero) { //if number shouldn't be present on the screen
142+
check_and_change(0, slot_number, true);
143+
}
144+
else if (row_number == 0) {
145+
check_and_change(value % 10, slot_number, false);
146+
}
147+
else {
148+
check_and_change((value % 10)+10, slot_number, false);
149+
}
150+
value = value / 10;
151+
}
152+
}
153+
154+
155+
unsigned short get_display_hour(unsigned short hour) {
156+
157+
if (clock_is_24h_style()) {
158+
return hour;
159+
}
160+
161+
unsigned short display_hour = hour % 12;
162+
163+
// Converts "0" to "12"
164+
return display_hour ? display_hour : 12;
165+
166+
}
167+
168+
169+
void display_time(PblTm *tick_time) {
170+
display_value(get_display_hour(tick_time->tm_hour), 0, false);
171+
display_value(tick_time->tm_min, 1, true);
172+
count_seconds(tick_time->tm_sec);
173+
}
174+
175+
176+
void handle_second_tick(AppContextRef ctx, PebbleTickEvent *t) {
177+
(void)t;
178+
(void)ctx;
179+
180+
display_time(t->tick_time);
181+
}
182+
183+
184+
void handle_init(AppContextRef ctx) {
185+
(void)ctx;
186+
187+
window_init(&window, "RobotoBig watch");
188+
window_stack_push(&window, true);
189+
window_set_background_color(&window, GColorBlack);
190+
191+
seconds_init();
192+
193+
resource_init_current_app(&APP_RESOURCES);
194+
195+
// Avoids a blank screen on watch start.
196+
PblTm tick_time;
197+
198+
get_time(&tick_time);
199+
display_time(&tick_time);
200+
seconds_first_display(tick_time.tm_sec);
201+
}
202+
203+
204+
void handle_deinit(AppContextRef ctx) {
205+
(void)ctx;
206+
207+
for (int i = 0; i < TOTAL_IMAGE_SLOTS; i++) {
208+
unload_digit_image_from_slot(i);
209+
}
210+
211+
}
212+
213+
214+
void pbl_main(void *params) {
215+
PebbleAppHandlers handlers = {
216+
.init_handler = &handle_init,
217+
.deinit_handler = &handle_deinit,
218+
219+
.tick_info = {
220+
.tick_handler = &handle_second_tick,
221+
.tick_units = SECOND_UNIT
222+
}
223+
224+
};
225+
app_event_loop(params, &handlers);
226+
}

0 commit comments

Comments
 (0)