diff options
Diffstat (limited to 'apps/plugins/clock/clock_draw_analog.c')
-rw-r--r-- | apps/plugins/clock/clock_draw_analog.c | 217 |
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 | |||
37 | void 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 | |||
42 | void 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 | |||
49 | void 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 | |||
74 | void 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 | |||
82 | void 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 | |||
104 | void 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 | ******************/ | ||
119 | void 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 | } | ||