summaryrefslogtreecommitdiff
path: root/apps/plugins/clock/clock_draw_analog.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/clock/clock_draw_analog.c')
-rw-r--r--apps/plugins/clock/clock_draw_analog.c217
1 files changed, 217 insertions, 0 deletions
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}