summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorKevin Ferrare <kevin@rockbox.org>2007-08-04 03:01:46 +0000
committerKevin Ferrare <kevin@rockbox.org>2007-08-04 03:01:46 +0000
commit93b2f9fd447b73fff736d71826880ef9ac64bd94 (patch)
tree1a4f54016c312738d66fb9dd2348ea0ef14f1255 /apps/plugins
parentffbbc60f38ddc8aeadc9cea1102077e22ca84a1a (diff)
downloadrockbox-93b2f9fd447b73fff736d71826880ef9ac64bd94.tar.gz
rockbox-93b2f9fd447b73fff736d71826880ef9ac64bd94.zip
Rewrote the clock plugin in a cleaner and more modular way so that it can scale on remote screens. Use left-right keys to change the type of clock displayed (analogic, digital, binary) and up/downto change the look of the clock
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14174 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-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
53 files changed, 1958 insertions, 1742 deletions
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