summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugin.h4
-rw-r--r--apps/plugins/SOURCES1
-rw-r--r--apps/plugins/SUBDIRS5
-rw-r--r--apps/plugins/bitmaps/native/SOURCES8
-rw-r--r--apps/plugins/bitmaps/native/clock_binary.112x64x1.bmpbin0 -> 1974 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_binary.128x128x16.bmpbin0 -> 3414 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_binary.138x110x2.bmpbin0 -> 2614 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_binary.160x128x16.bmpbin0 -> 5374 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_binary.160x128x2.bmpbin0 -> 3038 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_binary.220x176x16.bmpbin0 -> 10638 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_binary.320x240x16.bmpbin0 -> 21334 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_digits.112x64x1.bmpbin1262 -> 1102 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_digits.128x128x16.bmpbin25256 -> 21894 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_digits.138x110x2.bmpbin12600 -> 11062 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_digits.160x128x16.bmpbin39956 -> 34634 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_digits.160x128x2.bmpbin15776 -> 13818 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_digits.220x176x16.bmpbin79436 -> 68850 bytes
-rw-r--r--apps/plugins/bitmaps/native/clock_digits.320x240x16.bmpbin159656 -> 138374 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/SOURCES11
-rw-r--r--apps/plugins/bitmaps/remote_native/clock_binary_remote.112x64x1.bmpbin0 -> 1974 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/clock_digits_remote.112x64x1.bmpbin0 -> 1102 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/clock_logo_remote.112x64x1.bmpbin0 -> 864 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/clock_messages_remote.112x64x1.bmpbin0 -> 1408 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/clock_segments_remote.112x64x1.bmpbin0 -> 1102 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/clock_smalldigits_remote.112x64x1.bmpbin0 -> 582 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/clock_smallsegments_remote.112x64x1.bmpbin0 -> 686 bytes
-rw-r--r--apps/plugins/clock.c1673
-rw-r--r--apps/plugins/clock/Makefile112
-rw-r--r--apps/plugins/clock/SOURCES10
-rw-r--r--apps/plugins/clock/clock.c199
-rw-r--r--apps/plugins/clock/clock.h32
-rw-r--r--apps/plugins/clock/clock_bitmap_strings.c46
-rw-r--r--apps/plugins/clock/clock_bitmap_strings.h31
-rw-r--r--apps/plugins/clock/clock_bitmaps.c105
-rw-r--r--apps/plugins/clock/clock_bitmaps.h33
-rw-r--r--apps/plugins/clock/clock_counter.c42
-rw-r--r--apps/plugins/clock/clock_counter.h19
-rw-r--r--apps/plugins/clock/clock_draw.c103
-rw-r--r--apps/plugins/clock/clock_draw.h32
-rw-r--r--apps/plugins/clock/clock_draw_analog.c217
-rw-r--r--apps/plugins/clock/clock_draw_analog.h32
-rw-r--r--apps/plugins/clock/clock_draw_binary.c51
-rw-r--r--apps/plugins/clock/clock_draw_binary.h27
-rw-r--r--apps/plugins/clock/clock_draw_digital.c87
-rw-r--r--apps/plugins/clock/clock_draw_digital.h31
-rw-r--r--apps/plugins/clock/clock_menu.c246
-rw-r--r--apps/plugins/clock/clock_menu.h7
-rw-r--r--apps/plugins/clock/clock_settings.c200
-rw-r--r--apps/plugins/clock/clock_settings.h91
-rw-r--r--apps/plugins/lib/SOURCES1
-rw-r--r--apps/plugins/lib/picture.c70
-rw-r--r--apps/plugins/lib/picture.h40
-rw-r--r--apps/plugins/lib/xlcd.h3
-rw-r--r--apps/plugins/lib/xlcd_draw.c135
-rw-r--r--apps/screen_access.c4
-rw-r--r--apps/screen_access.h3
56 files changed, 1967 insertions, 1744 deletions
diff --git a/apps/plugin.h b/apps/plugin.h
index 5146e18139..61cfe96e8d 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -112,12 +112,12 @@
112#define PLUGIN_MAGIC 0x526F634B /* RocK */ 112#define PLUGIN_MAGIC 0x526F634B /* RocK */
113 113
114/* increase this every time the api struct changes */ 114/* increase this every time the api struct changes */
115#define PLUGIN_API_VERSION 68 115#define PLUGIN_API_VERSION 69
116 116
117/* update this to latest version if a change to the api struct breaks 117/* update this to latest version if a change to the api struct breaks
118 backwards compatibility (and please take the opportunity to sort in any 118 backwards compatibility (and please take the opportunity to sort in any
119 new function which are "waiting" at the end of the function table) */ 119 new function which are "waiting" at the end of the function table) */
120#define PLUGIN_MIN_API_VERSION 68 120#define PLUGIN_MIN_API_VERSION 69
121 121
122/* plugin return codes */ 122/* plugin return codes */
123enum plugin_status { 123enum plugin_status {
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 96a7ebec2d..31d94d5811 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -82,7 +82,6 @@ vu_meter.c
82wormlet.c 82wormlet.c
83 83
84#if CONFIG_RTC 84#if CONFIG_RTC
85clock.c
86#if CONFIG_KEYPAD == RECORDER_PAD /* Recorder models only for now */ 85#if CONFIG_KEYPAD == RECORDER_PAD /* Recorder models only for now */
87calendar.c 86calendar.c
88#endif 87#endif
diff --git a/apps/plugins/SUBDIRS b/apps/plugins/SUBDIRS
index 6665f41e4e..3f0fc9051b 100644
--- a/apps/plugins/SUBDIRS
+++ b/apps/plugins/SUBDIRS
@@ -3,6 +3,11 @@
3/* For all targets */ 3/* For all targets */
4 4
5/* For various targets... */ 5/* For various targets... */
6
7#if CONFIG_RTC
8clock
9#endif
10
6#if (CONFIG_KEYPAD == RECORDER_PAD) || defined(HAVE_LCD_COLOR) \ 11#if (CONFIG_KEYPAD == RECORDER_PAD) || defined(HAVE_LCD_COLOR) \
7 || defined(IRIVER_H100_SERIES) || defined(IAUDIO_M5) 12 || defined(IRIVER_H100_SERIES) || defined(IAUDIO_M5)
8rockboy 13rockboy
diff --git a/apps/plugins/bitmaps/native/SOURCES b/apps/plugins/bitmaps/native/SOURCES
index 05029c430c..93939c95f7 100644
--- a/apps/plugins/bitmaps/native/SOURCES
+++ b/apps/plugins/bitmaps/native/SOURCES
@@ -112,6 +112,7 @@ chessbox_pieces.64x64x1.bmp
112 112
113/* Clock */ 113/* Clock */
114#if (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) && (LCD_DEPTH >= 16) 114#if (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240) && (LCD_DEPTH >= 16)
115clock_binary.320x240x16.bmp
115clock_digits.320x240x16.bmp 116clock_digits.320x240x16.bmp
116clock_smalldigits.320x240x16.bmp 117clock_smalldigits.320x240x16.bmp
117clock_segments.320x240x16.bmp 118clock_segments.320x240x16.bmp
@@ -119,6 +120,7 @@ clock_smallsegments.320x240x16.bmp
119clock_logo.320x240x16.bmp 120clock_logo.320x240x16.bmp
120clock_messages.320x240x16.bmp 121clock_messages.320x240x16.bmp
121#elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176) && (LCD_DEPTH >= 16) 122#elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176) && (LCD_DEPTH >= 16)
123clock_binary.220x176x16.bmp
122clock_digits.220x176x16.bmp 124clock_digits.220x176x16.bmp
123clock_smalldigits.220x176x16.bmp 125clock_smalldigits.220x176x16.bmp
124clock_segments.220x176x16.bmp 126clock_segments.220x176x16.bmp
@@ -126,6 +128,7 @@ clock_smallsegments.220x176x16.bmp
126clock_logo.220x176x16.bmp 128clock_logo.220x176x16.bmp
127clock_messages.220x176x16.bmp 129clock_messages.220x176x16.bmp
128#elif (LCD_WIDTH >= 176) && (LCD_HEIGHT >= 132) && (LCD_DEPTH >= 16) 130#elif (LCD_WIDTH >= 176) && (LCD_HEIGHT >= 132) && (LCD_DEPTH >= 16)
131clock_binary.160x128x16.bmp
129clock_digits.160x128x16.bmp 132clock_digits.160x128x16.bmp
130clock_smalldigits.160x128x16.bmp 133clock_smalldigits.160x128x16.bmp
131clock_segments.160x128x16.bmp 134clock_segments.160x128x16.bmp
@@ -133,6 +136,7 @@ clock_smallsegments.160x128x16.bmp
133clock_logo.176x132x16.bmp 136clock_logo.176x132x16.bmp
134clock_messages.176x132x16.bmp 137clock_messages.176x132x16.bmp
135#elif (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128) && (LCD_DEPTH >= 16) 138#elif (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128) && (LCD_DEPTH >= 16)
139clock_binary.160x128x16.bmp
136clock_digits.160x128x16.bmp 140clock_digits.160x128x16.bmp
137clock_smalldigits.160x128x16.bmp 141clock_smalldigits.160x128x16.bmp
138clock_segments.160x128x16.bmp 142clock_segments.160x128x16.bmp
@@ -140,6 +144,7 @@ clock_smallsegments.160x128x16.bmp
140clock_logo.160x128x16.bmp 144clock_logo.160x128x16.bmp
141clock_messages.160x128x16.bmp 145clock_messages.160x128x16.bmp
142#elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 128) && (LCD_DEPTH >= 16) 146#elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 128) && (LCD_DEPTH >= 16)
147clock_binary.128x128x16.bmp
143clock_digits.128x128x16.bmp 148clock_digits.128x128x16.bmp
144clock_smalldigits.128x128x16.bmp 149clock_smalldigits.128x128x16.bmp
145clock_segments.128x128x16.bmp 150clock_segments.128x128x16.bmp
@@ -147,6 +152,7 @@ clock_smallsegments.128x128x16.bmp
147clock_logo.128x128x16.bmp 152clock_logo.128x128x16.bmp
148clock_messages.128x128x16.bmp 153clock_messages.128x128x16.bmp
149#elif (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128) && (LCD_DEPTH >= 2) 154#elif (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128) && (LCD_DEPTH >= 2)
155clock_binary.160x128x2.bmp
150clock_digits.160x128x2.bmp 156clock_digits.160x128x2.bmp
151clock_smalldigits.160x128x2.bmp 157clock_smalldigits.160x128x2.bmp
152clock_segments.160x128x2.bmp 158clock_segments.160x128x2.bmp
@@ -154,6 +160,7 @@ clock_smallsegments.160x128x2.bmp
154clock_logo.160x128x2.bmp 160clock_logo.160x128x2.bmp
155clock_messages.160x128x2.bmp 161clock_messages.160x128x2.bmp
156#elif (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110) && (LCD_DEPTH >= 2) 162#elif (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110) && (LCD_DEPTH >= 2)
163clock_binary.138x110x2.bmp
157clock_digits.138x110x2.bmp 164clock_digits.138x110x2.bmp
158clock_smalldigits.160x128x2.bmp 165clock_smalldigits.160x128x2.bmp
159clock_segments.138x110x2.bmp 166clock_segments.138x110x2.bmp
@@ -161,6 +168,7 @@ clock_smallsegments.160x128x2.bmp
161clock_logo.138x110x2.bmp 168clock_logo.138x110x2.bmp
162clock_messages.138x110x2.bmp 169clock_messages.138x110x2.bmp
163#elif (LCD_WIDTH >= 112) && (LCD_HEIGHT >= 64) && (LCD_DEPTH >= 1) 170#elif (LCD_WIDTH >= 112) && (LCD_HEIGHT >= 64) && (LCD_DEPTH >= 1)
171clock_binary.112x64x1.bmp
164clock_digits.112x64x1.bmp 172clock_digits.112x64x1.bmp
165clock_smalldigits.112x64x1.bmp 173clock_smalldigits.112x64x1.bmp
166clock_segments.112x64x1.bmp 174clock_segments.112x64x1.bmp
diff --git a/apps/plugins/bitmaps/native/clock_binary.112x64x1.bmp b/apps/plugins/bitmaps/native/clock_binary.112x64x1.bmp
new file mode 100644
index 0000000000..a42401c293
--- /dev/null
+++ b/apps/plugins/bitmaps/native/clock_binary.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_binary.128x128x16.bmp b/apps/plugins/bitmaps/native/clock_binary.128x128x16.bmp
new file mode 100644
index 0000000000..9f98dc2753
--- /dev/null
+++ b/apps/plugins/bitmaps/native/clock_binary.128x128x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_binary.138x110x2.bmp b/apps/plugins/bitmaps/native/clock_binary.138x110x2.bmp
new file mode 100644
index 0000000000..0596c71e3c
--- /dev/null
+++ b/apps/plugins/bitmaps/native/clock_binary.138x110x2.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_binary.160x128x16.bmp b/apps/plugins/bitmaps/native/clock_binary.160x128x16.bmp
new file mode 100644
index 0000000000..d1982ba94a
--- /dev/null
+++ b/apps/plugins/bitmaps/native/clock_binary.160x128x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_binary.160x128x2.bmp b/apps/plugins/bitmaps/native/clock_binary.160x128x2.bmp
new file mode 100644
index 0000000000..9808694a6c
--- /dev/null
+++ b/apps/plugins/bitmaps/native/clock_binary.160x128x2.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_binary.220x176x16.bmp b/apps/plugins/bitmaps/native/clock_binary.220x176x16.bmp
new file mode 100644
index 0000000000..3cc2bd15cb
--- /dev/null
+++ b/apps/plugins/bitmaps/native/clock_binary.220x176x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_binary.320x240x16.bmp b/apps/plugins/bitmaps/native/clock_binary.320x240x16.bmp
new file mode 100644
index 0000000000..158ac90ae9
--- /dev/null
+++ b/apps/plugins/bitmaps/native/clock_binary.320x240x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_digits.112x64x1.bmp b/apps/plugins/bitmaps/native/clock_digits.112x64x1.bmp
index c8738029cb..cd4a3ba152 100644
--- a/apps/plugins/bitmaps/native/clock_digits.112x64x1.bmp
+++ b/apps/plugins/bitmaps/native/clock_digits.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_digits.128x128x16.bmp b/apps/plugins/bitmaps/native/clock_digits.128x128x16.bmp
index 87694982c9..c9edb25dd0 100644
--- a/apps/plugins/bitmaps/native/clock_digits.128x128x16.bmp
+++ b/apps/plugins/bitmaps/native/clock_digits.128x128x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_digits.138x110x2.bmp b/apps/plugins/bitmaps/native/clock_digits.138x110x2.bmp
index d3a3ea15a4..69a2fef25b 100644
--- a/apps/plugins/bitmaps/native/clock_digits.138x110x2.bmp
+++ b/apps/plugins/bitmaps/native/clock_digits.138x110x2.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_digits.160x128x16.bmp b/apps/plugins/bitmaps/native/clock_digits.160x128x16.bmp
index 6b2b41c496..7fccf93928 100644
--- a/apps/plugins/bitmaps/native/clock_digits.160x128x16.bmp
+++ b/apps/plugins/bitmaps/native/clock_digits.160x128x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_digits.160x128x2.bmp b/apps/plugins/bitmaps/native/clock_digits.160x128x2.bmp
index 6a82bb05d0..75abec3fa4 100644
--- a/apps/plugins/bitmaps/native/clock_digits.160x128x2.bmp
+++ b/apps/plugins/bitmaps/native/clock_digits.160x128x2.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_digits.220x176x16.bmp b/apps/plugins/bitmaps/native/clock_digits.220x176x16.bmp
index 41fef2bc1e..c18e7aeb35 100644
--- a/apps/plugins/bitmaps/native/clock_digits.220x176x16.bmp
+++ b/apps/plugins/bitmaps/native/clock_digits.220x176x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/clock_digits.320x240x16.bmp b/apps/plugins/bitmaps/native/clock_digits.320x240x16.bmp
index 0da719cd54..8a6ea68d43 100644
--- a/apps/plugins/bitmaps/native/clock_digits.320x240x16.bmp
+++ b/apps/plugins/bitmaps/native/clock_digits.320x240x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/remote_native/SOURCES b/apps/plugins/bitmaps/remote_native/SOURCES
index d59621d686..a884ebb24a 100644
--- a/apps/plugins/bitmaps/remote_native/SOURCES
+++ b/apps/plugins/bitmaps/remote_native/SOURCES
@@ -4,3 +4,14 @@ osx.dummy.bmp
4 4
5/* Jackpot */ 5/* Jackpot */
6jackpot_slots_remote.15x210x1.bmp 6jackpot_slots_remote.15x210x1.bmp
7
8clock_logo_remote.112x64x1.bmp
9clock_messages_remote.112x64x1.bmp
10
11clock_binary_remote.112x64x1.bmp
12
13clock_digits_remote.112x64x1.bmp
14clock_smalldigits_remote.112x64x1.bmp
15
16clock_segments_remote.112x64x1.bmp
17clock_smallsegments_remote.112x64x1.bmp
diff --git a/apps/plugins/bitmaps/remote_native/clock_binary_remote.112x64x1.bmp b/apps/plugins/bitmaps/remote_native/clock_binary_remote.112x64x1.bmp
new file mode 100644
index 0000000000..a42401c293
--- /dev/null
+++ b/apps/plugins/bitmaps/remote_native/clock_binary_remote.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/remote_native/clock_digits_remote.112x64x1.bmp b/apps/plugins/bitmaps/remote_native/clock_digits_remote.112x64x1.bmp
new file mode 100644
index 0000000000..cd4a3ba152
--- /dev/null
+++ b/apps/plugins/bitmaps/remote_native/clock_digits_remote.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/remote_native/clock_logo_remote.112x64x1.bmp b/apps/plugins/bitmaps/remote_native/clock_logo_remote.112x64x1.bmp
new file mode 100644
index 0000000000..47b6cddf73
--- /dev/null
+++ b/apps/plugins/bitmaps/remote_native/clock_logo_remote.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/remote_native/clock_messages_remote.112x64x1.bmp b/apps/plugins/bitmaps/remote_native/clock_messages_remote.112x64x1.bmp
new file mode 100644
index 0000000000..8cdc43155f
--- /dev/null
+++ b/apps/plugins/bitmaps/remote_native/clock_messages_remote.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/remote_native/clock_segments_remote.112x64x1.bmp b/apps/plugins/bitmaps/remote_native/clock_segments_remote.112x64x1.bmp
new file mode 100644
index 0000000000..15caccec22
--- /dev/null
+++ b/apps/plugins/bitmaps/remote_native/clock_segments_remote.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/remote_native/clock_smalldigits_remote.112x64x1.bmp b/apps/plugins/bitmaps/remote_native/clock_smalldigits_remote.112x64x1.bmp
new file mode 100644
index 0000000000..54a0802d20
--- /dev/null
+++ b/apps/plugins/bitmaps/remote_native/clock_smalldigits_remote.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/remote_native/clock_smallsegments_remote.112x64x1.bmp b/apps/plugins/bitmaps/remote_native/clock_smallsegments_remote.112x64x1.bmp
new file mode 100644
index 0000000000..767e25556e
--- /dev/null
+++ b/apps/plugins/bitmaps/remote_native/clock_smallsegments_remote.112x64x1.bmp
Binary files differ
diff --git a/apps/plugins/clock.c b/apps/plugins/clock.c
deleted file mode 100644
index 71415c03d4..0000000000
--- a/apps/plugins/clock.c
+++ /dev/null
@@ -1,1673 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2003 Zakk Roberts
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20/*****************************
21 * RELEASE NOTES
22
23***** VERSION 4.00 **
24New almost entirely bitmap based display. Scales to all resolutions. Combined
25Digital and LCD modes into one. Use Rockbox menu code for the menu. Removed
26count-down option. A couple new options. Source code reworked, improved, cleaned
27up.
28
29***** VERSION 3.10 **
30Drawing now scales for the display - still needs updated bitmaps for the binary
31and plain mode. The Time's Up logo could also be updated.
32
33***** VERSION 3.00 **
34New, simpler UI - every screen can be accessed from the new Main Menu.
35Huge code cleanup - many major functions rewritten and optimized,
36targeting scalability. Number of variables reduced majorly.
37New clock mode: Plain (simple, large text). ON now controls counter
38(press toggle/hold reset). Fancier credits roll. New logo. iRiver and iPod ports
39are working but not yet scaled to fit their LCDs.
40
41***** VERSION 2.60 **
42Fixed general settings typo, split up settings function, added cursor animations,
43and updated cursor look (rounded edges).
44
45***** VERSION 2.51 **
46"Show Counter" option is now saved to disk
47
48***** VERSION 2.50 **
49New general settings mode added, reworked options screen, cleaned up a few
50things and removed redundant code, faster load_settings(), fixed a
51help-screen bug (thanks to zeekoe)
52
53***** VERSION 2.40 **
54Cleaned and optimized code, removed unused code/bitmaps, credits screen updated,
55centered text all over, general settings added at ON+F3,
56new arrow bitmap for general settings and mode selector,
57bugfix: 12:00AM is no longer 00:00AM
58
59***** VERSION 2.31 **
60Fixed credits roll - now displays all names. Features
61improved animations. Also revised release notes.
62
63***** VERSION 2.30 **
64Tab indentation removed, and Counter screen added
65at ON+F2, with countdown options
66
67***** VERSION 2.22 **
68Fixed two bugs:
69Digital settings are now independent of LCD settings
7012/24h "Analog" settings are now displayed correctly.
71
72***** VERSION 2.21 **
73-Changed the behaviour of F2
74
75***** VERSION 2.20 **
76Few small bugs taken care of. New features:
77New binary mode, new mode selector, "counter", and redesigned help screen.
78
79***** VERSION 2.10 **
80New bug fixes, and some new features:
81an LCD imitation mode, and American and European date modes.
82
83***** VERSION 2.00 **
84Major update, lots of bugfixes and new features.
85Fullscreen mode introduced, modes have independent settings, credit roll
86added, options screen reworked, logo selector, and -much- cleaner code.
87
88***** VERSION 1.0 **
89Original release, featuring analog/digital modes and a few options.
90*****************************/
91#include "plugin.h"
92#include "time.h"
93#include "checkbox.h"
94#include "xlcd.h"
95#include "oldmenuapi.h"
96#include "fixedpoint.h"
97#include "pluginlib_actions.h"
98
99PLUGIN_HEADER
100
101/* External bitmap references */
102#include "clock_digits.h"
103#include "clock_smalldigits.h"
104#include "clock_smallsegments.h"
105#include "clock_messages.h"
106#include "clock_logo.h"
107#include "clock_segments.h"
108
109/* Bitmap positions/deltas, per LCD size */
110#if (LCD_WIDTH >= 112) && (LCD_HEIGHT >= 64) && (LCD_DEPTH >= 1) /* Archos */
111#define LCD_OFFSET 1
112#define HAND_W 2
113#else
114#define LCD_OFFSET 1.5
115#define HAND_W 3
116#endif
117
118#define DIGIT_WIDTH BMPWIDTH_clock_digits
119#define DIGIT_HEIGHT (BMPHEIGHT_clock_digits/15)
120#define SMALLDIGIT_WIDTH BMPWIDTH_clock_smalldigits
121#define SMALLDIGIT_HEIGHT (BMPHEIGHT_clock_smalldigits/13)
122#define SMALLSEG_WIDTH BMPWIDTH_clock_smallsegments
123#define SMALLSEG_HEIGHT (BMPHEIGHT_clock_smallsegments/13)
124#define MESSAGE_WIDTH BMPWIDTH_clock_messages
125#define MESSAGE_HEIGHT (BMPHEIGHT_clock_messages/6)
126#define LOGO_WIDTH BMPWIDTH_clock_logo
127#define LOGO_HEIGHT BMPHEIGHT_clock_logo
128
129/* Parts of larger bitmaps */
130#define COLON 10
131#define DOT_FILLED 11
132#define DOT_EMPTY 12
133#define ICON_PM 13
134#define ICON_AM 14
135#define SEGMENT_AM 11
136#define SEGMENT_PM 12
137#define SLASH 11
138#define PERIOD 12
139
140/* Message names/values */
141#define MESSAGE_LOADING 0
142#define MESSAGE_LOADED 1
143#define MESSAGE_ERRLOAD 2
144#define MESSAGE_SAVING 3
145#define MESSAGE_SAVED 4
146#define MESSAGE_ERRSAVE 5
147
148/* Some macros to simplify drawing et al */
149#define draw_digit( num, x, y )\
150 rb->lcd_bitmap_part( clock_digits, 0, num * DIGIT_HEIGHT, \
151 DIGIT_WIDTH, x, y, DIGIT_WIDTH, DIGIT_HEIGHT )
152#define draw_smalldigit( num, x, y )\
153 rb->lcd_bitmap_part( clock_smalldigits, 0, num * SMALLDIGIT_HEIGHT, \
154 SMALLDIGIT_WIDTH, x, y, SMALLDIGIT_WIDTH, SMALLDIGIT_HEIGHT )
155#define draw_segment( num, x, y )\
156 rb->lcd_bitmap_part( clock_segments, 0, num * DIGIT_HEIGHT, \
157 DIGIT_WIDTH, x, y, DIGIT_WIDTH, DIGIT_HEIGHT )
158#define draw_smallsegment( num, x, y )\
159 rb->lcd_bitmap_part( clock_smallsegments, 0, num * SMALLSEG_HEIGHT, \
160 SMALLSEG_WIDTH, x, y, SMALLSEG_WIDTH, SMALLSEG_HEIGHT )
161#define draw_message( msg, ypos )\
162 rb->lcd_bitmap_part( clock_messages, 0, msg*MESSAGE_HEIGHT, MESSAGE_WIDTH, \
163 0, LCD_HEIGHT-(MESSAGE_HEIGHT*ypos), MESSAGE_WIDTH, MESSAGE_HEIGHT )
164#define DIGIT_XOFS(x) (LCD_WIDTH-x*DIGIT_WIDTH)/2
165#define DIGIT_YOFS(x) (LCD_HEIGHT-x*DIGIT_HEIGHT)/2
166#define SMALLDIGIT_XOFS(x) (LCD_WIDTH-x*SMALLDIGIT_WIDTH)/2
167#define SMALLDIGIT_YOFS(x) (LCD_HEIGHT-x*SMALLDIGIT_HEIGHT)/2
168#define SMALLSEG_XOFS(x) (LCD_WIDTH-x*SMALLSEG_WIDTH)/2
169#define SMALLSEG_YOFS(x) (LCD_HEIGHT-x*SMALLSEG_HEIGHT)/2
170
171/* Keymaps */
172const struct button_mapping* plugin_contexts[]={
173 generic_actions,
174 generic_directions
175};
176
177#define ACTION_COUNTER_TOGGLE PLA_FIRE
178#define ACTION_COUNTER_RESET PLA_FIRE_REPEAT
179#define ACTION_MENU PLA_MENU
180#define ACTION_EXIT PLA_QUIT
181#define ACTION_MODE_NEXT PLA_RIGHT
182#define ACTION_MODE_PREV PLA_LEFT
183
184/************
185 * Prototypes
186 ***********/
187void save_settings(bool interface);
188
189/********************
190 * Misc counter stuff
191 *******************/
192int start_tick = 0;
193int passed_time = 0;
194int counter = 0;
195int displayed_value = 0;
196int count_h, count_m, count_s;
197bool counting = false;
198
199/********************
200 * Everything else...
201 *******************/
202bool idle_poweroff = true; /* poweroff activated or not? */
203bool exit_clock = false; /* when true, the main plugin loop will exit */
204
205static struct plugin_api* rb;
206
207/***********************************************************************
208 * Used for hands to define lengths at a given time, analog + fullscreen
209 **********************************************************************/
210unsigned int xminute[61];
211unsigned int yminute[61];
212unsigned int yhour[61];
213unsigned int xhour[61];
214unsigned int xminute_full[61];
215unsigned int yminute_full[61];
216unsigned int xhour_full[61];
217unsigned int yhour_full[61];
218
219/* settings are saved to this location */
220static const char default_filename[] = "/.rockbox/rocks/.clock_settings";
221
222/*********************************************************
223 * Some arrays/definitions for drawing settings/menu text.
224 ********************************************************/
225#define ANALOG 1
226#define FULLSCREEN 2
227#define DIGITAL 3
228#define PLAIN 4
229#define BINARY 5
230#define CLOCK_MODES 5
231
232#define analog_date 0
233#define analog_secondhand 1
234#define analog_time 2
235#define digital_seconds 0
236#define digital_date 1
237#define digital_blinkcolon 2
238#define digital_format 3
239#define fullscreen_border 0
240#define fullscreen_secondhand 1
241#define binary_mode 0
242#define plain_format 0
243#define plain_seconds 1
244#define plain_date 2
245#define plain_blinkcolon 3
246#define general_counter 0
247#define general_savesetting 1
248#define general_backlight 2
249
250/* Option structs (possible selections per each option) */
251static const struct opt_items noyes_text[] = {
252 { "No", -1 },
253 { "Yes", -1 }
254};
255
256static const struct opt_items backlight_settings_text[] = {
257 { "Always Off", -1 },
258 { "Rockbox setting", -1 },
259 { "Always On", -1 }
260};
261static const struct opt_items idle_poweroff_text[] = {
262 { "Disabled", -1 },
263 { "Enabled", -1 }
264};
265static const struct opt_items counting_direction_text[] = {
266 {"Down", -1},
267 {"Up", -1}
268};
269static const struct opt_items date_format_text[] = {
270 { "No", -1 },
271 { "American format", -1 },
272 { "European format", -1 }
273};
274
275static const struct opt_items analog_time_text[] = {
276 { "No", -1 },
277 { "24-hour Format", -1 },
278 { "12-hour Format", -1 }
279};
280
281static const struct opt_items time_format_text[] = {
282 { "24-hour Format", -1 },
283 { "12-hour Format", -1 }
284};
285
286static const struct opt_items binary_mode_text[] = {
287 { "Numbers", -1 },
288 { "Dots", -1 }
289};
290
291/*****************************************
292 * All settings, saved to default_filename
293 ****************************************/
294struct saved_settings
295{
296 int clock; /* clock mode */
297 int general[4]; /* general settings*/
298 int analog[3];
299 int digital[4];
300 int fullscreen[2];
301 int binary[1];
302 int plain[4];
303} clock_settings;
304
305/************************
306 * Setting default values
307 ***********************/
308void reset_settings(void)
309{
310 clock_settings.clock = 1;
311 clock_settings.general[general_counter] = 1;
312 clock_settings.general[general_savesetting] = 1;
313 clock_settings.general[general_backlight] = 2;
314 clock_settings.analog[analog_date] = 0;
315 clock_settings.analog[analog_secondhand] = true;
316 clock_settings.analog[analog_time] = false;
317 clock_settings.digital[digital_seconds] = 1;
318 clock_settings.digital[digital_date] = 1;
319 clock_settings.digital[digital_blinkcolon] = false;
320 clock_settings.digital[digital_format] = true;
321 clock_settings.fullscreen[fullscreen_border] = true;
322 clock_settings.fullscreen[fullscreen_secondhand] = true;
323 clock_settings.plain[plain_format] = true;
324 clock_settings.plain[plain_seconds] = true;
325 clock_settings.plain[plain_date] = 1;
326 clock_settings.plain[plain_blinkcolon] = false;
327}
328
329/**************************************************************
330 * Simple function to check if we're switching to digital mode,
331 * and if so, set bg/fg colors appropriately.
332 *************************************************************/
333void set_digital_colors(void)
334{
335#ifdef HAVE_LCD_COLOR /* color LCDs.. */
336 if(clock_settings.clock == DIGITAL)
337 {
338 rb->lcd_set_foreground(LCD_WHITE);
339 rb->lcd_set_background(LCD_BLACK);
340 }
341 else
342 {
343 rb->lcd_set_foreground(LCD_BLACK);
344 rb->lcd_set_background(LCD_RGBPACK(180,200,230));
345 }
346#elif LCD_DEPTH >= 2
347 if(clock_settings.clock == DIGITAL)
348 {
349 rb->lcd_set_foreground(LCD_WHITE);
350 rb->lcd_set_background(LCD_BLACK);
351 }
352 else
353 {
354 rb->lcd_set_foreground(LCD_BLACK);
355 rb->lcd_set_background(LCD_WHITE);
356 }
357#endif
358}
359
360/*************************************************************
361 * Simple function to set standard black-on-light blue colors.
362 ************************************************************/
363void set_standard_colors(void)
364{
365#ifdef HAVE_LCD_COLOR /* color LCDs only.. */
366 rb->lcd_set_foreground(LCD_BLACK);
367 rb->lcd_set_background(LCD_RGBPACK(180,200,230));
368#elif LCD_DEPTH >= 2
369 rb->lcd_set_foreground(LCD_BLACK);
370 rb->lcd_set_background(LCD_WHITE);
371#endif
372}
373
374/**************************
375 * Cleanup on plugin return
376 *************************/
377void cleanup(void *parameter)
378{
379 (void)parameter;
380
381 if(clock_settings.general[general_savesetting] == 1)
382 save_settings(true);
383
384 /* restore set backlight timeout */
385 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
386}
387
388/****************
389 * Shows the logo
390 ***************/
391void show_clock_logo(void)
392{
393#ifdef HAVE_LCD_COLOR
394 rb->lcd_set_foreground(LCD_BLACK);
395 rb->lcd_set_background(LCD_RGBPACK(180,200,230));
396#endif
397
398 rb->lcd_clear_display();;
399
400 rb->lcd_bitmap(clock_logo, 0, 0, LOGO_WIDTH, LOGO_HEIGHT);
401
402 rb->lcd_update();
403}
404
405/********************************
406 * Saves "saved_settings" to disk
407 *******************************/
408void save_settings(bool interface)
409{
410 int fd;
411
412 if(interface)
413 {
414 rb->lcd_clear_display();
415 show_clock_logo();
416
417 draw_message(MESSAGE_SAVING, 1);
418
419 rb->lcd_update();
420 }
421
422 fd = rb->creat(default_filename); /* create the settings file */
423
424 if(fd >= 0) /* file exists, save successful */
425 {
426 rb->write (fd, &clock_settings, sizeof(struct saved_settings));
427 rb->close(fd);
428
429 if(interface)
430 {
431 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
432 rb->lcd_fillrect(0, LCD_HEIGHT-MESSAGE_HEIGHT, LCD_WIDTH, MESSAGE_HEIGHT);
433 rb->lcd_set_drawmode(DRMODE_SOLID);
434 draw_message(MESSAGE_SAVED, 1);
435 }
436 }
437 else /* couldn't save for some reason */
438 {
439 if(interface)
440 {
441 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
442 rb->lcd_fillrect(0, LCD_HEIGHT-MESSAGE_HEIGHT, LCD_WIDTH, MESSAGE_HEIGHT);
443 rb->lcd_set_drawmode(DRMODE_SOLID);
444 draw_message(MESSAGE_ERRSAVE, 1);
445 }
446 }
447
448 if(interface)
449 {
450 rb->lcd_update();
451 rb->sleep(HZ); /* pause a second */
452 }
453}
454
455/**********************************
456 * Loads "saved_settings" from disk
457 *********************************/
458void load_settings(void)
459{
460 /* open the settings file */
461 int fd;
462 fd = rb->open(default_filename, O_RDONLY);
463
464 rb->lcd_clear_display();
465 show_clock_logo();
466
467 draw_message(MESSAGE_LOADING, 1);
468
469 rb->lcd_update();
470
471 if(fd >= 0) /* does file exist? */
472 {
473 if(rb->filesize(fd) == sizeof(struct saved_settings)) /* if so, is it the right size? */
474 {
475 rb->read(fd, &clock_settings, sizeof(struct saved_settings));
476 rb->close(fd);
477
478 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
479 rb->lcd_fillrect(0, LCD_HEIGHT-MESSAGE_HEIGHT, LCD_WIDTH, MESSAGE_HEIGHT);
480 rb->lcd_set_drawmode(DRMODE_SOLID);
481 draw_message(MESSAGE_LOADED, 1);
482 }
483 else /* must be invalid, bail out */
484 {
485 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
486 rb->lcd_fillrect(0, LCD_HEIGHT-MESSAGE_HEIGHT, LCD_WIDTH, MESSAGE_HEIGHT);
487 rb->lcd_set_drawmode(DRMODE_SOLID);
488 draw_message(MESSAGE_ERRLOAD, 1);
489
490 reset_settings();
491 }
492 }
493 else /* must be missing, bail out */
494 {
495 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
496 rb->lcd_fillrect(0, LCD_HEIGHT-MESSAGE_HEIGHT, LCD_WIDTH, MESSAGE_HEIGHT);
497 rb->lcd_set_drawmode(DRMODE_SOLID);
498 draw_message(MESSAGE_ERRLOAD, 1);
499
500 reset_settings();
501 }
502
503 rb->lcd_update();
504
505#ifndef SIMULATOR
506 rb->ata_sleep();
507#endif
508
509 rb->sleep(HZ);
510}
511
512void polar_to_cartesian(int a, int r, int* x, int* y)
513{
514 *x = (sin_int(a) * r) >> 14;
515 *y = (sin_int(a-90) * r) >> 14;
516}
517
518void polar_to_cartesian_screen_centered(struct screen * display,
519 int a, int r, int* x, int* y)
520{
521 polar_to_cartesian(a, r, x, y);
522 *x+=display->width/2;
523 *y+=display->height/2;
524}
525
526void angle_to_square(struct screen * display,
527 int square_width, int square_height,
528 int a, int* x, int* y)
529{
530 a = (a+360-90)%360;
531 if(a>45 && a<=135){/* top line */
532 a-=45;
533 *x=square_width-(square_width*2*a)/90;
534 *y=square_height;
535 }else if(a>135 && a<=225){/* left line */
536 a-=135;
537 *x=-square_width;
538 *y=square_height-(square_height*2*a)/90;
539 }else if(a>225 && a<=315){/* bottom line */
540 a-=225;
541 *x=(square_width*2*a)/90-square_width;
542 *y=-square_height;
543 }else if(a>315 || a<=45){/* right line */
544 if(a>315)
545 a-=315;
546 else
547 a+=45;
548 *x=square_width;
549 *y=(square_height*2*a)/90-square_height;
550 }
551 /* recenter */
552 *x+=display->width/2;
553 *y+=display->height/2;
554}
555
556/*******************************
557 * Init clock, set up x/y tables
558 ******************************/
559void init_clock(void)
560{
561 #define ANALOG_VALUES 60
562 #define ANALOG_YCENTER (LCD_HEIGHT/2)
563 #define ANALOG_XCENTER (LCD_WIDTH/2)
564 #define ANALOG_MIN_RADIUS MIN(LCD_HEIGHT/2 -10, LCD_WIDTH/2 -10)
565 #define ANALOG_HR_RADIUS ((2 * ANALOG_MIN_RADIUS)/3)
566
567 #define PI 3.141592
568 int i;
569
570 rb->lcd_setfont(FONT_SYSFIXED); /* universal font */
571
572 load_settings();
573
574 /* set backlight timeout */
575 if(clock_settings.general[general_backlight] == 0)
576 rb->backlight_set_timeout(0);
577 else if(clock_settings.general[general_backlight] == 1)
578 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
579 else if(clock_settings.general[general_backlight] == 2)
580 rb->backlight_set_timeout(1);
581
582 for(i=0; i<ANALOG_VALUES; i++)
583 {
584 int angle=360 * i / ANALOG_VALUES;
585 polar_to_cartesian_screen_centered(
586 rb->screens[0], angle, ANALOG_MIN_RADIUS,
587 &(xminute[i]), &(yminute[i]));
588 polar_to_cartesian_screen_centered(
589 rb->screens[0], angle, ANALOG_HR_RADIUS,
590 &(xhour[i]), &(yhour[i]));
591
592 /* Fullscreen initialization */
593 angle_to_square(rb->screens[0], LCD_WIDTH/2, LCD_HEIGHT/2, angle,
594 &(xminute_full[i]), &(yminute_full[i]));
595 angle_to_square(rb->screens[0], LCD_WIDTH/3, LCD_HEIGHT/3, angle,
596 &(xhour_full[i]), &(yhour_full[i]));
597 }
598}
599
600/*******************
601 * Analog clock mode
602 ******************/
603void analog_clock(int hour, int minute, int second)
604{
605 if(hour >= 12)
606 hour -= 12;
607
608 int i;
609 int hourpos = (hour*5) + (minute/12);
610
611 /* Crappy fake antialiasing (color LCDs only)!
612 * how this works is we draw a large mid-gray hr/min/sec hand,
613 * then the actual (slightly smaller) hand on top of those.
614 * End result: mid-gray edges to the black hands, smooths them out. */
615#ifdef HAVE_LCD_COLOR
616 rb->lcd_set_foreground(LCD_RGBPACK(100,110,125));
617
618 /* second hand */
619 if(clock_settings.analog[analog_secondhand])
620 {
621 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-2, LCD_WIDTH/2, LCD_HEIGHT/2+2,
622 xminute[second], yminute[second]);
623 xlcd_filltriangle(LCD_WIDTH/2-2, LCD_HEIGHT/2, LCD_WIDTH/2+2, LCD_HEIGHT/2,
624 xminute[second], yminute[second]);
625 }
626
627 /* minute hand */
628 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-4, LCD_WIDTH/2, LCD_HEIGHT/2+4,
629 xminute[minute], yminute[minute]);
630 xlcd_filltriangle(LCD_WIDTH/2-4, LCD_HEIGHT/2, LCD_WIDTH/2+4, LCD_HEIGHT/2,
631 xminute[minute], yminute[minute]);
632
633 /* hour hand */
634 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-4, LCD_WIDTH/2, LCD_HEIGHT/2+4,
635 xhour[hourpos], yhour[hourpos]);
636 xlcd_filltriangle(LCD_WIDTH/2-4, LCD_HEIGHT/2, LCD_WIDTH/2+4, LCD_HEIGHT/2,
637 xhour[hourpos], yhour[hourpos]);
638
639 rb->lcd_set_foreground(LCD_BLACK);
640#endif
641
642 /* second hand, if needed */
643 if(clock_settings.analog[analog_secondhand])
644 {
645 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-1, LCD_WIDTH/2, LCD_HEIGHT/2+1,
646 xminute[second], yminute[second]);
647 xlcd_filltriangle(LCD_WIDTH/2-1, LCD_HEIGHT/2, LCD_WIDTH/2+1, LCD_HEIGHT/2,
648 xminute[second], yminute[second]);
649 }
650
651 /* minute hand */
652 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-HAND_W, LCD_WIDTH/2,
653 LCD_HEIGHT/2+HAND_W, xminute[minute], yminute[minute]);
654 xlcd_filltriangle(LCD_WIDTH/2-HAND_W, LCD_HEIGHT/2, LCD_WIDTH/2
655 +HAND_W, LCD_HEIGHT/2, xminute[minute], yminute[minute]);
656
657 /* hour hand */
658 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-HAND_W, LCD_WIDTH/2,
659 LCD_HEIGHT/2+HAND_W, xhour[hourpos], yhour[hourpos]);
660 xlcd_filltriangle(LCD_WIDTH/2-HAND_W, LCD_HEIGHT/2, LCD_WIDTH/2
661 +HAND_W, LCD_HEIGHT/2, xhour[hourpos], yhour[hourpos]);
662
663 /* Draw the circle */
664 for(i=0; i < 60; i+=5)
665 rb->lcd_fillrect(xminute[i]-1, yminute[i]-1, 3, 3);
666
667 /* Draw the cover over the center */
668 rb->lcd_drawline((LCD_WIDTH/2)-1, (LCD_HEIGHT/2)+3,
669 (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)+3);
670 rb->lcd_drawline((LCD_WIDTH/2)-3, (LCD_HEIGHT/2)+2,
671 (LCD_WIDTH/2)+3, (LCD_HEIGHT/2)+2);
672 rb->lcd_drawline((LCD_WIDTH/2)-4, (LCD_HEIGHT/2)+1,
673 (LCD_WIDTH/2)+4, (LCD_HEIGHT/2)+1);
674 rb->lcd_drawline((LCD_WIDTH/2)-4, LCD_HEIGHT/2,
675 (LCD_WIDTH/2)+4, LCD_HEIGHT/2);
676 rb->lcd_drawline((LCD_WIDTH/2)-4, (LCD_HEIGHT/2)-1,
677 (LCD_WIDTH/2)+4, (LCD_HEIGHT/2)-1);
678 rb->lcd_drawline((LCD_WIDTH/2)-3, (LCD_HEIGHT/2)-2,
679 (LCD_WIDTH/2)+3, (LCD_HEIGHT/2)-2);
680 rb->lcd_drawline((LCD_WIDTH/2)-1, (LCD_HEIGHT/2)-3,
681 (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)-3);
682}
683
684/********************
685 * Digital clock mode
686 *******************/
687void digital_clock(int hour, int minute, int second, bool colon)
688{
689 int x_ofs=0;
690
691 /* this basically detects if we draw an AM or PM bitmap.
692 * if we don't, we center the hh:mm display. */
693 if(!clock_settings.digital[digital_format])
694 x_ofs=DIGIT_WIDTH/2;
695
696#if LCD_DEPTH == 1
697 rb->lcd_fillrect(0,0,112,64);
698#endif
699
700 if(clock_settings.digital[digital_format])
701 {
702 /* draw the AM or PM bitmap */
703 if(hour<12)
704 draw_segment(SEGMENT_AM,DIGIT_XOFS(6)+DIGIT_WIDTH*5, 0);
705 else
706 draw_segment(SEGMENT_PM,DIGIT_XOFS(6)+DIGIT_WIDTH*5, 0);
707
708 /* and then readjust the hour to 12-hour format
709 * ( 13:00+ -> 1:00+ ) */
710 if(hour>12)
711 hour -= 12;
712 }
713
714 /* hour */
715 draw_segment(hour/10, DIGIT_XOFS(6)+x_ofs, 0);
716 draw_segment(hour%10, DIGIT_XOFS(6)+DIGIT_WIDTH+x_ofs, 0);
717
718 /* colon */
719 if(colon)
720 draw_segment(COLON, DIGIT_XOFS(6)+2*DIGIT_WIDTH+x_ofs, 0);
721
722 /* minutes */
723 draw_segment(minute/10, DIGIT_XOFS(6)+3*DIGIT_WIDTH+x_ofs, 0);
724 draw_segment(minute%10, DIGIT_XOFS(6)+4*DIGIT_WIDTH+x_ofs, 0);
725
726 if(clock_settings.digital[digital_seconds])
727 {
728 draw_segment(second/10, DIGIT_XOFS(2), DIGIT_HEIGHT);
729 draw_segment(second%10, DIGIT_XOFS(2)+DIGIT_WIDTH, DIGIT_HEIGHT);
730 }
731}
732
733/***********************
734 * Fullscreen clock mode
735 **********************/
736void fullscreen_clock(int hour, int minute, int second)
737{
738 if(hour >= 12)
739 hour -= 12;
740
741 int i;
742 int hourpos = (hour*5) + (minute/12);
743
744 /* Crappy fake antialiasing (color LCDs only)!
745 * how this works is we draw a large mid-gray hr/min/sec hand,
746 * then the actual (slightly smaller) hand on top of those.
747 * End result: mid-gray edges to the black hands, smooths them out. */
748#ifdef HAVE_LCD_COLOR
749 rb->lcd_set_foreground(LCD_RGBPACK(100,110,125));
750
751 /* second hand */
752 if(clock_settings.analog[analog_secondhand])
753 {
754 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-2, LCD_WIDTH/2, LCD_HEIGHT/2+2,
755 xminute_full[second], yminute_full[second]);
756 xlcd_filltriangle(LCD_WIDTH/2-2, LCD_HEIGHT/2, LCD_WIDTH/2+2, LCD_HEIGHT/2,
757 xminute_full[second], yminute_full[second]);
758 }
759
760 /* minute hand */
761 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-4, LCD_WIDTH/2, LCD_HEIGHT/2+4,
762 xminute_full[minute], yminute_full[minute]);
763 xlcd_filltriangle(LCD_WIDTH/2-4, LCD_HEIGHT/2, LCD_WIDTH/2+4, LCD_HEIGHT/2,
764 xminute_full[minute], yminute_full[minute]);
765
766 /* hour hand */
767 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-4, LCD_WIDTH/2, LCD_HEIGHT/2+4,
768 xhour_full[hourpos], yhour_full[hourpos]);
769 xlcd_filltriangle(LCD_WIDTH/2-4, LCD_HEIGHT/2, LCD_WIDTH/2+4, LCD_HEIGHT/2,
770 xhour_full[hourpos], yhour_full[hourpos]);
771
772 rb->lcd_set_foreground(LCD_BLACK);
773#endif
774
775 /* second hand, if needed */
776 if(clock_settings.analog[analog_secondhand])
777 {
778 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-1, LCD_WIDTH/2, LCD_HEIGHT/2+1,
779 xminute_full[second], yminute_full[second]);
780 xlcd_filltriangle(LCD_WIDTH/2-1, LCD_HEIGHT/2, LCD_WIDTH/2+1, LCD_HEIGHT/2,
781 xminute_full[second], yminute_full[second]);
782 }
783
784 /* minute hand */
785 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-3, LCD_WIDTH/2, LCD_HEIGHT/2+3,
786 xminute_full[minute], yminute_full[minute]);
787 xlcd_filltriangle(LCD_WIDTH/2-3, LCD_HEIGHT/2, LCD_WIDTH/2+3, LCD_HEIGHT/2,
788 xminute_full[minute], yminute_full[minute]);
789
790 /* hour hand */
791 xlcd_filltriangle(LCD_WIDTH/2, LCD_HEIGHT/2-3, LCD_WIDTH/2, LCD_HEIGHT/2+3,
792 xhour_full[hourpos], yhour_full[hourpos]);
793 xlcd_filltriangle(LCD_WIDTH/2-3, LCD_HEIGHT/2, LCD_WIDTH/2+3, LCD_HEIGHT/2,
794 xhour_full[hourpos], yhour_full[hourpos]);
795
796 /* Draw the circle */
797 for(i=0; i < 60; i+=5)
798 rb->lcd_fillrect(xminute_full[i]-1, yminute_full[i]-1, 3, 3);
799
800 /* Draw the cover over the center */
801 rb->lcd_drawline((LCD_WIDTH/2)-1, (LCD_HEIGHT/2)+3,
802 (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)+3);
803 rb->lcd_drawline((LCD_WIDTH/2)-3, (LCD_HEIGHT/2)+2,
804 (LCD_WIDTH/2)+3, (LCD_HEIGHT/2)+2);
805 rb->lcd_drawline((LCD_WIDTH/2)-4, (LCD_HEIGHT/2)+1,
806 (LCD_WIDTH/2)+4, (LCD_HEIGHT/2)+1);
807 rb->lcd_drawline((LCD_WIDTH/2)-4, LCD_HEIGHT/2,
808 (LCD_WIDTH/2)+4, LCD_HEIGHT/2);
809 rb->lcd_drawline((LCD_WIDTH/2)-4, (LCD_HEIGHT/2)-1,
810 (LCD_WIDTH/2)+4, (LCD_HEIGHT/2)-1);
811 rb->lcd_drawline((LCD_WIDTH/2)-3, (LCD_HEIGHT/2)-2,
812 (LCD_WIDTH/2)+3, (LCD_HEIGHT/2)-2);
813 rb->lcd_drawline((LCD_WIDTH/2)-1, (LCD_HEIGHT/2)-3,
814 (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)-3);
815}
816
817/*******************
818 * Binary clock mode
819 ******************/
820void binary_clock(int hour, int minute, int second)
821{
822 int i, xpos=0;
823 int mode_var[3]; /* pointers to h, m, s arguments */
824 int mode; /* 0 = hour, 1 = minute, 2 = second */
825
826 mode_var[0] = hour;
827 mode_var[1] = minute;
828 mode_var[2] = second;
829
830 for(mode = 0; mode < 3; mode++)
831 {
832 for(i = 32; i > 0; i /= 2)
833 {
834 if(mode_var[mode] >= i)
835 {
836 if(clock_settings.binary[binary_mode])
837 draw_digit(DOT_FILLED, xpos*DIGIT_WIDTH+DIGIT_XOFS(6), DIGIT_HEIGHT*mode+DIGIT_YOFS(3));
838 else
839 draw_digit(1, xpos*DIGIT_WIDTH+DIGIT_XOFS(6), DIGIT_HEIGHT*mode+DIGIT_YOFS(3));
840 mode_var[mode] -= i;
841 }
842 else
843 {
844 if(clock_settings.binary[binary_mode])
845 draw_digit(DOT_EMPTY, xpos*DIGIT_WIDTH+DIGIT_XOFS(6), DIGIT_HEIGHT*mode+DIGIT_YOFS(3));
846 else
847 draw_digit(0, xpos*DIGIT_WIDTH+DIGIT_XOFS(6), DIGIT_HEIGHT*mode+DIGIT_YOFS(3));
848 }
849
850 xpos++;
851 }
852
853 xpos=0; /* reset the x-pos for next mode */
854 }
855}
856
857/******************
858 * Plain clock mode
859 *****************/
860void plain_clock(int hour, int minute, int second, bool colon)
861{
862
863 int x_ofs=0;
864
865 /* this basically detects if we draw an AM or PM bitmap.
866 * if we don't, we center the hh:mm display. */
867 if(!clock_settings.plain[plain_format])
868 x_ofs=DIGIT_WIDTH/2;
869
870 if(clock_settings.plain[plain_format])
871 {
872 /* draw the AM or PM bitmap */
873 if(hour<12)
874 draw_digit(ICON_AM, DIGIT_XOFS(6)+(DIGIT_WIDTH*5)+x_ofs, 0);
875 else
876 draw_digit(ICON_PM, DIGIT_XOFS(6)+(DIGIT_WIDTH*5)+x_ofs, 0);
877
878 /* and then readjust the hour to 12-hour format
879 * ( 13:00+ -> 1:00+ ) */
880 if(hour>12)
881 hour -= 12;
882 }
883
884
885 draw_digit(hour/10, DIGIT_XOFS(6)+(DIGIT_WIDTH*0)+x_ofs, 0);
886 draw_digit(hour%10, DIGIT_XOFS(6)+(DIGIT_WIDTH*1)+x_ofs, 0);
887
888 if(colon)
889 draw_digit(COLON, DIGIT_XOFS(6)+(DIGIT_WIDTH*2)+x_ofs, 0);
890
891 draw_digit(minute/10, DIGIT_XOFS(6)+(DIGIT_WIDTH*3)+x_ofs, 0);
892 draw_digit(minute%10, DIGIT_XOFS(6)+(DIGIT_WIDTH*4)+x_ofs, 0);
893
894 if(clock_settings.plain[plain_seconds])
895 {
896 draw_digit(second/10, DIGIT_XOFS(2), DIGIT_HEIGHT);
897 draw_digit(second%10, DIGIT_XOFS(2)+(DIGIT_WIDTH), DIGIT_HEIGHT);
898 }
899}
900
901
902
903/****************************************
904 * Draws the extras, IE border, digits...
905 ***************************************/
906void draw_extras(int year, int day, int month, int hour, int minute, int second)
907{
908 int i;
909
910 struct tm* current_time = rb->get_time();
911
912 char moday[8];
913 char dateyr[6];
914 char tmhrmin[7];
915 char tmsec[3];
916
917 /* american date readout */
918 if(clock_settings.analog[analog_date] == 1)
919 rb->snprintf(moday, sizeof(moday), "%02d/%02d", month, day);
920 else
921 rb->snprintf(moday, sizeof(moday), "%02d.%02d", day, month);
922 rb->snprintf(dateyr, sizeof(dateyr), "%d", year);
923 rb->snprintf(tmhrmin, sizeof(tmhrmin), "%02d:%02d", hour, minute);
924 rb->snprintf(tmsec, sizeof(tmsec), "%02d", second);
925
926 /* Analog Extras */
927 if(clock_settings.clock == ANALOG)
928 {
929 if(clock_settings.analog[analog_time] != 0) /* Digital readout */
930 {
931 draw_smalldigit(hour/10, SMALLDIGIT_WIDTH*0, 0);
932 draw_smalldigit(hour%10, SMALLDIGIT_WIDTH*1, 0);
933 draw_smalldigit(COLON, SMALLDIGIT_WIDTH*2, 0);
934 draw_smalldigit(minute/10, SMALLDIGIT_WIDTH*3, 0);
935 draw_smalldigit(minute%10, SMALLDIGIT_WIDTH*4, 0);
936
937 draw_smalldigit(second/10, SMALLDIGIT_WIDTH*1.5, SMALLDIGIT_HEIGHT);
938 draw_smalldigit(second%10, SMALLDIGIT_WIDTH*2.5, SMALLDIGIT_HEIGHT);
939
940 /* AM/PM indicator */
941 if(clock_settings.analog[analog_time] == 2)
942 {
943 if(current_time->tm_hour > 12) /* PM */
944 draw_digit(ICON_PM, LCD_WIDTH-DIGIT_WIDTH, DIGIT_HEIGHT/2-DIGIT_HEIGHT);
945 else /* AM */
946 draw_digit(ICON_AM, LCD_WIDTH-DIGIT_WIDTH, DIGIT_HEIGHT/2-DIGIT_HEIGHT);
947 }
948 }
949 if(clock_settings.analog[analog_date] != 0) /* Date readout */
950 {
951 if(clock_settings.analog[analog_date] == 1)
952 {
953 draw_smalldigit(month/10, SMALLDIGIT_WIDTH*0,
954 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
955 draw_smalldigit(month%10, SMALLDIGIT_WIDTH*1,
956 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
957 draw_smalldigit(SLASH, SMALLDIGIT_WIDTH*2,
958 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
959 draw_smalldigit(day/10, SMALLDIGIT_WIDTH*3,
960 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
961 draw_smalldigit(day%10, SMALLDIGIT_WIDTH*4,
962 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
963 draw_smalldigit(year/1000, SMALLDIGIT_WIDTH*0.5,
964 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
965 draw_smalldigit(year%1000/100, SMALLDIGIT_WIDTH*1.5,
966 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
967 draw_smalldigit(year%100/10, SMALLDIGIT_WIDTH*2.5,
968 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
969 draw_smalldigit(year%10, SMALLDIGIT_WIDTH*3.5,
970 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
971 }
972 else if(clock_settings.analog[analog_date] == 2)
973 {
974
975 draw_smalldigit(day/10, SMALLDIGIT_WIDTH*0,
976 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
977 draw_smalldigit(day%10, SMALLDIGIT_WIDTH*1,
978 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
979 draw_smalldigit(PERIOD, SMALLDIGIT_WIDTH*2,
980 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
981 draw_smalldigit(month/10, SMALLDIGIT_WIDTH*3,
982 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
983 draw_smalldigit(month%10, SMALLDIGIT_WIDTH*4,
984 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
985 draw_smalldigit(year/1000, SMALLDIGIT_WIDTH*0.5,
986 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
987 draw_smalldigit(year%1000/100, SMALLDIGIT_WIDTH*1.5,
988 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
989 draw_smalldigit(year%100/10, SMALLDIGIT_WIDTH*2.5,
990 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
991 draw_smalldigit(year%10, SMALLDIGIT_WIDTH*3.5,
992 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
993 }
994 }
995 }
996 else if(clock_settings.clock == DIGITAL)
997 {
998 /* Date readout */
999 if(clock_settings.digital[digital_date] == 1) /* american mode */
1000 {
1001 draw_smallsegment(month/10, SMALLSEG_WIDTH*0+SMALLSEG_XOFS(10),
1002 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1003 draw_smallsegment(month%10, SMALLSEG_WIDTH*1+SMALLSEG_XOFS(10),
1004 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1005 draw_smallsegment(SLASH, SMALLSEG_WIDTH*2+SMALLSEG_XOFS(10),
1006 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1007 draw_smallsegment(day/10, SMALLSEG_WIDTH*3+SMALLSEG_XOFS(10),
1008 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1009 draw_smallsegment(day%10, SMALLSEG_WIDTH*4+SMALLSEG_XOFS(10),
1010 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1011 draw_smallsegment(SLASH, SMALLSEG_WIDTH*5+SMALLSEG_XOFS(10),
1012 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1013 draw_smallsegment(year/1000, SMALLSEG_WIDTH*6+SMALLSEG_XOFS(10),
1014 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1015 draw_smallsegment(year%1000/100, SMALLSEG_WIDTH*7+SMALLSEG_XOFS(10),
1016 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1017 draw_smallsegment(year%100/10, SMALLSEG_WIDTH*8+SMALLSEG_XOFS(10),
1018 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1019 draw_smallsegment(year%10, SMALLSEG_WIDTH*9+SMALLSEG_XOFS(10),
1020 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1021 }
1022 else if(clock_settings.digital[digital_date] == 2) /* european mode */
1023 {
1024 draw_smallsegment(day/10, SMALLSEG_WIDTH*0+SMALLSEG_XOFS(10),
1025 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1026 draw_smallsegment(day%10, SMALLSEG_WIDTH*1+SMALLSEG_XOFS(10),
1027 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1028 draw_smallsegment(PERIOD, SMALLSEG_WIDTH*2+SMALLSEG_XOFS(10),
1029 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1030 draw_smallsegment(month/10, SMALLSEG_WIDTH*3+SMALLSEG_XOFS(10),
1031 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1032 draw_smallsegment(month%10, SMALLSEG_WIDTH*4+SMALLSEG_XOFS(10),
1033 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1034 draw_smallsegment(PERIOD, SMALLSEG_WIDTH*5+SMALLSEG_XOFS(10),
1035 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1036 draw_smallsegment(year/1000, SMALLSEG_WIDTH*6+SMALLSEG_XOFS(10),
1037 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1038 draw_smallsegment(year%1000/100, SMALLSEG_WIDTH*7+SMALLSEG_XOFS(10),
1039 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1040 draw_smallsegment(year%100/10, SMALLSEG_WIDTH*8+SMALLSEG_XOFS(10),
1041 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1042 draw_smallsegment(year%10, SMALLSEG_WIDTH*9+SMALLSEG_XOFS(10),
1043 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET*2);
1044 }
1045 }
1046 else if(clock_settings.clock == FULLSCREEN) /* Fullscreen mode */
1047 {
1048 if(clock_settings.fullscreen[fullscreen_border])
1049 {
1050 for(i=0; i < 60; i+=5) /* Draw the circle */
1051 rb->lcd_fillrect(xminute_full[i]-1, yminute_full[i]-1, 3, 3);
1052 }
1053 }
1054 else if(clock_settings.clock == PLAIN) /* Plain mode */
1055 {
1056 /* Date readout */
1057 if(clock_settings.plain[plain_date] == 1) /* american mode */
1058 {
1059 draw_smalldigit(month/10, SMALLDIGIT_WIDTH*0+SMALLDIGIT_XOFS(10),
1060 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1061 draw_smalldigit(month%10, SMALLDIGIT_WIDTH*1+SMALLDIGIT_XOFS(10),
1062 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1063 draw_smalldigit(SLASH, SMALLDIGIT_WIDTH*2+SMALLDIGIT_XOFS(10),
1064 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1065 draw_smalldigit(day/10, SMALLDIGIT_WIDTH*3+SMALLDIGIT_XOFS(10),
1066 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1067 draw_smalldigit(day%10, SMALLDIGIT_WIDTH*4+SMALLDIGIT_XOFS(10),
1068 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1069 draw_smalldigit(SLASH, SMALLDIGIT_WIDTH*5+SMALLDIGIT_XOFS(10),
1070 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1071 draw_smalldigit(year/1000, SMALLDIGIT_WIDTH*6+SMALLDIGIT_XOFS(10),
1072 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1073 draw_smalldigit(year%1000/100, SMALLDIGIT_WIDTH*7+SMALLDIGIT_XOFS(10),
1074 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1075 draw_smalldigit(year%100/10, SMALLDIGIT_WIDTH*8+SMALLDIGIT_XOFS(10),
1076 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1077 draw_smalldigit(year%10, SMALLDIGIT_WIDTH*9+SMALLDIGIT_XOFS(10),
1078 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1079 }
1080 else if(clock_settings.plain[plain_date] == 2) /* european mode */
1081 {
1082 draw_smalldigit(day/10, SMALLDIGIT_WIDTH*0+SMALLDIGIT_XOFS(10),
1083 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1084 draw_smalldigit(day%10, SMALLDIGIT_WIDTH*1+SMALLDIGIT_XOFS(10),
1085 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1086 draw_smalldigit(PERIOD, SMALLDIGIT_WIDTH*2+SMALLDIGIT_XOFS(10),
1087 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1088 draw_smalldigit(month/10, SMALLDIGIT_WIDTH*3+SMALLDIGIT_XOFS(10),
1089 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1090 draw_smalldigit(month%10, SMALLDIGIT_WIDTH*4+SMALLDIGIT_XOFS(10),
1091 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1092 draw_smalldigit(PERIOD, SMALLDIGIT_WIDTH*5+SMALLDIGIT_XOFS(10),
1093 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1094 draw_smalldigit(year/1000, SMALLDIGIT_WIDTH*6+SMALLDIGIT_XOFS(10),
1095 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1096 draw_smalldigit(year%1000/100, SMALLDIGIT_WIDTH*7+SMALLDIGIT_XOFS(10),
1097 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1098 draw_smalldigit(year%100/10, SMALLDIGIT_WIDTH*8+SMALLDIGIT_XOFS(10),
1099 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1100 draw_smalldigit(year%10, SMALLDIGIT_WIDTH*9+SMALLDIGIT_XOFS(10),
1101 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET*2);
1102 }
1103 }
1104}
1105
1106/*********************
1107 * Display the counter
1108 ********************/
1109void show_counter(void)
1110{
1111
1112 /* increment counter */
1113 if(counting)
1114 passed_time = *rb->current_tick - start_tick;
1115 else
1116 passed_time = 0;
1117
1118 displayed_value = counter + passed_time;
1119 displayed_value = displayed_value / HZ;
1120
1121 /* these are the REAL displayed values */
1122 count_s = displayed_value % 60;
1123 count_m = displayed_value % 3600 / 60;
1124 count_h = displayed_value / 3600;
1125
1126 if(clock_settings.general[general_counter])
1127 {
1128 if(clock_settings.clock == ANALOG)
1129 {
1130 draw_smalldigit(count_h/10, LCD_WIDTH-SMALLDIGIT_WIDTH*5,
1131 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
1132 draw_smalldigit(count_h%10, LCD_WIDTH-SMALLDIGIT_WIDTH*4,
1133 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
1134 draw_smalldigit(COLON, LCD_WIDTH-SMALLDIGIT_WIDTH*3,
1135 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
1136 draw_smalldigit(count_m/10, LCD_WIDTH-SMALLDIGIT_WIDTH*2,
1137 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
1138 draw_smalldigit(count_m%10, LCD_WIDTH-SMALLDIGIT_WIDTH,
1139 LCD_HEIGHT-SMALLDIGIT_HEIGHT*2);
1140 draw_smalldigit(count_s/10, LCD_WIDTH-SMALLDIGIT_WIDTH*3.5,
1141 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
1142 draw_smalldigit(count_s%10, LCD_WIDTH-SMALLDIGIT_WIDTH*2.5,
1143 LCD_HEIGHT-SMALLDIGIT_HEIGHT);
1144 }
1145 else if(clock_settings.clock == DIGITAL)
1146 {
1147 draw_smallsegment(count_h/10, SMALLSEG_WIDTH*0+SMALLSEG_XOFS(8),
1148 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET);
1149 draw_smallsegment(count_h%10, SMALLSEG_WIDTH*1+SMALLSEG_XOFS(8),
1150 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET);
1151 draw_smallsegment(COLON, SMALLSEG_WIDTH*2+SMALLSEG_XOFS(8),
1152 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET);
1153 draw_smallsegment(count_m/10, SMALLSEG_WIDTH*3+SMALLSEG_XOFS(8),
1154 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET);
1155 draw_smallsegment(count_m%10, SMALLSEG_WIDTH*4+SMALLSEG_XOFS(8),
1156 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET);
1157 draw_smallsegment(COLON, SMALLSEG_WIDTH*5+SMALLSEG_XOFS(8),
1158 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET);
1159 draw_smallsegment(count_s/10, SMALLSEG_WIDTH*6+SMALLSEG_XOFS(8),
1160 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET);
1161 draw_smallsegment(count_s%10, SMALLSEG_WIDTH*7+SMALLSEG_XOFS(8),
1162 LCD_HEIGHT-SMALLSEG_HEIGHT*LCD_OFFSET);
1163 }
1164 else if(clock_settings.clock == FULLSCREEN)
1165 {
1166
1167 draw_smalldigit(count_h/10, SMALLDIGIT_WIDTH*0+SMALLDIGIT_XOFS(8),
1168 LCD_HEIGHT-SMALLDIGIT_HEIGHT*1.5);
1169 draw_smalldigit(count_h%10, SMALLDIGIT_WIDTH*1+SMALLDIGIT_XOFS(8),
1170 LCD_HEIGHT-SMALLDIGIT_HEIGHT*1.5);
1171 draw_smalldigit(COLON, SMALLDIGIT_WIDTH*2+SMALLDIGIT_XOFS(8),
1172 LCD_HEIGHT-SMALLDIGIT_HEIGHT*1.5);
1173 draw_smalldigit(count_m/10, SMALLDIGIT_WIDTH*3+SMALLDIGIT_XOFS(8),
1174 LCD_HEIGHT-SMALLDIGIT_HEIGHT*1.5);
1175 draw_smalldigit(count_m%10, SMALLDIGIT_WIDTH*4+SMALLDIGIT_XOFS(8),
1176 LCD_HEIGHT-SMALLDIGIT_HEIGHT*1.5);
1177 draw_smalldigit(COLON, SMALLDIGIT_WIDTH*5+SMALLDIGIT_XOFS(8),
1178 LCD_HEIGHT-SMALLDIGIT_HEIGHT*1.5);
1179 draw_smalldigit(count_s/10, SMALLDIGIT_WIDTH*6+SMALLDIGIT_XOFS(8),
1180 LCD_HEIGHT-SMALLDIGIT_HEIGHT*1.5);
1181 draw_smalldigit(count_s%10, SMALLDIGIT_WIDTH*7+SMALLDIGIT_XOFS(8),
1182 LCD_HEIGHT-SMALLDIGIT_HEIGHT*1.5);
1183 }
1184 else if(clock_settings.clock == PLAIN)
1185 {
1186 draw_smalldigit(count_h/10, SMALLDIGIT_WIDTH*0+SMALLDIGIT_XOFS(8),
1187 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET);
1188 draw_smalldigit(count_h%10, SMALLDIGIT_WIDTH*1+SMALLDIGIT_XOFS(8),
1189 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET);
1190 draw_smalldigit(COLON, SMALLDIGIT_WIDTH*2+SMALLDIGIT_XOFS(8),
1191 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET);
1192 draw_smalldigit(count_m/10, SMALLDIGIT_WIDTH*3+SMALLDIGIT_XOFS(8),
1193 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET);
1194 draw_smalldigit(count_m%10, SMALLDIGIT_WIDTH*4+SMALLDIGIT_XOFS(8),
1195 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET);
1196 draw_smalldigit(COLON, SMALLDIGIT_WIDTH*5+SMALLDIGIT_XOFS(8),
1197 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET);
1198 draw_smalldigit(count_s/10, SMALLDIGIT_WIDTH*6+SMALLDIGIT_XOFS(8),
1199 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET);
1200 draw_smalldigit(count_s%10, SMALLDIGIT_WIDTH*7+SMALLDIGIT_XOFS(8),
1201 LCD_HEIGHT-SMALLDIGIT_HEIGHT*LCD_OFFSET);
1202 }
1203 }
1204}
1205
1206/* Menus */
1207
1208/***************
1209 * Select a mode
1210 **************/
1211bool menu_mode_selector(void)
1212{
1213 int selection=clock_settings.clock-1;
1214
1215 set_standard_colors();
1216
1217 MENUITEM_STRINGLIST(menu,"Mode Selector",NULL, "Analog", "Full-screen",
1218 "Digital/LCD","Plain","Binary");
1219
1220 /* check for this, so if the user exits the menu without
1221 * making a selection, it won't change to some weird value. */
1222 if(rb->do_menu(&menu, &selection) >=0){
1223 clock_settings.clock = selection+1;
1224 return(true);
1225 }
1226 return(false);
1227}
1228
1229/**********************
1230 * Analog settings menu
1231 *********************/
1232void menu_analog_settings(void)
1233{
1234 int selection=0, result=0;
1235
1236 MENUITEM_STRINGLIST(menu,"Analog Mode Settings",NULL,"Show Date",
1237 "Show Second Hand","Show Time Readout");
1238
1239 while(result>=0)
1240 {
1241 result=rb->do_menu(&menu, &selection);
1242 switch(result)
1243 {
1244 case 0:
1245 rb->set_option("Show Date", &clock_settings.analog[analog_date],
1246 INT, date_format_text, 3, NULL);
1247 break;
1248 case 1:
1249 rb->set_option("Show Second Hand", &clock_settings.analog[analog_secondhand],
1250 INT, noyes_text, 2, NULL);
1251 break;
1252 case 2:
1253 rb->set_option("Show Time", &clock_settings.analog[analog_time],
1254 INT, analog_time_text, 3, NULL);
1255 break;
1256 }
1257 }
1258}
1259
1260/***********************
1261 * Digital settings menu
1262 **********************/
1263void menu_digital_settings(void)
1264{
1265 int selection=0, result=0;
1266
1267 MENUITEM_STRINGLIST(menu,"Digital/LCD Mode Settings",NULL,"Show Date",
1268 "Show Seconds","Blinking Colon","Time Format");
1269
1270 while(result>=0)
1271 {
1272 result=rb->do_menu(&menu, &selection);
1273 switch(result)
1274 {
1275 case 0:
1276 rb->set_option("Show Date", &clock_settings.digital[digital_date],
1277 INT, date_format_text, 3, NULL);
1278 break;
1279 case 1:
1280 rb->set_option("Show Seconds", &clock_settings.digital[digital_seconds],
1281 INT, noyes_text, 2, NULL);
1282 break;
1283 case 2:
1284 rb->set_option("Blinking Colon", &clock_settings.digital[digital_blinkcolon],
1285 INT, noyes_text, 2, NULL);
1286 break;
1287 case 3:
1288 rb->set_option("Time Format", &clock_settings.digital[digital_format],
1289 INT, time_format_text, 2, NULL);
1290 break;
1291 }
1292 }
1293}
1294
1295/**************************
1296 * Fullscreen settings menu
1297 *************************/
1298void menu_fullscreen_settings(void)
1299{
1300 int selection=0, result=0;
1301
1302 MENUITEM_STRINGLIST(menu,"Fullscreen Mode Settings",NULL,
1303 "Show Border","Show Second Hand");
1304
1305 while(result>=0)
1306 {
1307 result=rb->do_menu(&menu, &selection);
1308 switch(result)
1309 {
1310 case 0:
1311 rb->set_option("Show Border", &clock_settings.fullscreen[fullscreen_border],
1312 INT, noyes_text, 2, NULL);
1313 break;
1314 case 1:
1315 rb->set_option("Show Second Hand", &clock_settings.fullscreen[fullscreen_secondhand],
1316 INT, noyes_text, 2, NULL);
1317 break;
1318 }
1319 }
1320}
1321
1322/**********************
1323 * Binary settings menu
1324 *********************/
1325void menu_binary_settings(void)
1326{
1327 int selection=0, result=0;
1328
1329 MENUITEM_STRINGLIST(menu,"Binary Mode Settings",NULL,"Display Mode");
1330
1331 while(result>=0)
1332 {
1333 result=rb->do_menu(&menu, &selection);
1334 switch(result)
1335 {
1336 case 0:
1337 rb->set_option("Display Mode", &clock_settings.binary[binary_mode],
1338 INT, binary_mode_text, 2, NULL);
1339 }
1340
1341 }
1342}
1343
1344/*********************
1345 * Plain settings menu
1346 ********************/
1347void menu_plain_settings(void)
1348{
1349 int selection=0, result=0;
1350
1351 MENUITEM_STRINGLIST(menu,"Plain Mode Settings",NULL,"Show Date",
1352 "Show Seconds","Blinking Colon","Time Format");
1353
1354 while(result>=0)
1355 {
1356 result=rb->do_menu(&menu, &selection);
1357 switch(result)
1358 {
1359 case 0:
1360 rb->set_option("Show Date", &clock_settings.plain[plain_date],
1361 INT, date_format_text, 3, NULL);
1362 break;
1363 case 1:
1364 rb->set_option("Show Seconds", &clock_settings.plain[plain_seconds],
1365 INT, noyes_text, 2, NULL);
1366 break;
1367 case 2:
1368 rb->set_option("Blinking Colon", &clock_settings.plain[plain_blinkcolon],
1369 INT, noyes_text, 2, NULL);
1370 break;
1371 case 3:
1372 rb->set_option("Time Format", &clock_settings.plain[plain_format],
1373 INT, time_format_text, 2, NULL);
1374 break;
1375 }
1376 }
1377}
1378
1379/***********************************************************
1380 * Confirm resetting of settings, used in general_settings()
1381 **********************************************************/
1382void confirm_reset(void)
1383{
1384 int result=0;
1385
1386 rb->set_option("Reset all settings?", &result, INT, noyes_text, 2, NULL);
1387
1388 if(result == 1) /* reset! */
1389 {
1390 reset_settings();
1391 rb->splash(HZ, "Settings reset!");
1392 }
1393 else
1394 rb->splash(HZ, "Settings NOT reset.");
1395}
1396
1397/************************************
1398 * General settings. Reset, save, etc
1399 ***********************************/
1400void menu_general_settings(void)
1401{
1402 int selection=0, result=0;
1403
1404 MENUITEM_STRINGLIST(menu,"General Settings",NULL,"Reset Settings",
1405 "Save Settings Now","Save On Exit","Show Counter",
1406 "Backlight Settings","Idle Poweroff (temporary)");
1407
1408 while(result>=0)
1409 {
1410 result=rb->do_menu(&menu, &selection);
1411 switch(result)
1412 {
1413 case 0:
1414 confirm_reset();
1415 break;
1416
1417 case 1:
1418 save_settings(false);
1419 rb->splash(HZ, "Settings saved");
1420 break;
1421
1422 case 2:
1423 rb->set_option("Save On Exit", &clock_settings.general[general_savesetting],
1424 INT, noyes_text, 2, NULL);
1425
1426 /* if we no longer save on exit, we better save now to remember that */
1427 if(clock_settings.general[general_savesetting] == 0)
1428 save_settings(false);
1429 break;
1430
1431 case 3:
1432 rb->set_option("Show Counter", &clock_settings.general[general_counter],
1433 INT, noyes_text, 2, NULL);
1434 break;
1435
1436 case 4:
1437 rb->set_option("Backlight Settings", &clock_settings.general[general_backlight],
1438 INT, backlight_settings_text, 3, NULL);
1439 break;
1440
1441 case 5:
1442 rb->set_option("Idle Poweroff (temporary)", &idle_poweroff,
1443 BOOL, idle_poweroff_text, 2, NULL);
1444 break;
1445 }
1446
1447 }
1448}
1449
1450/***********
1451 * Main menu
1452 **********/
1453void main_menu(void)
1454{
1455 int selection=0;
1456 bool done = false;
1457
1458 set_standard_colors();
1459
1460 MENUITEM_STRINGLIST(menu,"Clock Menu",NULL,"View Clock","Mode Selector",
1461 "Mode Settings","General Settings","Quit");
1462
1463 while(!done)
1464 {
1465 switch(rb->do_menu(&menu, &selection))
1466 {
1467 case 0:
1468 rb->lcd_setfont(FONT_SYSFIXED);
1469 done = true;
1470 break;
1471
1472 case 1:
1473 done=menu_mode_selector();
1474 break;
1475
1476 case 2:
1477 switch(clock_settings.clock)
1478 {
1479 case ANALOG: menu_analog_settings();break;
1480 case DIGITAL: menu_digital_settings();break;
1481 case FULLSCREEN: menu_fullscreen_settings();break;
1482 case BINARY: menu_binary_settings();break;
1483 case PLAIN: menu_plain_settings();break;
1484 }
1485 break;
1486
1487 case 3:
1488 menu_general_settings();
1489 break;
1490
1491 case 4:
1492 exit_clock = true;
1493 done = true;
1494 break;
1495
1496 default:
1497 done=true;
1498 break;
1499 }
1500 }
1501
1502 rb->lcd_setfont(FONT_SYSFIXED);
1503 set_digital_colors();
1504}
1505
1506/**********************************************************************
1507 * Plugin starts here
1508 **********************************************************************/
1509enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1510{
1511 int button;
1512
1513 /* time/date ints */
1514 int hour, minute, second;
1515 int temphour;
1516 int last_second = -1;
1517 int year, day, month;
1518
1519 bool counter_btn_held = false;
1520
1521 struct tm* current_time;
1522
1523 (void)parameter;
1524 rb = api;
1525
1526#if LCD_DEPTH > 1
1527 rb->lcd_set_backdrop(NULL);
1528#endif
1529
1530 init_clock();
1531
1532 /* init xlcd functions */
1533 xlcd_init(rb);
1534
1535 set_digital_colors();
1536
1537 while(!exit_clock)
1538 {
1539 /*********************
1540 * Time info
1541 *********************/
1542 current_time = rb->get_time();
1543 hour = current_time->tm_hour;
1544 minute = current_time->tm_min;
1545 second = current_time->tm_sec;
1546 temphour = current_time->tm_hour;
1547
1548 /*********************
1549 * Date info
1550 *********************/
1551 year = current_time->tm_year + 1900;
1552 day = current_time->tm_mday;
1553 month = current_time->tm_mon + 1;
1554
1555 if(second != last_second)
1556 {
1557 rb->lcd_clear_display();
1558
1559 /* Analog mode */
1560 if(clock_settings.clock == ANALOG)
1561 analog_clock(hour, minute, second);
1562 /* Digital mode */
1563 else if(clock_settings.clock == DIGITAL)
1564 {
1565 if(clock_settings.digital[digital_blinkcolon])
1566 digital_clock(hour, minute, second, second & 1);
1567 else
1568 digital_clock(hour, minute, second, true);
1569 }
1570 /* Fullscreen mode */
1571 else if(clock_settings.clock == FULLSCREEN)
1572 fullscreen_clock(hour, minute, second);
1573 /* Binary mode */
1574 else if(clock_settings.clock == BINARY)
1575 binary_clock(hour, minute, second);
1576 /* Plain mode */
1577 else if(clock_settings.clock == PLAIN)
1578 {
1579 if(clock_settings.plain[plain_blinkcolon])
1580 plain_clock(hour, minute, second, second & 1);
1581 else
1582 plain_clock(hour, minute, second, true);
1583 }
1584
1585 /* show counter */
1586 show_counter();
1587 }
1588
1589 if(clock_settings.analog[analog_time] == 2 && temphour == 0)
1590 temphour = 12;
1591 if(clock_settings.analog[analog_time] == 2 && temphour > 12)
1592 temphour -= 12;
1593
1594 /* all the "extras" - readouts/displays */
1595 draw_extras(year, day, month, temphour, minute, second);
1596
1597 if(!idle_poweroff)
1598 rb->reset_poweroff_timer();
1599
1600 rb->lcd_update();
1601
1602 /*************************
1603 * Scan for button presses
1604 ************************/
1605 button = pluginlib_getaction(rb, HZ/10, plugin_contexts, 2);
1606 switch (button)
1607 {
1608 case ACTION_COUNTER_TOGGLE: /* start/stop counter */
1609 if(clock_settings.general[general_counter])
1610 {
1611 if(!counter_btn_held) /* Ignore if the counter was reset */
1612 {
1613 if(counting)
1614 {
1615 counting = false;
1616 counter += passed_time;
1617 }
1618 else
1619 {
1620 counting = true;
1621 start_tick = *rb->current_tick;
1622 }
1623 }
1624 counter_btn_held = false;
1625 }
1626 break;
1627
1628 case ACTION_COUNTER_RESET: /* reset counter */
1629 if(clock_settings.general[general_counter])
1630 {
1631 counter_btn_held = true; /* Ignore the release event */
1632 counter = 0;
1633 start_tick = *rb->current_tick;
1634 }
1635 break;
1636
1637 case ACTION_MODE_NEXT:
1638 if(clock_settings.clock < CLOCK_MODES)
1639 clock_settings.clock++;
1640 else
1641 clock_settings.clock = 1;
1642
1643 set_digital_colors();
1644 break;
1645
1646 case ACTION_MODE_PREV:
1647 if(clock_settings.clock > 1)
1648 clock_settings.clock--;
1649 else
1650 clock_settings.clock = CLOCK_MODES;
1651
1652 set_digital_colors();
1653 break;
1654
1655 case ACTION_MENU:
1656 main_menu();
1657 break;
1658
1659 case ACTION_EXIT:
1660 exit_clock=true;
1661 break;
1662
1663 default:
1664 if(rb->default_event_handler_ex(button, cleanup, NULL)
1665 == SYS_USB_CONNECTED)
1666 return PLUGIN_USB_CONNECTED;
1667 break;
1668 }
1669 }
1670
1671 cleanup(NULL);
1672 return PLUGIN_OK;
1673}
diff --git a/apps/plugins/clock/Makefile b/apps/plugins/clock/Makefile
new file mode 100644
index 0000000000..0481d3e1c2
--- /dev/null
+++ b/apps/plugins/clock/Makefile
@@ -0,0 +1,112 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $$Id: $$
8#
9
10INCLUDES = -I$(APPSDIR) -I.. -I. -I$(APPSDIR)/plugins/lib \
11 $(TARGET_INC) -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
12 -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) -I$(BUILDDIR) \
13 -I$(BUILDDIR)/pluginbitmaps
14CFLAGS = $(INCLUDES) $(GCCOPTS) $(TARGET) $(EXTRA_DEFINES) \
15 -DTARGET_ID=$(TARGET_ID) -DMEM=${MEMORYSIZE} -DPLUGIN
16
17ifdef APPEXTRA
18 INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
19endif
20
21LINKFILE := $(OBJDIR)/link.lds
22DEPFILE = $(OBJDIR)/dep-clock
23
24# This sets up 'SRC' based on the files mentioned in SOURCES
25include $(TOOLSDIR)/makesrc.inc
26
27SOURCES = $(SRC)
28OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
29DIRS = .
30
31ifndef SIMVER
32 LDS := ../plugin.lds
33 OUTPUT = $(OUTDIR)/clock.rock
34else ## simulators
35 OUTPUT = $(OUTDIR)/clock.rock
36endif
37
38all: $(OUTPUT)
39
40ifndef SIMVER
41$(OBJDIR)/clock.elf: $(OBJS) $(LINKFILE) $(BITMAPLIBS)
42 $(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -O -nostdlib -o $@ $(OBJS) -L$(BUILDDIR) -lplugin -lgcc \
43 $(LINKBITMAPS) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/clock.map
44
45$(OUTPUT): $(OBJDIR)/clock.elf
46 $(call PRINTS,OBJCOPY $(@F))$(OC) -O binary $< $@
47else
48
49ifeq ($(SIMVER), x11)
50###################################################
51# This is the X11 simulator version
52
53$(OUTPUT): $(OBJS)
54 $(call PRINTS,LD $(@F))$(CC) $(CFLAGS) $(SHARED_FLAG) $(OBJS) -L$(BUILDDIR) -lplugin $(LINKBITMAPS) -o $@
55ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
56# 'x' must be kept or you'll have "Win32 error 5"
57# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
58# #define ERROR_ACCESS_DENIED 5L
59else
60 @chmod -x $@
61endif
62
63else # end of x11-simulator
64ifeq ($(SIMVER), sdl)
65###################################################
66# This is the SDL simulator version
67
68$(OUTPUT): $(OBJS)
69 $(call PRINTS,LD $(@F))$(CC) $(CFLAGS) $(SHARED_FLAG) $(OBJS) -L$(BUILDDIR) -lplugin $(LINKBITMAPS) -o $@
70ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
71# 'x' must be kept or you'll have "Win32 error 5"
72# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
73# #define ERROR_ACCESS_DENIED 5L
74else
75 @chmod -x $@
76endif
77
78else # end of sdl-simulator
79###################################################
80# This is the win32 simulator version
81DLLTOOLFLAGS = --export-all
82DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin
83
84$(OUTPUT): $(OBJS)
85 $(call PRINTS,DLL $(@F))$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $(OBJS)
86 $(SILENT)$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $(OBJS) \
87 $(BUILDDIR)/libplugin.a $(BITMAPLIBS) -o $@
88ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
89# 'x' must be kept or you'll have "Win32 error 5"
90# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
91# #define ERROR_ACCESS_DENIED 5L
92else
93 @chmod -x $@
94endif
95endif # end of win32-simulator
96endif
97endif # end of simulator section
98
99
100include $(TOOLSDIR)/make.inc
101
102# MEMORYSIZE should be passed on to this makefile with the chosen memory size
103# given in number of MB
104$(LINKFILE): $(LDS)
105 $(call PRINTS,build $(@F))cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) \
106 $(DEFINES) -E -P - >$@
107
108clean:
109 $(call PRINTS,cleaning clock)rm -rf $(OBJDIR)/clock
110 $(SILENT)rm -f $(OBJDIR)/clock.* $(DEPFILE)
111
112-include $(DEPFILE)
diff --git a/apps/plugins/clock/SOURCES b/apps/plugins/clock/SOURCES
new file mode 100644
index 0000000000..28fae83093
--- /dev/null
+++ b/apps/plugins/clock/SOURCES
@@ -0,0 +1,10 @@
1clock.c
2clock_bitmaps.c
3clock_bitmap_strings.c
4clock_counter.c
5clock_draw.c
6clock_draw_analog.c
7clock_draw_binary.c
8clock_draw_digital.c
9clock_menu.c
10clock_settings.c
diff --git a/apps/plugins/clock/clock.c b/apps/plugins/clock/clock.c
new file mode 100644
index 0000000000..46d167ba54
--- /dev/null
+++ b/apps/plugins/clock/clock.c
@@ -0,0 +1,199 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: clock.c 14095 2007-07-31 10:53:53Z nls $
9 *
10 * Copyright (C) 2007 Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "plugin.h"
21#include "time.h"
22#include "pluginlib_actions.h"
23#include "xlcd.h"
24
25#include "clock.h"
26#include "clock_counter.h"
27#include "clock_draw.h"
28#include "clock_menu.h"
29#include "clock_settings.h"
30
31PLUGIN_HEADER
32
33/* Keymaps */
34const struct button_mapping* plugin_contexts[]={
35 generic_actions,
36 generic_directions,
37#if NB_SCREENS == 2
38 remote_directions
39#endif
40};
41#define NB_ACTION_CONTEXTS sizeof(plugin_contexts)/sizeof(plugin_contexts[0])
42#define ACTION_COUNTER_TOGGLE PLA_FIRE
43#define ACTION_COUNTER_RESET PLA_FIRE_REPEAT
44#define ACTION_MENU PLA_MENU
45#define ACTION_EXIT PLA_QUIT
46#define ACTION_MODE_NEXT PLA_RIGHT
47#define ACTION_MODE_PREV PLA_LEFT
48#define ACTION_SKIN_NEXT PLA_UP
49#define ACTION_SKIN_PREV PLA_DOWN
50
51extern struct plugin_api* rb;
52
53/**************************
54 * Cleanup on plugin return
55 *************************/
56void cleanup(void *parameter)
57{
58 (void)parameter;
59 clock_draw_restore_colors();
60 if(clock_settings.general.save_settings == 1)
61 save_settings();
62
63 /* restore set backlight timeout */
64 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
65}
66
67/* puts the current time into the time struct */
68void clock_update_time( struct time* time){
69 struct tm* current_time = rb->get_time();
70 time->hour = current_time->tm_hour;
71 time->minute = current_time->tm_min;
72 time->second = current_time->tm_sec;
73
74 /*********************
75 * Date info
76 *********************/
77 time->year = current_time->tm_year + 1900;
78 time->day = current_time->tm_mday;
79 time->month = current_time->tm_mon + 1;
80
81}
82
83void format_date(char* buffer, struct time* time, enum date_format format){
84 switch(format){
85 case JAPANESE:
86 rb->snprintf(buffer, 20, "%04d/%02d/%02d",
87 time->year, time->month, time->day);
88 break;
89 case EUROPEAN:
90 rb->snprintf(buffer, 20, "%02d/%02d/%04d",
91 time->day, time->month, time->year);
92 break;
93 case ENGLISH:
94 rb->snprintf(buffer, 20, "%02d/%02d/%04d",
95 time->month, time->day, time->year);
96 break;
97 case NONE:
98 default:
99 break;
100 }
101}
102
103/**********************************************************************
104 * Plugin starts here
105 **********************************************************************/
106enum plugin_status plugin_start(struct plugin_api* api, void* parameter){
107 int button;
108 int last_second = -1;
109 bool redraw=true;
110 int i;
111 struct time time;
112 struct counter counter;
113 bool exit_clock = false;
114 (void)parameter;
115 rb = api;
116
117#if LCD_DEPTH > 1
118 rb->lcd_set_backdrop(NULL);
119#endif
120
121 load_settings();
122
123 /* init xlcd functions */
124 xlcd_init(rb);
125 counter_init(&counter);
126 clock_draw_set_colors();
127
128 while(!exit_clock){
129 clock_update_time(&time);
130
131 if(!clock_settings.general.idle_poweroff)
132 rb->reset_poweroff_timer();
133
134 /*************************
135 * Scan for button presses
136 ************************/
137 button = pluginlib_getaction(rb, HZ/10, plugin_contexts, NB_ACTION_CONTEXTS);
138 redraw=true;/* we'll set it to false afterwards if there was no action */
139 switch (button){
140 case ACTION_COUNTER_TOGGLE: /* start/stop counter */
141 if(clock_settings.general.show_counter)
142 counter_toggle(&counter);
143 break;
144
145 case ACTION_COUNTER_RESET: /* reset counter */
146 if(clock_settings.general.show_counter)
147 counter_reset(&counter);
148 break;
149
150 case ACTION_MODE_NEXT:
151 clock_settings.mode++;
152 if(clock_settings.mode >= NB_CLOCK_MODES)
153 clock_settings.mode = 0;
154 break;
155
156 case ACTION_MODE_PREV:
157 clock_settings.mode--;
158 if(clock_settings.mode < 0)
159 clock_settings.mode = NB_CLOCK_MODES-1;
160 break;
161 case ACTION_SKIN_PREV:
162 clock_settings_skin_next(&clock_settings);
163 break;
164 case ACTION_SKIN_NEXT:
165 clock_settings_skin_previous(&clock_settings);
166 break;
167 case ACTION_MENU:
168 clock_draw_restore_colors();
169 exit_clock=main_menu();
170 break;
171
172 case ACTION_EXIT:
173 /*clock_draw_restore_colors();
174 exit_clock=main_menu();*/
175 exit_clock=true;
176 break;
177
178 default:
179 redraw=false;
180 if(rb->default_event_handler_ex(button, cleanup, NULL)
181 == SYS_USB_CONNECTED)
182 return PLUGIN_USB_CONNECTED;
183 break;
184 }
185 if(time.second != last_second){
186 last_second=time.second;
187 redraw=true;
188 }
189 if(redraw){
190 clock_draw_set_colors();
191 FOR_NB_SCREENS(i)
192 clock_draw(rb->screens[i], &time, &counter);
193 redraw=false;
194 }
195 }
196
197 cleanup(NULL);
198 return PLUGIN_OK;
199}
diff --git a/apps/plugins/clock/clock.h b/apps/plugins/clock/clock.h
new file mode 100644
index 0000000000..bd5b74fa56
--- /dev/null
+++ b/apps/plugins/clock/clock.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _CLOCK_
21#define _CLOCK_
22#include "clock_settings.h"
23extern struct plugin_api* rb;
24
25struct time{
26 int year, day, month;
27 int hour, minute, second;
28};
29
30void format_date(char* buffer, struct time* time, enum date_format format);
31
32#endif /* _CLOCK_ */
diff --git a/apps/plugins/clock/clock_bitmap_strings.c b/apps/plugins/clock/clock_bitmap_strings.c
new file mode 100644
index 0000000000..f2bef78f12
--- /dev/null
+++ b/apps/plugins/clock/clock_bitmap_strings.c
@@ -0,0 +1,46 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "clock.h"
21#include "clock_bitmap_strings.h"
22
23void draw_string(struct screen* display, const struct picture* bitmaps,
24 char* str, int x, int y){
25 int i, bitmap_pos;
26 char c;
27 for(i=0;(c=str[i]);i++){
28 bitmap_pos=-1;
29 if(c>='0'&&c<='9')
30 bitmap_pos=c-'0';
31 else if(c==':')
32 bitmap_pos=10;
33 else if(c=='A' || c=='/')/* 'AM' in digits, '/' in smalldigits */
34 bitmap_pos=11;
35 else if(c=='P' || c=='.')/* 'PM' in digits, '.' in smalldigits */
36 bitmap_pos=12;
37 if(bitmap_pos>=0)
38 vertical_picture_draw_sprite(display, bitmaps, bitmap_pos,
39 x+i*bitmaps->width, y);
40 }
41}
42
43void getstringsize(const struct picture* bitmaps, char* str, int *w, int *h ){
44 *h=bitmaps->height;
45 *w=rb->strlen(str)*bitmaps->width;
46}
diff --git a/apps/plugins/clock/clock_bitmap_strings.h b/apps/plugins/clock/clock_bitmap_strings.h
new file mode 100644
index 0000000000..61f5ac5953
--- /dev/null
+++ b/apps/plugins/clock/clock_bitmap_strings.h
@@ -0,0 +1,31 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20
21#ifndef _CLOCK_BITMAP_STRINGS_
22#define _CLOCK_BITMAP_STRINGS_
23#include "plugin.h"
24#include "picture.h"
25
26void draw_string(struct screen* display, const struct picture* bitmaps,
27 char* str, int x, int y);
28
29void getstringsize(const struct picture* bitmaps, char* str, int *w, int *h );
30
31#endif /* _CLOCK_BITMAP_STRINGS_ */
diff --git a/apps/plugins/clock/clock_bitmaps.c b/apps/plugins/clock/clock_bitmaps.c
new file mode 100644
index 0000000000..c8550d180a
--- /dev/null
+++ b/apps/plugins/clock/clock_bitmaps.c
@@ -0,0 +1,105 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20
21#include "clock_bitmaps.h"
22
23/* bitmaps */
24#include "clock_binary.h"
25#include "clock_digits.h"
26#include "clock_smalldigits.h"
27#include "clock_segments.h"
28#include "clock_smallsegments.h"
29
30#include "clock_logo.h"
31#include "clock_messages.h"
32
33#if NB_SCREENS==2
34#include "clock_binary_remote.h"
35#include "clock_digits_remote.h"
36#include "clock_smalldigits_remote.h"
37#include "clock_segments_remote.h"
38#include "clock_smallsegments_remote.h"
39
40#include "clock_logo_remote.h"
41#include "clock_messages_remote.h"
42
43#endif
44
45
46const struct picture logos[]={
47 {clock_logo, BMPWIDTH_clock_logo, BMPHEIGHT_clock_logo},
48#if NB_SCREENS==2
49 {clock_logo_remote,BMPWIDTH_clock_logo_remote,BMPHEIGHT_clock_logo_remote}
50#endif
51};
52
53const struct picture messages[]={
54 {clock_messages,BMPWIDTH_clock_messages,
55 BMPHEIGHT_clock_messages/6},
56#if NB_SCREENS==2
57 {clock_messages_remote,BMPWIDTH_clock_messages_remote,
58 BMPHEIGHT_clock_messages_remote/6}
59#endif
60};
61
62const struct picture binary[]={
63 {clock_binary,
64 BMPWIDTH_clock_binary, BMPHEIGHT_clock_binary/2 },
65#if NB_SCREENS==2
66 {clock_binary_remote,
67 BMPWIDTH_clock_binary_remote,BMPHEIGHT_clock_binary_remote/2}
68#endif
69};
70
71const struct picture digits[]={
72 {clock_digits,
73 BMPWIDTH_clock_digits, BMPHEIGHT_clock_digits/13 },
74#if NB_SCREENS==2
75 {clock_digits_remote,
76 BMPWIDTH_clock_digits_remote,BMPHEIGHT_clock_digits_remote/13}
77#endif
78};
79
80const struct picture smalldigits[]={
81 {clock_smalldigits,
82 BMPWIDTH_clock_smalldigits, BMPHEIGHT_clock_smalldigits/13 },
83#if NB_SCREENS==2
84 {clock_smalldigits_remote,
85 BMPWIDTH_clock_smalldigits_remote,BMPHEIGHT_clock_smalldigits_remote/13}
86#endif
87};
88
89const struct picture segments[]={
90 {clock_segments,
91 BMPWIDTH_clock_segments, BMPHEIGHT_clock_segments/13 },
92#if NB_SCREENS==2
93 {clock_segments_remote,
94 BMPWIDTH_clock_segments_remote,BMPHEIGHT_clock_segments_remote/13}
95#endif
96};
97
98const struct picture smallsegments[]={
99 {clock_smallsegments,
100 BMPWIDTH_clock_smallsegments, BMPHEIGHT_clock_smallsegments/13 },
101#if NB_SCREENS==2
102 {clock_smallsegments_remote,
103 BMPWIDTH_clock_smallsegments_remote,BMPHEIGHT_clock_smallsegments_remote/13}
104#endif
105};
diff --git a/apps/plugins/clock/clock_bitmaps.h b/apps/plugins/clock/clock_bitmaps.h
new file mode 100644
index 0000000000..a3986f3b4f
--- /dev/null
+++ b/apps/plugins/clock/clock_bitmaps.h
@@ -0,0 +1,33 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _CLOCK_BITMAPS_
21#define _CLOCK_BITMAPS_
22#include "picture.h"
23
24extern const struct picture logos[];
25extern const struct picture messages[];
26
27extern const struct picture binary[];
28extern const struct picture digits[];
29extern const struct picture smalldigits[];
30extern const struct picture segments[];
31extern const struct picture smallsegments[];
32
33#endif
diff --git a/apps/plugins/clock/clock_counter.c b/apps/plugins/clock/clock_counter.c
new file mode 100644
index 0000000000..7137eeaf38
--- /dev/null
+++ b/apps/plugins/clock/clock_counter.c
@@ -0,0 +1,42 @@
1#include "clock_counter.h"
2#include "clock_bitmap_strings.h"
3
4void counter_init(struct counter* counter){
5 counter->ticks_since_started=0;
6 counter->ticks_at_last_unpause=0;
7 counter->paused=true;
8}
9
10int counter_get_ticks_since_last_pause(struct counter* counter){
11 if(!counter->paused)
12 return(*rb->current_tick - counter->ticks_at_last_unpause);
13 return(0);
14}
15
16void counter_toggle(struct counter* counter){
17 counter_pause(counter, !counter->paused);
18}
19
20void counter_pause(struct counter* counter, bool pause){
21 if(pause){
22 counter->ticks_since_started+=counter_get_ticks_since_last_pause(counter);
23 }else{
24 counter->ticks_at_last_unpause=*rb->current_tick;
25 }
26 counter->paused=pause;
27}
28
29void counter_get_elapsed_time(struct counter* counter, struct time* elapsed_time){
30 int total_time=counter_get_ticks_since_last_pause(counter);
31 total_time+=counter->ticks_since_started;
32 total_time/=HZ;/* converts ticks to seconds */
33
34 elapsed_time->second = total_time%60;
35 elapsed_time->minute = (total_time%3600) / 60;
36 elapsed_time->hour = total_time / 3600;
37 /* not yet ! */
38 elapsed_time->day=0;
39 elapsed_time->month=0;
40 elapsed_time->year=0;
41}
42
diff --git a/apps/plugins/clock/clock_counter.h b/apps/plugins/clock/clock_counter.h
new file mode 100644
index 0000000000..25523d45f6
--- /dev/null
+++ b/apps/plugins/clock/clock_counter.h
@@ -0,0 +1,19 @@
1#ifndef _CLOCK_MESSAGE_
2#define _CLOCK_MESSAGE_
3#include "clock.h"
4#include "plugin.h"
5#include "picture.h"
6
7struct counter{
8 int ticks_at_last_unpause;/* to count the time from last pause to now */
9 int ticks_since_started;/* accumulated time */
10 bool paused;
11};
12
13void counter_init(struct counter* counter);
14void counter_toggle(struct counter* counter);
15#define counter_reset(counter) counter_init(counter)
16void counter_pause(struct counter* counter, bool paused);
17void counter_get_elapsed_time(struct counter* counter, struct time* elapsed_time);
18
19#endif /* _CLOCK_MESSAGE_ */
diff --git a/apps/plugins/clock/clock_draw.c b/apps/plugins/clock/clock_draw.c
new file mode 100644
index 0000000000..daf19f7363
--- /dev/null
+++ b/apps/plugins/clock/clock_draw.c
@@ -0,0 +1,103 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "clock.h"
21#include "clock_draw.h"
22#include "clock_draw_digital.h"
23#include "clock_draw_analog.h"
24#include "clock_draw_binary.h"
25#include "clock_settings.h"
26
27void black_background(struct screen* display){
28#if (LCD_DEPTH > 1) || (defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH > 1))
29 if(display->depth>1){
30 display->set_background(LCD_BLACK);
31 display->clear_display();
32 }else
33#endif
34 {
35 display->clear_display();
36 display->fillrect(0,0,display->width,display->height);
37 }
38}
39
40void white_background(struct screen* display){
41#if (LCD_DEPTH > 1) || (defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH > 1))
42 if(display->depth>1){
43#if defined(HAVE_LCD_COLOR)
44 if(display->is_color)/* restore to the bitmap's background */
45 display->set_background(LCD_RGBPACK(180,200,230));
46 else
47#endif
48 display->set_background(LCD_WHITE);
49 }
50#endif
51 display->clear_display();
52}
53
54bool skin_require_black_background(int mode, int skin){
55 return((mode==BINARY && skin==2) || (mode==DIGITAL && skin==1 ));
56}
57
58void skin_set_background(struct screen* display, int mode, int skin){
59 if(skin_require_black_background(mode, skin) )
60 black_background(display);
61 else
62 white_background(display);
63}
64
65void skin_restore_background(struct screen* display, int mode, int skin){
66 if(skin_require_black_background(mode, skin) )
67 white_background(display);
68}
69
70void clock_draw_set_colors(void){
71 int i;
72 FOR_NB_SCREENS(i)
73 skin_set_background(rb->screens[i],
74 clock_settings.mode,
75 clock_settings.skin[clock_settings.mode]);
76}
77
78void clock_draw_restore_colors(void){
79 int i;
80 FOR_NB_SCREENS(i){
81 skin_restore_background(rb->screens[i],
82 clock_settings.mode,
83 clock_settings.skin[clock_settings.mode]);
84 rb->screens[i]->update();
85 }
86}
87
88void clock_draw(struct screen* display, struct time* time,
89 struct counter* counter){
90 if(!clock_settings.general.show_counter)
91 counter=0;
92 int skin=clock_settings.skin[clock_settings.mode];
93 skin_set_background(display, clock_settings.mode, skin);
94 if(clock_settings.mode == ANALOG)
95 analog_clock_draw(display, time, &clock_settings, counter, skin);
96
97 else if(clock_settings.mode == DIGITAL)
98 digital_clock_draw(display, time, &clock_settings, counter, skin);
99
100 else if(clock_settings.mode == BINARY)
101 binary_clock_draw(display, time, skin);
102 display->update();
103}
diff --git a/apps/plugins/clock/clock_draw.h b/apps/plugins/clock/clock_draw.h
new file mode 100644
index 0000000000..b589b7ee0e
--- /dev/null
+++ b/apps/plugins/clock/clock_draw.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _CLOCK_DRAW_
21#define _CLOCK_DRAW_
22#include "plugin.h"
23#include "clock.h"
24#include "clock_counter.h"
25
26void clock_draw_set_colors(void);
27void clock_draw_restore_colors(void);
28
29void clock_draw(struct screen* display, struct time* time,
30 struct counter* counter);
31
32#endif /* _CLOCK_DRAW_ */
diff --git a/apps/plugins/clock/clock_draw_analog.c b/apps/plugins/clock/clock_draw_analog.c
new file mode 100644
index 0000000000..1fd98773f2
--- /dev/null
+++ b/apps/plugins/clock/clock_draw_analog.c
@@ -0,0 +1,217 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare based on Zakk Roberts's work
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "clock_draw_analog.h"
21#include "xlcd.h"
22#include "fixedpoint.h"
23#include "clock_bitmaps.h"
24#include "clock_bitmap_strings.h"
25
26#define ANALOG_SECOND_RADIUS(screen, round) \
27 ANALOG_MINUTE_RADIUS(screen, round)
28#define ANALOG_MINUTE_RADIUS(screen, round) \
29 (round?MIN(screen->height/2 -10, screen->width/2 -10):screen->height/2)
30#define ANALOG_HOUR_RADIUS(screen, round) \
31 (ANALOG_MINUTE_RADIUS(screen, round)/2)
32
33#define HOUR_ANGLE(hour, minute, second) (30*(hour) +(minute)/2)
34#define MINUTE_ANGLE(minute, second) (6*(minute)+(second)/10)
35#define SECOND_ANGLE(second) (6 * (second))
36
37void polar_to_cartesian(int a, int r, int* x, int* y){
38 *x = (sin_int(a) * r) >> 14;
39 *y = (sin_int(a-90) * r) >> 14;
40}
41
42void polar_to_cartesian_screen_centered(struct screen * display,
43 int a, int r, int* x, int* y){
44 polar_to_cartesian(a, r, x, y);
45 *x+=display->width/2;
46 *y+=display->height/2;
47}
48
49void angle_to_square(int square_width, int square_height,
50 int a, int* x, int* y){
51 a = (a+360-90)%360;
52 if(a>45 && a<=135){/* top line */
53 a-=45;
54 *x=square_width-(square_width*2*a)/90;
55 *y=square_height;
56 }else if(a>135 && a<=225){/* left line */
57 a-=135;
58 *x=-square_width;
59 *y=square_height-(square_height*2*a)/90;
60 }else if(a>225 && a<=315){/* bottom line */
61 a-=225;
62 *x=(square_width*2*a)/90-square_width;
63 *y=-square_height;
64 }else if(a>315 || a<=45){/* right line */
65 if(a>315)
66 a-=315;
67 else
68 a+=45;
69 *x=square_width;
70 *y=(square_height*2*a)/90-square_height;
71 }
72}
73
74void angle_to_square_screen_centered(struct screen * display,
75 int square_width, int square_height,
76 int a, int* x, int* y){
77 angle_to_square(square_width, square_height, a, x, y);
78 *x+=display->width/2;
79 *y+=display->height/2;
80}
81
82void draw_hand(struct screen* display, int angle,
83 int radius, int thickness, bool round){
84 int x1, y1; /* the longest */
85 int x2, y2, x3, y3; /* the base */
86 if(round){/* round clock */
87 polar_to_cartesian_screen_centered(display, angle,
88 radius, &x1, &y1);
89 }else{/* fullscreen clock, hands describes square motions */
90 int square_width, square_height;
91 /* radius is defined smallest between width and height */
92 square_height=radius;
93 square_width=(radius*display->width)/display->height;
94 angle_to_square_screen_centered(
95 display, square_width, square_height, angle, &x1, &y1);
96 }
97 polar_to_cartesian_screen_centered(display, (angle+120)%360,
98 radius/40+thickness, &x2, &y2);
99 polar_to_cartesian_screen_centered(display, (angle+240)%360,
100 radius/40+thickness, &x3, &y3);
101 xlcd_filltriangle_screen(display, x1, y1, x2, y2, x3, y3);
102}
103
104void draw_hands(struct screen* display, int hour, int minute, int second,
105 int thickness, bool round, bool draw_seconds){
106 if(draw_seconds){
107 draw_hand(display, SECOND_ANGLE(second),
108 ANALOG_SECOND_RADIUS(display, round), thickness, round);
109 }
110 draw_hand(display, MINUTE_ANGLE(minute, second),
111 ANALOG_MINUTE_RADIUS(display, round), thickness+2, round);
112 draw_hand(display, HOUR_ANGLE(hour, minute, second),
113 ANALOG_HOUR_RADIUS(display, round), thickness+2, round);
114}
115
116/*******************
117 * Analog clock mode
118 ******************/
119void analog_clock_draw(struct screen* display, struct time* time,
120 struct clock_settings* settings,
121 struct counter* counter,
122 int skin){
123 int i;
124 const struct picture* smalldigits_bitmaps =
125 &(smalldigits[display->screen_type]);
126 int hour=time->hour;
127 if(hour >= 12)
128 hour -= 12;
129
130 /* show_date */
131 /* show_digital_time*/
132
133 /* Crappy fake antialiasing (color LCDs only)!
134 * how this works is we draw a large mid-gray hr/min/sec hand,
135 * then the actual (slightly smaller) hand on top of those.
136 * End result: mid-gray edges to the black hands, smooths them out. */
137#ifdef HAVE_LCD_COLOR
138 if(display->is_color){
139 display->set_foreground(LCD_RGBPACK(100,110,125));
140 draw_hands(display, hour, time->minute, time->second, 2,
141 skin, settings->analog.show_seconds);
142 display->set_foreground(LCD_BLACK);
143 }
144#endif
145 draw_hands(display, hour, time->minute, time->second, 0, skin,
146 settings->analog.show_seconds);
147
148 if(settings->analog.show_border){
149 /* Draws square dots every 5 minutes */
150 int x, y;
151 int size=display->height/50;/* size of the square dots */
152 if(size%2)/* a pair number */
153 size++;
154 for(i=0; i < 60; i+=5){
155 if(skin){
156 polar_to_cartesian_screen_centered(display, MINUTE_ANGLE(i, 0),
157 ANALOG_MINUTE_RADIUS(display, skin), &x, &y);
158 }else{
159 angle_to_square_screen_centered(
160 display, display->width/2-size/2, display->height/2-size/2,
161 MINUTE_ANGLE(i, 0), &x, &y);
162 }
163 display->fillrect(x-size/2, y-size/2, size, size);
164 }
165 }
166
167 if(counter){
168 char buffer[10];
169 int second_str_w, hour_str_w, str_h;
170 struct time counter_time;
171 counter_get_elapsed_time(counter, &counter_time);
172 rb->snprintf(buffer, 10, "%02d:%02d",
173 counter_time.hour, counter_time.minute);
174 getstringsize(smalldigits_bitmaps, buffer, &hour_str_w, &str_h);
175 draw_string(display, smalldigits_bitmaps, buffer,
176 display->width-hour_str_w,
177 display->height-2*str_h);
178
179 rb->snprintf(buffer, 10, "%02d", counter_time.second);
180 getstringsize(smalldigits_bitmaps, buffer, &second_str_w, &str_h);
181 draw_string(display, smalldigits_bitmaps, buffer,
182 display->width-(hour_str_w+second_str_w)/2,
183 display->height-str_h);
184 }
185 if(settings->analog.show_date && settings->general.date_format!=NONE){
186 char buffer[10];
187 int year_str_w, monthday_str_w, str_h;
188 if(settings->general.date_format==ENGLISH){
189 rb->snprintf(buffer, 10, "%02d/%02d", time->month, time->day);
190 }else{
191 rb->snprintf(buffer, 10, "%02d/%02d", time->day, time->month);
192 }
193 getstringsize(smalldigits_bitmaps, buffer, &monthday_str_w, &str_h);
194 draw_string(display, smalldigits_bitmaps, buffer,
195 0, display->height-2*str_h);
196 rb->snprintf(buffer, 10, "%04d", time->year);
197 getstringsize(smalldigits_bitmaps, buffer, &year_str_w, &str_h);
198 draw_string(display, smalldigits_bitmaps, buffer,
199 (monthday_str_w-year_str_w)/2, display->height-str_h);
200 }
201
202 /* Draw the cover over the center */
203 display->drawline((display->width/2)-1, (display->height/2)+3,
204 (display->width/2)+1, (display->height/2)+3);
205 display->drawline((display->width/2)-3, (display->height/2)+2,
206 (display->width/2)+3, (display->height/2)+2);
207 display->drawline((display->width/2)-4, (display->height/2)+1,
208 (display->width/2)+4, (display->height/2)+1);
209 display->drawline((display->width/2)-4, display->height/2,
210 (display->width/2)+4, display->height/2);
211 display->drawline((display->width/2)-4, (display->height/2)-1,
212 (display->width/2)+4, (display->height/2)-1);
213 display->drawline((display->width/2)-3, (display->height/2)-2,
214 (display->width/2)+3, (display->height/2)-2);
215 display->drawline((display->width/2)-1, (display->height/2)-3,
216 (display->width/2)+1, (display->height/2)-3);
217}
diff --git a/apps/plugins/clock/clock_draw_analog.h b/apps/plugins/clock/clock_draw_analog.h
new file mode 100644
index 0000000000..4b8f3f8432
--- /dev/null
+++ b/apps/plugins/clock/clock_draw_analog.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _ANALOG_CLOCK_
21#define _ANALOG_CLOCK_
22#include "plugin.h"
23#include "clock.h"
24#include "clock_counter.h"
25#include "clock_settings.h"
26
27void analog_clock_draw(struct screen* display, struct time* time,
28 struct clock_settings* settings,
29 struct counter* counter,
30 int skin);
31
32#endif /* _ANALOG_CLOCK_ */
diff --git a/apps/plugins/clock/clock_draw_binary.c b/apps/plugins/clock/clock_draw_binary.c
new file mode 100644
index 0000000000..5bc84f1583
--- /dev/null
+++ b/apps/plugins/clock/clock_draw_binary.c
@@ -0,0 +1,51 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "clock_draw_binary.h"
20#include "clock_bitmap_strings.h"
21#include "clock_bitmaps.h"
22#include "picture.h"
23
24const struct picture* binary_skin[]={binary,digits,segments};
25
26void print_binary(char* buffer, int number, int nb_bits){
27 int i;
28 int mask=1;
29 buffer[nb_bits]='\0';
30 for(i=0; i<nb_bits; i++){
31 if((number & mask) !=0)
32 buffer[nb_bits-i-1]='1';
33 else
34 buffer[nb_bits-i-1]='0';
35 mask=mask<<1;
36 }
37}
38
39void binary_clock_draw(struct screen* display, struct time* time, int skin){
40 int lines_values[]={
41 time->hour,time->minute,time->second
42 };
43 char buffer[9];
44 int i;
45 const struct picture* binary_bitmaps = &(binary_skin[skin][display->screen_type]);
46 for(i=0;i<3;i++){
47 print_binary(buffer, lines_values[i], 6);
48 draw_string(display, binary_bitmaps, buffer, 0,
49 binary_bitmaps->height*i);
50 }
51}
diff --git a/apps/plugins/clock/clock_draw_binary.h b/apps/plugins/clock/clock_draw_binary.h
new file mode 100644
index 0000000000..323a640442
--- /dev/null
+++ b/apps/plugins/clock/clock_draw_binary.h
@@ -0,0 +1,27 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _BINARY_CLOCK_
21#define _BINARY_CLOCK_
22#include "plugin.h"
23#include "clock.h"
24
25void binary_clock_draw(struct screen* display, struct time* time, int skin);
26
27#endif /* _BINARY_CLOCK_ */
diff --git a/apps/plugins/clock/clock_draw_digital.c b/apps/plugins/clock/clock_draw_digital.c
new file mode 100644
index 0000000000..9fff47c520
--- /dev/null
+++ b/apps/plugins/clock/clock_draw_digital.c
@@ -0,0 +1,87 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "clock.h"
21#include "clock_draw_digital.h"
22#include "clock_bitmap_strings.h"
23#include "clock_bitmaps.h"
24#include "picture.h"
25
26const struct picture* digits_skin[]={digits,segments};
27const struct picture* smalldigits_skin[]={smalldigits,smallsegments};
28
29#define buffer_printf(buffer, buffer_pos, ... ) \
30 buffer_pos+=rb->snprintf(&buffer[buffer_pos], sizeof(buffer)-buffer_pos, __VA_ARGS__);
31
32void digital_clock_draw(struct screen* display,
33 struct time* time,
34 struct clock_settings* settings,
35 struct counter* counter,
36 int skin){
37 bool display_colon;
38 const struct picture* digits_bitmaps = &(digits_skin[skin][display->screen_type]);
39 const struct picture* smalldigits_bitmaps = &(smalldigits_skin[skin][display->screen_type]);
40 int hour=time->hour;
41 int str_w, str_h;
42 char buffer[20];
43 int buffer_pos=0;
44
45 if(settings->digital.blinkcolon){
46 display_colon=(time->second%2==0);
47 }
48 else
49 display_colon=true;
50
51 if(settings->general.hour_format==H12){/* AM/PM format */
52 if(hour>12){
53 buffer_printf(buffer, buffer_pos, "P");/* AM */
54 /* readjust the hour to 12-hour format
55 * ( 13:00+ -> 1:00+ ) */
56 hour -= 12;
57 }else
58 buffer_printf(buffer, buffer_pos, "A");/* AM */
59 }
60 buffer_printf(buffer, buffer_pos, "%02d", hour);
61 buffer_printf(buffer, buffer_pos, "%c", display_colon?':':' ');
62 buffer_printf(buffer, buffer_pos, "%02d", time->minute);
63 getstringsize(digits_bitmaps, buffer, &str_w, &str_h);
64 draw_string(display, digits_bitmaps, buffer, (display->width-str_w)/2, 0);
65 if(settings->digital.show_seconds){
66 buffer_pos=0;
67 buffer_printf(buffer, buffer_pos, "%02d", time->second);
68 getstringsize(digits_bitmaps, buffer, &str_w, &str_h);
69 draw_string(display, digits_bitmaps, buffer, (display->width-str_w)/2,
70 digits_bitmaps->height);
71 }
72 if(settings->general.date_format!=NONE){
73 format_date(buffer, time, settings->general.date_format);
74 getstringsize(smalldigits_bitmaps, buffer, &str_w, &str_h);
75 draw_string(display, smalldigits_bitmaps, buffer, (display->width-str_w)/2,
76 display->height-smalldigits_bitmaps->height*2);
77 }
78 if(counter){
79 struct time counter_time;
80 counter_get_elapsed_time(counter, &counter_time);
81 rb->snprintf(buffer, 20, "%02d:%02d:%02d",
82 counter_time.hour, counter_time.minute, counter_time.second);
83 getstringsize(smalldigits_bitmaps, buffer, &str_w, &str_h);
84 draw_string(display, smalldigits_bitmaps, buffer, (display->width-str_w)/2,
85 display->height-str_h);
86 }
87}
diff --git a/apps/plugins/clock/clock_draw_digital.h b/apps/plugins/clock/clock_draw_digital.h
new file mode 100644
index 0000000000..b967e67571
--- /dev/null
+++ b/apps/plugins/clock/clock_draw_digital.h
@@ -0,0 +1,31 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _DIGITAL_CLOCK_
21#define _DIGITAL_CLOCK_
22#include "plugin.h"
23#include "clock.h"
24#include "clock_counter.h"
25#include "clock_settings.h"
26
27void digital_clock_draw(struct screen* display, struct time* time,
28 struct clock_settings* settings,
29 struct counter* counter, int skin);
30
31#endif /* _DIGITAL_CLOCK_ */
diff --git a/apps/plugins/clock/clock_menu.c b/apps/plugins/clock/clock_menu.c
new file mode 100644
index 0000000000..3310dbf929
--- /dev/null
+++ b/apps/plugins/clock/clock_menu.c
@@ -0,0 +1,246 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2003 Zakk Roberts
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "clock.h"
21#include "clock_bitmaps.h"
22#include "clock_settings.h"
23
24/* Option structs (possible selections per each option) */
25static const struct opt_items noyes_text[] = {
26 { "No", -1 },
27 { "Yes", -1 }
28};
29
30static const struct opt_items backlight_settings_text[] = {
31 { "Always Off", -1 },
32 { "Rockbox setting", -1 },
33 { "Always On", -1 }
34};
35
36static const struct opt_items idle_poweroff_text[] = {
37 { "Disabled", -1 },
38 { "Enabled", -1 }
39};
40
41static const struct opt_items date_format_text[] = {
42 { "No date", -1 },
43 { "English format", -1 },
44 { "European format", -1 },
45 { "Japanese format", -1 },
46};
47
48static const struct opt_items hour_format_text[] = {
49 { "24-hour Format", -1 },
50 { "12-hour Format", -1 }
51};
52
53/***************
54 * Select a mode, returs true when the mode has been selected
55 * (we go back to clock display then)
56 **************/
57bool menu_mode_selector(void){
58 MENUITEM_STRINGLIST(menu,"Mode Selector",NULL, "Analog",
59 "Digital", "Binary");
60 if(rb->do_menu(&menu, &clock_settings.mode) >=0)
61 return(true);
62 return(false);
63}
64
65/**********************
66 * Analog settings menu
67 *********************/
68void menu_analog_settings(void)
69{
70 int selection=0, result=0;
71
72 MENUITEM_STRINGLIST(menu,"Analog Mode Settings",NULL,"Show Date",
73 "Show Second Hand","Show Border");
74
75 while(result>=0){
76 result=rb->do_menu(&menu, &selection);
77 switch(result){
78 case 0:
79 rb->set_option("Show Date", &clock_settings.analog.show_date,
80 BOOL, noyes_text, 2, NULL);
81 break;
82 case 1:
83 rb->set_option("Show Second Hand",
84 &clock_settings.analog.show_seconds,
85 BOOL, noyes_text, 2, NULL);
86 break;
87 case 2:
88 rb->set_option("Show Border",
89 &clock_settings.analog.show_border,
90 BOOL, noyes_text, 2, NULL);
91 break;
92 }
93 }
94}
95
96/***********************
97 * Digital settings menu
98 **********************/
99void menu_digital_settings(void){
100 int selection=0, result=0;
101
102 MENUITEM_STRINGLIST(menu,"Digital Mode Settings",NULL,"Show Seconds",
103 "Blinking Colon");
104
105 while(result>=0){
106 result=rb->do_menu(&menu, &selection);
107 switch(result){
108 case 0:
109 rb->set_option("Show Seconds",
110 &clock_settings.digital.show_seconds,
111 BOOL, noyes_text, 2, NULL);
112 break;
113 case 1:
114 rb->set_option("Blinking Colon",
115 &clock_settings.digital.blinkcolon,
116 BOOL, noyes_text, 2, NULL);
117 break;
118 }
119 }
120}
121
122/***********************************************************
123 * Confirm resetting of settings, used in general_settings()
124 **********************************************************/
125void confirm_reset(void){
126 int result=0;
127
128 rb->set_option("Reset all settings?", &result, INT, noyes_text, 2, NULL);
129
130 if(result == 1){ /* reset! */
131 clock_settings_reset(&clock_settings);
132 rb->splash(HZ, "Settings reset!");
133 }
134 else
135 rb->splash(HZ, "Settings NOT reset.");
136}
137
138/************************************
139 * General settings. Reset, save, etc
140 ***********************************/
141void menu_general_settings(void){
142 int selection=0, result=0;
143
144 MENUITEM_STRINGLIST(menu,"General Settings",NULL,
145 "Hour format","Date format","Show Counter",
146 "Reset Settings","Save Settings Now",
147 "Save On Exit","Backlight Settings",
148 "Idle Poweroff (temporary)");
149
150 while(result>=0){
151 result=rb->do_menu(&menu, &selection);
152 switch(result){
153 case 0:
154 rb->set_option("Hour format",
155 &clock_settings.general.hour_format,
156 INT, hour_format_text, 2, NULL);
157 break;
158 case 1:
159 rb->set_option("Date format",
160 &clock_settings.general.date_format,
161 INT, date_format_text, 4, NULL);
162 break;
163 case 2:
164 rb->set_option("Show Counter", &clock_settings.general.show_counter,
165 BOOL, noyes_text, 2, NULL);
166 break;
167 case 3:
168 confirm_reset();
169 break;
170
171 case 4:
172 save_settings_wo_gui();
173 rb->splash(HZ, "Settings saved");
174 break;
175
176 case 5:
177 rb->set_option("Save On Exit",
178 &clock_settings.general.save_settings,
179 BOOL, noyes_text, 2, NULL);
180
181 /* if we no longer save on exit,
182 we better save now to remember that */
183 if(!clock_settings.general.save_settings)
184 save_settings_wo_gui();
185 break;
186 case 6:
187 rb->set_option("Backlight Settings",
188 &clock_settings.general.backlight,
189 INT, backlight_settings_text, 3, NULL);
190 apply_backlight_setting(clock_settings.general.backlight);
191 break;
192
193 case 7:
194 rb->set_option("Idle Poweroff (temporary)",
195 &clock_settings.general.idle_poweroff,
196 BOOL, idle_poweroff_text, 2, NULL);
197 break;
198 }
199 }
200}
201
202/***********
203 * Main menu
204 **********/
205bool main_menu(void){
206 int selection=0;
207 bool done = false;
208 bool exit_clock=false;
209
210 MENUITEM_STRINGLIST(menu,"Clock Menu",NULL,"View Clock","Mode Selector",
211 "Mode Settings","General Settings","Quit");
212
213 while(!done){
214 switch(rb->do_menu(&menu, &selection)){
215 case 0:
216 done = true;
217 break;
218
219 case 1:
220 done=menu_mode_selector();
221 break;
222
223 case 2:
224 switch(clock_settings.mode){
225 case ANALOG: menu_analog_settings();break;
226 case DIGITAL: menu_digital_settings();break;
227 case BINARY: /* no settings */;break;
228 }
229 break;
230
231 case 3:
232 menu_general_settings();
233 break;
234
235 case 4:
236 exit_clock = true;
237 done = true;
238 break;
239
240 default:
241 done=true;
242 break;
243 }
244 }
245 return(exit_clock);
246}
diff --git a/apps/plugins/clock/clock_menu.h b/apps/plugins/clock/clock_menu.h
new file mode 100644
index 0000000000..c02a42ce2a
--- /dev/null
+++ b/apps/plugins/clock/clock_menu.h
@@ -0,0 +1,7 @@
1
2#ifndef _CLOCK_MENU_
3#define _CLOCK_MENU_
4
5bool main_menu(void);
6
7#endif /* _CLOCK_MENU_ */
diff --git a/apps/plugins/clock/clock_settings.c b/apps/plugins/clock/clock_settings.c
new file mode 100644
index 0000000000..9bd7c90d3b
--- /dev/null
+++ b/apps/plugins/clock/clock_settings.c
@@ -0,0 +1,200 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare based on Zakk Roberts's work
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "clock.h"
21#include "clock_bitmaps.h"
22#include "clock_draw.h"
23#include "clock_settings.h"
24#include "picture.h"
25
26static int max_skin[]={
27 [ANALOG]=2,
28 [BINARY]=3,
29 [DIGITAL]=2,
30};
31
32enum message{
33 MESSAGE_LOADING,
34 MESSAGE_LOADED,
35 MESSAGE_ERRLOAD,
36 MESSAGE_SAVING,
37 MESSAGE_SAVED,
38 MESSAGE_ERRSAVE
39};
40
41enum settings_file_status{
42 LOADED, ERRLOAD,
43 SAVED, ERRSAVE
44};
45
46struct clock_settings clock_settings;
47
48void clock_settings_reset(struct clock_settings* settings){
49 settings->mode = ANALOG;
50 int i;
51 for(i=0;i<NB_CLOCK_MODES;i++){
52 settings->skin[i]=0;
53 }
54 settings->general.hour_format = H12;
55 settings->general.date_format = EUROPEAN;
56 settings->general.show_counter = true;
57 settings->general.save_settings = true;
58 settings->general.idle_poweroff=true;
59 settings->general.backlight = ROCKBOX_SETTING;
60
61 settings->analog.show_date = false;
62 settings->analog.show_seconds = true;
63 settings->analog.show_border = true;
64
65 settings->digital.show_seconds = true;
66 settings->digital.blinkcolon = false;
67 apply_backlight_setting(settings->general.backlight);
68}
69
70void apply_backlight_setting(int backlight_setting)
71{
72 if(backlight_setting == ALWAS_OFF)
73 rb->backlight_set_timeout(0);
74 else if(backlight_setting == ROCKBOX_SETTING)
75 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
76 else if(backlight_setting == ALWAYS_ON)
77 rb->backlight_set_timeout(1);
78}
79
80void clock_settings_skin_next(struct clock_settings* settings){
81 settings->skin[settings->mode]++;
82 if(settings->skin[settings->mode]>=max_skin[settings->mode])
83 settings->skin[settings->mode]=0;
84}
85
86void clock_settings_skin_previous(struct clock_settings* settings){
87 settings->skin[settings->mode]--;
88 if(settings->skin[settings->mode]<0)
89 settings->skin[settings->mode]=max_skin[settings->mode]-1;
90}
91
92enum settings_file_status clock_settings_load(struct clock_settings* settings,
93 char* filename){
94 int fd = rb->open(filename, O_RDONLY);
95 if(fd >= 0){ /* does file exist? */
96 /* basic consistency check */
97 if(rb->filesize(fd) == sizeof(*settings)){
98 rb->read(fd, settings, sizeof(*settings));
99 rb->close(fd);
100 apply_backlight_setting(settings->general.backlight);
101 return(LOADED);
102 }
103 }
104 /* Initializes the settings with default values at least */
105 clock_settings_reset(settings);
106 return(ERRLOAD);
107}
108
109enum settings_file_status clock_settings_save(struct clock_settings* settings,
110 char* filename){
111 int fd = rb->creat(filename);
112 if(fd >= 0){ /* does file exist? */
113 rb->write (fd, settings, sizeof(*settings));
114 rb->close(fd);
115 return(SAVED);
116 }
117 return(ERRSAVE);
118}
119
120void draw_logo(struct screen* display){
121#ifdef HAVE_LCD_COLOR
122 if(display->is_color){
123 display->set_foreground(LCD_BLACK);
124 display->set_background(LCD_RGBPACK(180,200,230));
125 }
126#endif
127
128 const struct picture* logo = &(logos[display->screen_type]);
129 display->clear_display();
130 picture_draw(display, logo, 0, 0);
131}
132
133void draw_message(struct screen* display, int msg, int y){
134 const struct picture* message = &(messages[display->screen_type]);
135 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
136 display->fillrect(0, display->height-message->height,
137 display->width, message->height);
138 display->set_drawmode(DRMODE_SOLID);
139 vertical_picture_draw_sprite(display, message, msg,
140 0, display->height-(message->height*y));
141}
142
143void load_settings(void){
144 int i;
145 struct screen* display;
146 FOR_NB_SCREENS(i){
147 display=rb->screens[i];
148 display->clear_display();
149 draw_logo(display);
150 draw_message(display, MESSAGE_LOADING, 1);
151 display->update();
152 }
153
154 enum settings_file_status load_status=
155 clock_settings_load(&clock_settings, settings_filename);
156
157 FOR_NB_SCREENS(i){
158 display=rb->screens[i];
159 if(load_status==LOADED)
160 draw_message(display, MESSAGE_LOADED, 1);
161 else
162 draw_message(display, MESSAGE_ERRLOAD, 1);
163 display->update();
164 }
165#ifndef SIMULATOR
166 rb->ata_sleep();
167#endif
168 rb->sleep(HZ);
169}
170
171void save_settings(void){
172 int i;
173 struct screen* display;
174 FOR_NB_SCREENS(i){
175 display=rb->screens[i];
176 display->clear_display();
177 draw_logo(display);
178
179 draw_message(display, MESSAGE_SAVING, 1);
180
181 display->update();
182 }
183 enum settings_file_status load_status=
184 clock_settings_save(&clock_settings, settings_filename);
185
186 FOR_NB_SCREENS(i){
187 display=rb->screens[i];
188
189 if(load_status==SAVED)
190 draw_message(display, MESSAGE_SAVED, 1);
191 else
192 draw_message(display, MESSAGE_ERRSAVE, 1);
193 display->update();
194 }
195 rb->sleep(HZ);
196}
197
198void save_settings_wo_gui(void){
199 clock_settings_save(&clock_settings, settings_filename);
200}
diff --git a/apps/plugins/clock/clock_settings.h b/apps/plugins/clock/clock_settings.h
new file mode 100644
index 0000000000..fadf3d5e63
--- /dev/null
+++ b/apps/plugins/clock/clock_settings.h
@@ -0,0 +1,91 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare based on Zakk Roberts's work
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _CLOCK_SETTINGS_
21#define _CLOCK_SETTINGS_
22#include "plugin.h"
23
24enum date_format{
25 NONE,
26 ENGLISH,
27 EUROPEAN,
28 JAPANESE,
29};
30
31enum hour_format{
32 H24,
33 H12
34};
35
36enum clock_modes{
37 ANALOG,
38 DIGITAL,
39 BINARY,
40 NB_CLOCK_MODES
41};
42
43enum backlight_handling{
44 ALWAS_OFF,
45 ROCKBOX_SETTING,
46 ALWAYS_ON
47};
48
49
50struct general_settings{
51 int hour_format;/* 0:24h, 1:12h*/
52 int date_format;
53 bool show_counter;
54 bool save_settings;
55 bool idle_poweroff;
56 int backlight;
57};
58
59struct analog_settings{
60 bool show_date;
61 bool show_seconds;
62 bool show_border;
63};
64
65struct digital_settings{
66 int show_seconds;
67 int blinkcolon;
68};
69
70struct clock_settings{
71 int mode; /* clock mode */
72 int skin[NB_CLOCK_MODES];/* how does each mode looks like */
73 struct general_settings general;
74 struct analog_settings analog;
75 struct digital_settings digital;
76};
77
78extern struct clock_settings clock_settings;
79
80/* settings are saved to this location */
81#define settings_filename "/.rockbox/rocks/.clock_settings"
82
83void clock_settings_skin_next(struct clock_settings* settings);
84void clock_settings_skin_previous(struct clock_settings* settings);
85void apply_backlight_setting(int backlight_setting);
86void clock_settings_reset(struct clock_settings* settings);
87void load_settings(void);
88void save_settings(void);
89void save_settings_wo_gui(void);
90
91#endif /* _CLOCK_SETTINGS_ */
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 03a990acda..88d362a670 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -21,6 +21,7 @@ profile_plugin.c
21#endif 21#endif
22#ifdef HAVE_LCD_BITMAP 22#ifdef HAVE_LCD_BITMAP
23checkbox.c 23checkbox.c
24picture.c
24xlcd_core.c 25xlcd_core.c
25xlcd_draw.c 26xlcd_draw.c
26xlcd_scroll.c 27xlcd_scroll.c
diff --git a/apps/plugins/lib/picture.c b/apps/plugins/lib/picture.c
new file mode 100644
index 0000000000..f214dfcdfd
--- /dev/null
+++ b/apps/plugins/lib/picture.c
@@ -0,0 +1,70 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "picture.h"
21
22void picture_draw(struct screen* display, const struct picture* picture,
23 int x, int y){
24 display->bitmap(
25 picture->data,
26 x, y,
27 picture->width, picture->height
28 );
29}
30
31/**
32 * Draws a part of the given picture on the given screen
33 * Use it when the data contains multiple pictures from top to bottom.
34 * In that case, picture.height represents the height of one picture,
35 * not the whole set.
36 * @param display the screen where to display the picture
37 * @param picture the picture's data, only a part will be displayed
38 * @param yoffset display the data in the picture from yoffset to
39 * yoffset+picture.height
40 * @param x abscissa where to put the picture
41 * @param y ordinate where to put the picture
42 */
43void vertical_picture_draw_part(struct screen* display, const struct picture* picture,
44 int yoffset,
45 int x, int y){
46 display->bitmap_part(
47 picture->data,
48 /*slice into picture->data */
49 0, yoffset,
50 picture->width,
51 /* Position on the screen */
52 x, y, picture->width, picture->height
53 );
54}
55
56/**
57 * Draws a part of the given picture on the given screen
58 * Use it when the data contains multiple pictures from top to bottom.
59 *
60 * @param display the screen where to display the picture
61 * @param picture the picture's data, only a part will be displayed
62 * @param sprite_no display that sprite in the picture
63 * @param x abscissa where to put the picture
64 * @param y ordinate where to put the picture
65 */
66void vertical_picture_draw_sprite(struct screen* display, const struct picture* picture,
67 int sprite_no,
68 int x, int y){
69 vertical_picture_draw_part(display, picture, sprite_no*picture->height, x, y);
70}
diff --git a/apps/plugins/lib/picture.h b/apps/plugins/lib/picture.h
new file mode 100644
index 0000000000..4bd550a2f3
--- /dev/null
+++ b/apps/plugins/lib/picture.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
9 *
10 * Copyright (C) 2007 Copyright Kévin Ferrare
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _PICTURE_
21#define _PICTURE_
22#include "plugin.h"
23
24struct picture{
25 const void* data;
26 int width;
27 int height;
28};
29
30void picture_draw(struct screen* display, const struct picture* picture,
31 int x, int y);
32
33void vertical_picture_draw_part(struct screen* display, const struct picture* picture,
34 int yoffset,
35 int x, int y);
36
37void vertical_picture_draw_sprite(struct screen* display, const struct picture* picture,
38 int sprite_no,
39 int x, int y);
40#endif
diff --git a/apps/plugins/lib/xlcd.h b/apps/plugins/lib/xlcd.h
index 473c51c732..59a048228b 100644
--- a/apps/plugins/lib/xlcd.h
+++ b/apps/plugins/lib/xlcd.h
@@ -28,7 +28,8 @@
28 28
29void xlcd_init(struct plugin_api* newrb); 29void xlcd_init(struct plugin_api* newrb);
30void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3); 30void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3);
31 31void xlcd_filltriangle_screen(struct screen* display,
32 int x1, int y1, int x2, int y2, int x3, int y3);
32#if LCD_DEPTH >= 8 33#if LCD_DEPTH >= 8
33void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, 34void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
34 int stride, int x, int y, int width, int height); 35 int stride, int x, int y, int width, int height);
diff --git a/apps/plugins/lib/xlcd_draw.c b/apps/plugins/lib/xlcd_draw.c
index 3ccdea9139..accf3b4f4b 100644
--- a/apps/plugins/lib/xlcd_draw.c
+++ b/apps/plugins/lib/xlcd_draw.c
@@ -25,46 +25,58 @@
25#ifdef HAVE_LCD_BITMAP 25#ifdef HAVE_LCD_BITMAP
26#include "xlcd.h" 26#include "xlcd.h"
27 27
28#if (LCD_DEPTH >= 8) || (LCD_PIXELFORMAT == HORIZONTAL_PACKING) 28/* sort the given coordinates by increasing x value */
29/* draw a filled triangle, using horizontal lines for speed */ 29void sort_points_by_increasing_x(int* x1, int* y1,
30void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) 30 int* x2, int* y2,
31 int* x3, int* y3)
31{ 32{
32 int x, y; 33 int x, y;
33 long fp_x1, fp_x2, fp_dx1, fp_dx2; 34 if (*x1 > *x3)
34
35 /* sort vertices by increasing y value */
36 if (y1 > y3)
37 { 35 {
38 if (y2 < y3) /* y2 < y3 < y1 */ 36 if (*x2 < *x3) /* x2 < x3 < x1 */
39 { 37 {
40 x = x1; x1 = x2; x2 = x3; x3 = x; 38 x = *x1; *x1 = *x2; *x2 = *x3; *x3 = x;
41 y = y1; y1 = y2; y2 = y3; y3 = y; 39 y = *y1; *y1 = *y2; *y2 = *y3; *y3 = y;
42 } 40 }
43 else if (y2 > y1) /* y3 < y1 < y2 */ 41 else if (*x2 > *x1) /* x3 < x1 < x2 */
44 { 42 {
45 x = x1; x1 = x3; x3 = x2; x2 = x; 43 x = *x1; *x1 = *x3; *x3 = *x2; *x2 = x;
46 y = y1; y1 = y3; y3 = y2; y2 = y; 44 y = *y1; *y1 = *y3; *y3 = *y2; *y2 = y;
47 } 45 }
48 else /* y3 <= y2 <= y1 */ 46 else /* x3 <= x2 <= x1 */
49 { 47 {
50 x = x1; x1 = x3; x3 = x; 48 x = *x1; *x1 = *x3; *x3 = x;
51 y = y1; y1 = y3; y3 = y; 49 y = *y1; *y1 = *y3; *y3 = y;
52 } 50 }
53 } 51 }
54 else 52 else
55 { 53 {
56 if (y2 < y1) /* y2 < y1 <= y3 */ 54 if (*x2 < *x1) /* x2 < x1 <= x3 */
57 { 55 {
58 x = x1; x1 = x2; x2 = x; 56 x = *x1; *x1 = *x2; *x2 = x;
59 y = y1; y1 = y2; y2 = y; 57 y = *y1; *y1 = *y2; *y2 = y;
60 } 58 }
61 else if (y2 > y3) /* y1 <= y3 < y2 */ 59 else if (*x2 > *x3) /* x1 <= x3 < x2 */
62 { 60 {
63 x = x2; x2 = x3; x3 = x; 61 x = *x2; *x2 = *x3; *x3 = x;
64 y = y2; y2 = y3; y3 = y; 62 y = *y2; *y2 = *y3; *y3 = y;
65 } 63 }
66 /* else already sorted */ 64 /* else already sorted */
67 } 65 }
66}
67
68#define sort_points_by_increasing_y(x1, y1, x2, y2, x3, y3) \
69 sort_points_by_increasing_x(y1, x1, y2, x2, y3, x3)
70
71/* draw a filled triangle, using horizontal lines for speed */
72void xlcd_filltriangle_horizontal(struct screen* display,
73 int x1, int y1,
74 int x2, int y2,
75 int x3, int y3)
76{
77 long fp_x1, fp_x2, fp_dx1, fp_dx2;
78 int y;
79 sort_points_by_increasing_y(&x1, &y1, &x2, &y2, &x3, &y3);
68 80
69 if (y1 < y3) /* draw */ 81 if (y1 < y3) /* draw */
70 { 82 {
@@ -72,12 +84,12 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
72 fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1); 84 fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1);
73 85
74 if (y1 < y2) /* first part */ 86 if (y1 < y2) /* first part */
75 { 87 {
76 fp_dx2 = ((x2 - x1) << 16) / (y2 - y1); 88 fp_dx2 = ((x2 - x1) << 16) / (y2 - y1);
77 fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1); 89 fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1);
78 for (y = y1; y < y2; y++) 90 for (y = y1; y < y2; y++)
79 { 91 {
80 _xlcd_rb->lcd_hline(fp_x1 >> 16, fp_x2 >> 16, y); 92 display->hline(fp_x1 >> 16, fp_x2 >> 16, y);
81 fp_x1 += fp_dx1; 93 fp_x1 += fp_dx1;
82 fp_x2 += fp_dx2; 94 fp_x2 += fp_dx2;
83 } 95 }
@@ -88,53 +100,23 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
88 fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1); 100 fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1);
89 for (y = y2; y < y3; y++) 101 for (y = y2; y < y3; y++)
90 { 102 {
91 _xlcd_rb->lcd_hline(fp_x1 >> 16, fp_x2 >> 16, y); 103 display->hline(fp_x1 >> 16, fp_x2 >> 16, y);
92 fp_x1 += fp_dx1; 104 fp_x1 += fp_dx1;
93 fp_x2 += fp_dx2; 105 fp_x2 += fp_dx2;
94 } 106 }
95 } 107 }
96 } 108 }
97} 109}
98#else /* (LCD_DEPTH < 8) && (LCD_PIXELFORMAT == VERTICAL_PACKING) */ 110
99/* draw a filled triangle, using vertical lines for speed */ 111/* draw a filled triangle, using vertical lines for speed */
100void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) 112void xlcd_filltriangle_vertical(struct screen* display,
113 int x1, int y1,
114 int x2, int y2,
115 int x3, int y3)
101{ 116{
102 int x, y;
103 long fp_y1, fp_y2, fp_dy1, fp_dy2; 117 long fp_y1, fp_y2, fp_dy1, fp_dy2;
104 118 int x;
105 /* sort vertices by increasing x value */ 119 sort_points_by_increasing_x(&x1, &y1, &x2, &y2, &x3, &y3);
106 if (x1 > x3)
107 {
108 if (x2 < x3) /* x2 < x3 < x1 */
109 {
110 x = x1; x1 = x2; x2 = x3; x3 = x;
111 y = y1; y1 = y2; y2 = y3; y3 = y;
112 }
113 else if (x2 > x1) /* x3 < x1 < x2 */
114 {
115 x = x1; x1 = x3; x3 = x2; x2 = x;
116 y = y1; y1 = y3; y3 = y2; y2 = y;
117 }
118 else /* x3 <= x2 <= x1 */
119 {
120 x = x1; x1 = x3; x3 = x;
121 y = y1; y1 = y3; y3 = y;
122 }
123 }
124 else
125 {
126 if (x2 < x1) /* x2 < x1 <= x3 */
127 {
128 x = x1; x1 = x2; x2 = x;
129 y = y1; y1 = y2; y2 = y;
130 }
131 else if (x2 > x3) /* x1 <= x3 < x2 */
132 {
133 x = x2; x2 = x3; x3 = x;
134 y = y2; y2 = y3; y3 = y;
135 }
136 /* else already sorted */
137 }
138 120
139 if (x1 < x3) /* draw */ 121 if (x1 < x3) /* draw */
140 { 122 {
@@ -142,12 +124,12 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
142 fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1); 124 fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1);
143 125
144 if (x1 < x2) /* first part */ 126 if (x1 < x2) /* first part */
145 { 127 {
146 fp_dy2 = ((y2 - y1) << 16) / (x2 - x1); 128 fp_dy2 = ((y2 - y1) << 16) / (x2 - x1);
147 fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1); 129 fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1);
148 for (x = x1; x < x2; x++) 130 for (x = x1; x < x2; x++)
149 { 131 {
150 _xlcd_rb->lcd_vline(x, fp_y1 >> 16, fp_y2 >> 16); 132 display->vline(x, fp_y1 >> 16, fp_y2 >> 16);
151 fp_y1 += fp_dy1; 133 fp_y1 += fp_dy1;
152 fp_y2 += fp_dy2; 134 fp_y2 += fp_dy2;
153 } 135 }
@@ -158,14 +140,33 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
158 fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1); 140 fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1);
159 for (x = x2; x < x3; x++) 141 for (x = x2; x < x3; x++)
160 { 142 {
161 _xlcd_rb->lcd_vline(x, fp_y1 >> 16, fp_y2 >> 16); 143 display->vline(x, fp_y1 >> 16, fp_y2 >> 16);
162 fp_y1 += fp_dy1; 144 fp_y1 += fp_dy1;
163 fp_y2 += fp_dy2; 145 fp_y2 += fp_dy2;
164 } 146 }
165 } 147 }
166 } 148 }
167} 149}
168#endif /* LCD_DEPTH, LCD_PIXELFORMAT */ 150
151void xlcd_filltriangle(int x1, int y1,
152 int x2, int y2,
153 int x3, int y3)
154{
155 /* default is main screen */
156 xlcd_filltriangle_screen(_xlcd_rb->screens[SCREEN_MAIN],
157 x1, y1, x2, y2, x3, y3);
158}
159
160void xlcd_filltriangle_screen(struct screen* display,
161 int x1, int y1,
162 int x2, int y2,
163 int x3, int y3)
164{
165 if(display->pixel_format==HORIZONTAL_PACKING || display->depth>=8)
166 xlcd_filltriangle_horizontal(display, x1, y1, x2, y2, x3, y3);
167 else
168 xlcd_filltriangle_vertical(display, x1, y1, x2, y2, x3, y3);
169}
169 170
170#if LCD_DEPTH >= 8 171#if LCD_DEPTH >= 8
171 172
diff --git a/apps/screen_access.c b/apps/screen_access.c
index 2d2013ec2a..b5731cf33a 100644
--- a/apps/screen_access.c
+++ b/apps/screen_access.c
@@ -39,6 +39,7 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
39#ifdef HAVE_REMOTE_LCD 39#ifdef HAVE_REMOTE_LCD
40 case SCREEN_REMOTE: 40 case SCREEN_REMOTE:
41 screen->is_color=false;/* No color remotes yet */ 41 screen->is_color=false;/* No color remotes yet */
42 screen->pixel_format=LCD_REMOTE_PIXELFORMAT;
42 screen->depth=LCD_REMOTE_DEPTH; 43 screen->depth=LCD_REMOTE_DEPTH;
43 screen->has_disk_led=false; 44 screen->has_disk_led=false;
44 45
@@ -118,6 +119,9 @@ void screen_init(struct screen * screen, enum screen_type screen_type)
118#else 119#else
119 screen->is_color=false; 120 screen->is_color=false;
120#endif 121#endif
122#ifdef HAVE_LCD_BITMAP
123 screen->pixel_format=LCD_PIXELFORMAT;
124#endif
121 screen->depth=LCD_DEPTH; 125 screen->depth=LCD_DEPTH;
122#if (CONFIG_LED == LED_VIRTUAL) 126#if (CONFIG_LED == LED_VIRTUAL)
123 screen->has_disk_led=false; 127 screen->has_disk_led=false;
diff --git a/apps/screen_access.h b/apps/screen_access.h
index 967bd55c02..822aab4a88 100644
--- a/apps/screen_access.h
+++ b/apps/screen_access.h
@@ -58,6 +58,9 @@ struct screen
58 enum screen_type screen_type; 58 enum screen_type screen_type;
59 int depth; 59 int depth;
60 bool is_color; 60 bool is_color;
61#ifdef HAVE_LCD_BITMAP
62 int pixel_format;
63#endif
61 int char_width; 64 int char_width;
62 int char_height; 65 int char_height;
63#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) 66#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)