Fix some quotation marks. Thanks to Alexander Levin for pointing it out.
[Rockbox.git] / apps / plugins / stopwatch.c
blobd4d890df0d73334fd7d5524e7e98c37522c5cd9f
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2004 Mike Holden
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 "plugin.h"
22 PLUGIN_HEADER
24 #ifdef HAVE_LCD_BITMAP
25 #define TIMER_Y 1
26 #else
27 #define TIMER_Y 0
28 #endif
30 #define LAP_Y TIMER_Y+1
31 #define MAX_LAPS 64
33 /* variable button definitions */
34 #if CONFIG_KEYPAD == RECORDER_PAD
35 #define STOPWATCH_QUIT BUTTON_OFF
36 #define STOPWATCH_START_STOP BUTTON_PLAY
37 #define STOPWATCH_RESET_TIMER BUTTON_LEFT
38 #define STOPWATCH_LAP_TIMER BUTTON_ON
39 #define STOPWATCH_SCROLL_UP BUTTON_UP
40 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
41 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
42 #define STOPWATCH_QUIT BUTTON_OFF
43 #define STOPWATCH_START_STOP BUTTON_SELECT
44 #define STOPWATCH_RESET_TIMER BUTTON_LEFT
45 #define STOPWATCH_LAP_TIMER BUTTON_ON
46 #define STOPWATCH_SCROLL_UP BUTTON_UP
47 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
48 #elif CONFIG_KEYPAD == ONDIO_PAD
49 #define STOPWATCH_QUIT BUTTON_OFF
50 #define STOPWATCH_START_STOP BUTTON_RIGHT
51 #define STOPWATCH_RESET_TIMER BUTTON_LEFT
52 #define STOPWATCH_LAP_TIMER BUTTON_MENU
53 #define STOPWATCH_SCROLL_UP BUTTON_UP
54 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
55 #elif CONFIG_KEYPAD == PLAYER_PAD
56 #define STOPWATCH_QUIT BUTTON_MENU
57 #define STOPWATCH_START_STOP BUTTON_PLAY
58 #define STOPWATCH_RESET_TIMER BUTTON_STOP
59 #define STOPWATCH_LAP_TIMER BUTTON_ON
60 #define STOPWATCH_SCROLL_UP BUTTON_RIGHT
61 #define STOPWATCH_SCROLL_DOWN BUTTON_LEFT
62 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
63 (CONFIG_KEYPAD == IRIVER_H300_PAD)
64 #define STOPWATCH_QUIT BUTTON_OFF
65 #define STOPWATCH_START_STOP BUTTON_SELECT
66 #define STOPWATCH_RESET_TIMER BUTTON_DOWN
67 #define STOPWATCH_LAP_TIMER BUTTON_ON
68 #define STOPWATCH_SCROLL_UP BUTTON_RIGHT
69 #define STOPWATCH_SCROLL_DOWN BUTTON_LEFT
71 #define STOPWATCH_RC_QUIT BUTTON_RC_STOP
73 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
74 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
75 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
76 #define STOPWATCH_QUIT BUTTON_MENU
77 #define STOPWATCH_START_STOP BUTTON_SELECT
78 #define STOPWATCH_RESET_TIMER BUTTON_LEFT
79 #define STOPWATCH_LAP_TIMER BUTTON_RIGHT
80 #define STOPWATCH_SCROLL_UP BUTTON_SCROLL_FWD
81 #define STOPWATCH_SCROLL_DOWN BUTTON_SCROLL_BACK
82 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
83 #define STOPWATCH_QUIT BUTTON_PLAY
84 #define STOPWATCH_START_STOP BUTTON_MODE
85 #define STOPWATCH_RESET_TIMER BUTTON_EQ
86 #define STOPWATCH_LAP_TIMER BUTTON_SELECT
87 #define STOPWATCH_SCROLL_UP BUTTON_UP
88 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
89 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
90 #define STOPWATCH_QUIT BUTTON_POWER
91 #define STOPWATCH_START_STOP BUTTON_PLAY
92 #define STOPWATCH_RESET_TIMER BUTTON_REC
93 #define STOPWATCH_LAP_TIMER BUTTON_SELECT
94 #define STOPWATCH_SCROLL_UP BUTTON_UP
95 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
96 #elif CONFIG_KEYPAD == GIGABEAT_PAD
97 #define STOPWATCH_QUIT BUTTON_POWER
98 #define STOPWATCH_START_STOP BUTTON_SELECT
99 #define STOPWATCH_RESET_TIMER BUTTON_A
100 #define STOPWATCH_LAP_TIMER BUTTON_MENU
101 #define STOPWATCH_SCROLL_UP BUTTON_UP
102 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
103 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
104 (CONFIG_KEYPAD == SANSA_C200_PAD)
105 #define STOPWATCH_QUIT BUTTON_POWER
106 #define STOPWATCH_START_STOP BUTTON_RIGHT
107 #define STOPWATCH_RESET_TIMER BUTTON_LEFT
108 #define STOPWATCH_LAP_TIMER BUTTON_SELECT
109 #define STOPWATCH_SCROLL_UP BUTTON_UP
110 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
111 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
112 #define STOPWATCH_QUIT BUTTON_POWER
113 #define STOPWATCH_START_STOP BUTTON_PLAY
114 #define STOPWATCH_RESET_TIMER BUTTON_REW
115 #define STOPWATCH_LAP_TIMER BUTTON_FF
116 #define STOPWATCH_SCROLL_UP BUTTON_SCROLL_UP
117 #define STOPWATCH_SCROLL_DOWN BUTTON_SCROLL_DOWN
118 #elif CONFIG_KEYPAD == MROBE500_PAD
119 #define STOPWATCH_QUIT BUTTON_POWER
120 #define STOPWATCH_START_STOP BUTTON_RC_HEART
121 #define STOPWATCH_RESET_TIMER BUTTON_RC_MODE
122 #define STOPWATCH_LAP_TIMER BUTTON_RC_PLAY
123 #define STOPWATCH_SCROLL_UP BUTTON_RIGHT
124 #define STOPWATCH_SCROLL_DOWN BUTTON_LEFT
125 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
126 #define STOPWATCH_QUIT BUTTON_BACK
127 #define STOPWATCH_START_STOP BUTTON_PLAY
128 #define STOPWATCH_RESET_TIMER BUTTON_MENU
129 #define STOPWATCH_LAP_TIMER BUTTON_SELECT
130 #define STOPWATCH_SCROLL_UP BUTTON_UP
131 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
132 #elif CONFIG_KEYPAD == MROBE100_PAD
133 #define STOPWATCH_QUIT BUTTON_POWER
134 #define STOPWATCH_START_STOP BUTTON_SELECT
135 #define STOPWATCH_RESET_TIMER BUTTON_DISPLAY
136 #define STOPWATCH_LAP_TIMER BUTTON_MENU
137 #define STOPWATCH_SCROLL_UP BUTTON_UP
138 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
139 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
140 #define STOPWATCH_QUIT BUTTON_RC_REC
141 #define STOPWATCH_START_STOP BUTTON_RC_PLAY
142 #define STOPWATCH_RESET_TIMER BUTTON_RC_REW
143 #define STOPWATCH_LAP_TIMER BUTTON_RC_FF
144 #define STOPWATCH_SCROLL_UP BUTTON_RC_VOL_UP
145 #define STOPWATCH_SCROLL_DOWN BUTTON_RC_VOL_DOWN
146 #define STOPWATCH_RC_QUIT BUTTON_REC
147 #elif CONFIG_KEYPAD == COWOND2_PAD
148 #define STOPWATCH_QUIT BUTTON_POWER
149 #define STOPWATCH_START_STOP BUTTON_SELECT
150 #define STOPWATCH_RESET_TIMER BUTTON_MENU
151 #define STOPWATCH_LAP_TIMER BUTTON_PLUS
152 #define STOPWATCH_SCROLL_UP BUTTON_UP
153 #define STOPWATCH_SCROLL_DOWN BUTTON_DOWN
154 #else
155 #error No keymap defined!
156 #endif
158 static struct plugin_api* rb;
160 static int stopwatch = 0;
161 static long start_at = 0;
162 static int prev_total = 0;
163 static bool counting = false;
164 static int curr_lap = 0;
165 static int lap_scroll = 0;
166 static int lap_start;
167 static int lap_times[MAX_LAPS];
169 static void ticks_to_string(int ticks,int lap,int buflen, char * buf)
171 int hours, minutes, seconds, cs;
173 hours = ticks / (HZ * 3600);
174 ticks -= (HZ * hours * 3600);
175 minutes = ticks / (HZ * 60);
176 ticks -= (HZ * minutes * 60);
177 seconds = ticks / HZ;
178 ticks -= (HZ * seconds);
179 cs = ticks;
180 if (!lap)
182 rb->snprintf(buf, buflen,
183 "%2d:%02d:%02d.%02d",
184 hours, minutes, seconds, cs);
186 else
189 if (lap > 1)
191 int last_ticks, last_hours, last_minutes, last_seconds, last_cs;
192 last_ticks = lap_times[(lap-1)%MAX_LAPS] - lap_times[(lap-2)%MAX_LAPS];
193 last_hours = last_ticks / (HZ * 3600);
194 last_ticks -= (HZ * last_hours * 3600);
195 last_minutes = last_ticks / (HZ * 60);
196 last_ticks -= (HZ * last_minutes * 60);
197 last_seconds = last_ticks / HZ;
198 last_ticks -= (HZ * last_seconds);
199 last_cs = last_ticks;
201 rb->snprintf(buf, buflen,
202 "%2d %2d:%02d:%02d.%02d [%2d:%02d:%02d.%02d]",
203 lap, hours, minutes, seconds, cs, last_hours,
204 last_minutes, last_seconds, last_cs);
206 else
208 rb->snprintf(buf, buflen,
209 "%2d %2d:%02d:%02d.%02d",
210 lap, hours, minutes, seconds, cs);
215 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
217 char buf[32];
218 int button;
219 int lap;
220 int done = false;
221 bool update_lap = true;
222 int lines;
224 (void)parameter;
225 rb = api;
227 #ifdef HAVE_LCD_BITMAP
228 int h;
229 rb->lcd_setfont(FONT_UI);
230 rb->lcd_getstringsize("M", NULL, &h);
231 lines = (LCD_HEIGHT / h) - (LAP_Y);
232 #else
233 lines = 1;
234 #endif
236 rb->lcd_clear_display();
238 while (!done)
240 if (counting)
242 stopwatch = prev_total + *rb->current_tick - start_at;
244 else
246 stopwatch = prev_total;
249 ticks_to_string(stopwatch,0,32,buf);
250 rb->lcd_puts(0, TIMER_Y, buf);
252 if(update_lap)
254 lap_start = curr_lap - lap_scroll;
255 for (lap = lap_start; lap > lap_start - lines; lap--)
257 if (lap > 0)
259 ticks_to_string(lap_times[(lap-1)%MAX_LAPS],lap,32,buf);
260 rb->lcd_puts_scroll(0, LAP_Y + lap_start - lap, buf);
262 else
264 rb->lcd_puts(0, LAP_Y + lap_start - lap,
265 " ");
268 update_lap = false;
271 rb->lcd_update();
273 if (! counting)
275 button = rb->button_get(true);
277 else
279 button = rb->button_get_w_tmo(10);
281 /* Make sure that the jukebox isn't powered off
282 automatically */
283 rb->reset_poweroff_timer();
285 switch (button)
288 /* exit */
289 #ifdef STOPWATCH_RC_QUIT
290 case STOPWATCH_RC_QUIT:
291 #endif
292 case STOPWATCH_QUIT:
293 done = true;
294 break;
296 /* Stop/Start toggle */
297 case STOPWATCH_START_STOP:
298 counting = ! counting;
299 if (counting)
301 start_at = *rb->current_tick;
302 stopwatch = prev_total + *rb->current_tick - start_at;
304 else
306 prev_total += *rb->current_tick - start_at;
307 stopwatch = prev_total;
309 break;
311 /* Reset timer */
312 case STOPWATCH_RESET_TIMER:
313 if (!counting)
315 prev_total = 0;
316 curr_lap = 0;
317 update_lap = true;
319 break;
321 /* Lap timer */
322 case STOPWATCH_LAP_TIMER:
323 lap_times[curr_lap%MAX_LAPS] = stopwatch;
324 curr_lap++;
325 update_lap = true;
326 break;
328 /* Scroll Lap timer up */
329 case STOPWATCH_SCROLL_UP:
330 if (lap_scroll > 0)
332 lap_scroll --;
333 update_lap = true;
335 break;
337 /* Scroll Lap timer down */
338 case STOPWATCH_SCROLL_DOWN:
339 if ((lap_scroll < curr_lap - lines) &&
340 (lap_scroll < (MAX_LAPS - lines)) )
342 lap_scroll ++;
343 update_lap = true;
345 break;
347 default:
348 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
349 return PLUGIN_USB_CONNECTED;
350 break;
353 return PLUGIN_OK;