/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: alarm.c,v 1.2 2004/03/23 16:00:00 lwi Exp $ * * Copyright (C) 2004 Ivo Burkart * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "time.h" #ifdef HAVE_RTC static struct plugin_api* rb; static char default_filename[] = "/.rockbox/rocks/.alarm_settings"; bool status; int field; int c_hour; int c_minute; int c_second; int c_oldsec; int a_hour[4]; int a_minute[4]; int a_second[4]; void format_int(char *res, int var) { rb->snprintf(res, 3, "%02d", var); } void format_time(char *res, int hour, int minute, int second) { rb->snprintf( res, 9, "%02d:%02d:%02d", hour, minute, second); } bool equal_atime(int idx, int hour, int minute, int second) { return ((hour == a_hour[idx]) && (minute == a_minute[idx]) && (second == a_second[idx])); } int check_idx(void) { if (equal_atime(1, a_hour[0], a_minute[0], a_second[0])) {return 1;} if (equal_atime(2, a_hour[0], a_minute[0], a_second[0])) {return 2;} if (equal_atime(3, a_hour[0], a_minute[0], a_second[0])) {return 3;} return 0; } void draw_atime(int x, int y) { char timestr[3]; format_int(timestr, a_hour[0]); rb->lcd_puts_style(x,y,timestr,(int)(field == 0)); rb->lcd_puts(x+2,y,":"); format_int(timestr, a_minute[0]); rb->lcd_puts_style(x+3,y,timestr,(int)(field == 1)); rb->lcd_puts(x+5,y,":"); format_int(timestr, a_second[0]); rb->lcd_puts_style(x+6,y,timestr,(int)(field == 2)); rb->lcd_puts(x+8,y," "); } void draw_fbuttons(void) { rb->lcd_puts_style(0,7,"Alm1",(int)(check_idx() == 1)); rb->lcd_puts(4,7," "); rb->lcd_puts_style(7,7,"Alm2",(int)(check_idx() == 2)); rb->lcd_puts(11,7," "); rb->lcd_puts_style(14,7,"Alm3",(int)(check_idx() == 3)); } void draw(void) { rb->lcd_setfont(FONT_SYSFIXED); rb->lcd_clear_display(); char timestr[9]; rb->lcd_puts(0,0,"Rockbox Alarm"); rb->lcd_puts(0,2,"Status: "); if (status) {rb->lcd_puts(8,2,"Alarm");} else {rb->lcd_puts(8,2,"Waiting");} rb->lcd_puts(0,3,"Time : "); format_time(timestr, c_hour, c_minute, c_second); rb->lcd_puts(8,3,timestr); rb->lcd_puts(0,4,"Alarm : "); draw_atime(8,4); rb->lcd_puts(0,5,"Play: Snooze 5 Min"); rb->lcd_puts(0,6,"OFF : Quit Plugin"); draw_fbuttons(); rb->lcd_update(); } void update_ctime(void) { struct tm* c_time; c_time = rb->get_time(); c_hour = c_time->tm_hour; c_minute = c_time->tm_min; c_second = c_time->tm_sec; } int wrap_int(int *var, int min, int max) { /* return a_second / (max + 1); var = var % (max + 1); */ int temp = 0; while ((*var) < min) {(*var) += (max-min+1); temp--;} while ((*var) > max) {(*var) -= (max-min+1); temp++;} return temp; } void wrap_atime(void) { a_minute[0] += wrap_int(&(a_second[0]), 0, 59); a_hour[0] += wrap_int(&(a_minute[0]), 0, 59); wrap_int(&(a_hour[0]), 0, 23); } void check_alarm(void) { if ((!status) && equal_atime(0, c_hour, c_minute, c_second)) { status = true; rb->mp3_play_pause(true); } } void move_field(int dif) { field += dif; wrap_int(&field,0,2); draw(); } void change_field(int dif) { switch (field) { case 0: {a_hour[0] += dif; break;} case 1: {a_minute[0] += dif; break;} case 2: {a_second[0] += dif; break;} } wrap_atime(); draw(); status = false; rb->mp3_play_pause(false); check_idx(); } void copy_atime(int idx1, int idx2) { a_hour[idx2] = a_hour[idx1]; a_minute[idx2] = a_minute[idx1]; a_second[idx2] = a_second[idx1]; } void change_preset(int idx, bool set) { if (set) { copy_atime(0,idx); } else { copy_atime(idx,0); } draw(); } void atime_offset(int hours, int minutes, int seconds) { a_hour[0] = c_hour + hours; a_minute[0] = c_minute + minutes; a_second[0] = c_second + seconds; wrap_atime(); } void save_atime(void) { int fd; fd = rb->creat(default_filename, O_WRONLY); if(fd >= 0) { rb->write (fd, &a_hour, sizeof(int[4])); rb->write (fd, &a_minute, sizeof(int[4])); rb->write (fd, &a_second, sizeof(int[4])); rb->close(fd); } } bool load_atime(void) { int fd; fd = rb->open(default_filename, O_RDONLY); if(fd >= 0) { rb->read (fd, &a_hour, sizeof(int[4])); rb->read (fd, &a_minute, sizeof(int[4])); rb->read (fd, &a_second, sizeof(int[4])); rb->close(fd); return true; } return false; } void init(void) { status = false; field = 0; update_ctime(); if (!(load_atime())) { atime_offset(1,0,0); copy_atime(0,1); copy_atime(0,2); copy_atime(0,3); } draw(); rb->mp3_play_pause(false); } void deinit(void) { save_atime(); // rb->mp3_play_pause(false); } void main_loop(void) { bool exit = false; while (!exit) { update_ctime(); check_alarm(); if (c_second != c_oldsec) { draw(); c_oldsec = c_second; } switch (rb->button_get_w_tmo(HZ / 2)) { case BUTTON_UP | BUTTON_REPEAT: case BUTTON_UP: { change_field(1); break; } case BUTTON_DOWN | BUTTON_REPEAT: case BUTTON_DOWN: { change_field(-1); break; } case BUTTON_LEFT: { move_field(-1); break; } case BUTTON_RIGHT: { move_field(+1); break; } case BUTTON_PLAY: { if (status) { status=false; rb->mp3_play_pause(false); atime_offset(0,5,0); } break; } case BUTTON_F1 | BUTTON_PLAY: { change_preset(1,true); break; } case BUTTON_F1: { change_preset(1,false); break; } case BUTTON_F2 | BUTTON_PLAY: { change_preset(2,true); break; } case BUTTON_F2: { change_preset(2,false); break; } case BUTTON_F3 | BUTTON_PLAY: { change_preset(3,true); break; } case BUTTON_F3: { change_preset(3,false); break; } case BUTTON_OFF: { exit = true; break; } case SYS_USB_CONNECTED: { rb->usb_screen(); update_ctime(); draw(); break; } } } } enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { TEST_PLUGIN_API(api); (void)parameter; rb = api; if (!(rb->mp3_is_playing())) { rb->splash(HZ*2, true, "Play a Song"); return PLUGIN_ERROR; } init(); main_loop(); deinit(); return PLUGIN_OK; } #else enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { TEST_PLUGIN_API(api); (void)parameter; rb = api; rb->splash(HZ*2, true, "Sorry, you need a RTC."); return PLUGIN_ERROR; } #endif