1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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"
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;
44 *x
= (sin_int(a
) * r
) >> 14;
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
);
54 *y
+=display
->height
/2;
57 void angle_to_square(int square_width
, int square_height
,
58 int a
, int* x
, int* y
)
61 if(a
>45 && a
<=135){/* top line */
63 *x
=square_width
-(square_width
*2*a
)/90;
65 }else if(a
>135 && a
<=225){/* left line */
68 *y
=square_height
-(square_height
*2*a
)/90;
69 }else if(a
>225 && a
<=315){/* bottom line */
71 *x
=(square_width
*2*a
)/90-square_width
;
73 }else if(a
>315 || a
<=45){/* right line */
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
);
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
)
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
)
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
)
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
);
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
);
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 */
182 int size
=display
->height
/50;/* size of the square dots */
183 if(size
%2)/* a pair number */
185 for(i
=0; i
< 60; i
+=5){
187 polar_to_cartesian_screen_centered(display
, MINUTE_ANGLE(i
, 0),
188 ANALOG_MINUTE_RADIUS(display
, skin
), &x
, &y
);
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
)
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
);
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
,
245 draw_hour(display
, time
, settings
->analog
.show_seconds
, skin
);
246 if(settings
->analog
.show_border
)
247 draw_border(display
, skin
);
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
);