Fix yellow
[Rockbox.git] / apps / plugins / clock / clock_draw_analog.c
blob0ab058e3fadffa2e628ce5382a7a24eb4c962d8b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: jackpot.c 14034 2007-07-28 05:42:55Z kevin $
10 * Copyright (C) 2007 Copyright Kévin Ferrare based on Zakk Roberts's work
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
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"
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 (2*ANALOG_MINUTE_RADIUS(screen, round)/3)
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))
37 /* Note that the given angle's origin is midday and not 3 o'clock */
38 void polar_to_cartesian(int a, int r, int* x, int* y)
40 #if CONFIG_LCD == LCD_SSD1815
41 /* Correct non-square pixel aspect of archos recorder LCD */
42 *x = (sin_int(a) * 5 / 4 * r) >> 14;
43 #else
44 *x = (sin_int(a) * r) >> 14;
45 #endif
46 *y = (sin_int(a-90) * r) >> 14;
49 void polar_to_cartesian_screen_centered(struct screen * display,
50 int a, int r, int* x, int* y)
52 polar_to_cartesian(a, r, x, y);
53 *x+=display->width/2;
54 *y+=display->height/2;
57 void angle_to_square(int square_width, int square_height,
58 int a, int* x, int* y)
60 a = (a+360-90)%360;
61 if(a>45 && a<=135){/* top line */
62 a-=45;
63 *x=square_width-(square_width*2*a)/90;
64 *y=square_height;
65 }else if(a>135 && a<=225){/* left line */
66 a-=135;
67 *x=-square_width;
68 *y=square_height-(square_height*2*a)/90;
69 }else if(a>225 && a<=315){/* bottom line */
70 a-=225;
71 *x=(square_width*2*a)/90-square_width;
72 *y=-square_height;
73 }else if(a>315 || a<=45){/* right line */
74 if(a>315)
75 a-=315;
76 else
77 a+=45;
78 *x=square_width;
79 *y=(square_height*2*a)/90-square_height;
83 void angle_to_square_screen_centered(struct screen * display,
84 int square_width, int square_height,
85 int a, int* x, int* y)
87 angle_to_square(square_width, square_height, a, x, y);
88 *x+=display->width/2;
89 *y+=display->height/2;
92 void draw_hand(struct screen* display, int angle,
93 int radius, int thickness, bool round)
95 int x1, y1; /* the longest */
96 int x2, y2, x3, y3; /* the base */
97 if(round){/* round clock */
98 polar_to_cartesian_screen_centered(display, angle, radius, &x1, &y1);
99 }else{/* fullscreen clock, hands describes square motions */
100 int square_width, square_height;
101 /* radius is defined smallest between width and height */
102 square_height=radius;
103 square_width=(radius*display->width)/display->height;
104 angle_to_square_screen_centered(
105 display, square_width, square_height, angle, &x1, &y1);
107 polar_to_cartesian_screen_centered(display, (angle+120)%360,
108 radius/40+thickness, &x2, &y2);
109 polar_to_cartesian_screen_centered(display, (angle+240)%360,
110 radius/40+thickness, &x3, &y3);
111 xlcd_filltriangle_screen(display, x1, y1, x2, y2, x3, y3);
112 rb->lcd_drawline(x1, y1, x2, y2);
113 rb->lcd_drawline(x1, y1, x3, y3);
116 void draw_hands(struct screen* display, int hour, int minute, int second,
117 int thickness, bool round, bool draw_seconds)
119 if(draw_seconds){
120 draw_hand(display, SECOND_ANGLE(second),
121 ANALOG_SECOND_RADIUS(display, round), thickness, round);
123 draw_hand(display, MINUTE_ANGLE(minute, second),
124 ANALOG_MINUTE_RADIUS(display, round), thickness+2, round);
125 draw_hand(display, HOUR_ANGLE(hour, minute, second),
126 ANALOG_HOUR_RADIUS(display, round), thickness+2, round);
129 void draw_counter(struct screen* display, struct counter* counter)
131 char buffer[10];
132 int second_str_w, hour_str_w, str_h;
133 const struct picture* smalldigits_bitmaps =
134 &(smalldigits[display->screen_type]);
135 struct time counter_time;
136 counter_get_elapsed_time(counter, &counter_time);
137 rb->snprintf(buffer, 10, "%02d:%02d",
138 counter_time.hour, counter_time.minute);
139 getstringsize(smalldigits_bitmaps, buffer, &hour_str_w, &str_h);
140 draw_string(display, smalldigits_bitmaps, buffer,
141 display->width-hour_str_w,
142 display->height-2*str_h);
144 rb->snprintf(buffer, 10, "%02d", counter_time.second);
145 getstringsize(smalldigits_bitmaps, buffer, &second_str_w, &str_h);
146 draw_string(display, smalldigits_bitmaps, buffer,
147 display->width-(hour_str_w+second_str_w)/2,
148 display->height-str_h);
151 void draw_date(struct screen* display, struct time* time, int date_format)
153 char buffer[10];
154 int year_str_w, monthday_str_w, str_h;
155 int year_line=date_format==JAPANESE?1:2;
156 int monthday_line=date_format==JAPANESE?2:1;
157 const struct picture* smalldigits_bitmaps =
158 &(smalldigits[display->screen_type]);
159 if(date_format==ENGLISH || date_format==JAPANESE){
160 rb->snprintf(buffer, 10, "%02d/%02d", time->month, time->day);
161 }else{
162 rb->snprintf(buffer, 10, "%02d/%02d", time->day, time->month);
164 /* draws month and day */
165 getstringsize(smalldigits_bitmaps, buffer, &monthday_str_w, &str_h);
166 draw_string(display, smalldigits_bitmaps, buffer,
167 0, display->height-year_line*str_h);
168 rb->snprintf(buffer, 10, "%04d", time->year);
170 /* draws year */
171 getstringsize(smalldigits_bitmaps, buffer, &year_str_w, &str_h);
172 draw_string(display, smalldigits_bitmaps, buffer,
173 (monthday_str_w-year_str_w)/2,
174 display->height-monthday_line*str_h);
177 void draw_border(struct screen* display, int skin)
179 /* Draws square dots every 5 minutes */
180 int i;
181 int x, y;
182 int size=display->height/50;/* size of the square dots */
183 if(size%2)/* a pair number */
184 size++;
185 for(i=0; i < 60; i+=5){
186 if(skin){
187 polar_to_cartesian_screen_centered(display, MINUTE_ANGLE(i, 0),
188 ANALOG_MINUTE_RADIUS(display, skin), &x, &y);
189 }else{
190 angle_to_square_screen_centered(
191 display, display->width/2-size/2, display->height/2-size/2,
192 MINUTE_ANGLE(i, 0), &x, &y);
194 display->fillrect(x-size/2, y-size/2, size, size);
198 void draw_hour(struct screen* display, struct time* time,
199 bool show_seconds, int skin)
201 int hour=time->hour;
202 if(hour >= 12)
203 hour -= 12;
205 /* Crappy fake antialiasing (color LCDs only)!
206 * how this works is we draw a large mid-gray hr/min/sec hand,
207 * then the actual (slightly smaller) hand on top of those.
208 * End result: mid-gray edges to the black hands, smooths them out. */
209 #ifdef HAVE_LCD_COLOR
210 if(display->is_color){
211 display->set_foreground(LCD_RGBPACK(100,110,125));
212 draw_hands(display, hour, time->minute, time->second,
213 1, skin, show_seconds);
214 display->set_foreground(LCD_BLACK);
216 #endif
217 draw_hands(display, hour, time->minute, time->second,
218 0, skin, show_seconds);
221 void draw_center_cover(struct screen* display)
223 display->drawline((display->width/2)-1, (display->height/2)+3,
224 (display->width/2)+1, (display->height/2)+3);
225 display->drawline((display->width/2)-3, (display->height/2)+2,
226 (display->width/2)+3, (display->height/2)+2);
227 display->drawline((display->width/2)-4, (display->height/2)+1,
228 (display->width/2)+4, (display->height/2)+1);
229 display->drawline((display->width/2)-4, display->height/2,
230 (display->width/2)+4, display->height/2);
231 display->drawline((display->width/2)-4, (display->height/2)-1,
232 (display->width/2)+4, (display->height/2)-1);
233 display->drawline((display->width/2)-3, (display->height/2)-2,
234 (display->width/2)+3, (display->height/2)-2);
235 display->drawline((display->width/2)-1, (display->height/2)-3,
236 (display->width/2)+1, (display->height/2)-3);
239 void analog_clock_draw(struct screen* display, struct time* time,
240 struct clock_settings* settings,
241 struct counter* counter,
242 int skin)
245 draw_hour(display, time, settings->analog.show_seconds, skin);
246 if(settings->analog.show_border)
247 draw_border(display, skin);
248 if(counter)
249 draw_counter(display, counter);
250 if(settings->analog.show_date && settings->general.date_format!=NONE)
251 draw_date(display, time, settings->general.date_format);
252 draw_center_cover(display);