diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES index 4951f0db9c..f1e18832bc 100644 --- a/apps/plugins/CATEGORIES +++ b/apps/plugins/CATEGORIES @@ -1,4 +1,5 @@ alpine_cdc,apps +alarmclock,apps autostart,apps battery_bench,apps bench_scaler,apps diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index da906e6967..88ddff5e29 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES @@ -107,6 +107,7 @@ vu_meter.c wormlet.c #if CONFIG_RTC +alarmclock.c #endif /* CONFIG_RTC */ #if (MEMORYSIZE <= 8) && !defined(SIMULATOR) /* loaders, only needed for Archos */ diff --git a/apps/plugins/alarmclock.c b/apps/plugins/alarmclock.c new file mode 100644 index 0000000000..c8653dcd64 --- /dev/null +++ b/apps/plugins/alarmclock.c @@ -0,0 +1,164 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Clément Pit-Claudel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "plugin.h" +#include "lib/pluginlib_actions.h" + +PLUGIN_HEADER + +const struct button_mapping *plugin_contexts[] = {generic_directions, + generic_actions}; + +static int current = 0; +static int alarm[2] = {0, 0}, maxval[2] = {24, 60}; +static bool quit = false, usb = false, waiting = false, done = false; + +static inline int get_button(void) { + return pluginlib_getaction(HZ/2, plugin_contexts, 2); +} + +int rem_seconds(void) { + return (((alarm[0] - rb->get_time()->tm_hour) * 3600) + +((alarm[1] - rb->get_time()->tm_min) * 60) + -(rb->get_time()->tm_sec)); +} + +void draw(void) { + char info[128]; + rb->lcd_clear_display(); + + int secs = rem_seconds(); + + if (waiting) + rb->snprintf(info, sizeof(info), "Next alarm in %02dh," + " %02dmn, and %02ds.", + secs / 3600, (secs / 60) % 60, secs % 60); + else { + if (current == 0) + rb->snprintf(info, sizeof(info), "Set alarm at [%02d]:%02d.", + alarm[0], + alarm[1]); + else + rb->snprintf(info, sizeof(info), "Set alarm at %02d:[%02d].", + alarm[0], + alarm[1]); + } + + int w, h; + rb->lcd_getstringsize(info, &w, &h); + + if (w > LCD_WIDTH || h > LCD_HEIGHT) + rb->splash(0, info); + else { + rb->lcd_putsxy((LCD_WIDTH - w) / 2, (LCD_HEIGHT - h) / 2, info); + rb->lcd_update(); + } +} + +bool can_play(void) { + int audio_status = rb->audio_status(); + if ((!audio_status && rb->global_status->resume_index != -1) + && (rb->playlist_resume() != -1)) { + return true; + } + else if (audio_status & AUDIO_STATUS_PAUSE) + return true; + + return false; +} + +void play(void) { + int audio_status = rb->audio_status(); + if (!audio_status && rb->global_status->resume_index != -1) { + if (rb->playlist_resume() != -1) { + rb->playlist_start(rb->global_status->resume_index, + rb->global_status->resume_offset); + } + } + else if (audio_status & AUDIO_STATUS_PAUSE) + rb->audio_resume(); +} + +enum plugin_status plugin_start(const void* parameter) +{ + int button; + (void)parameter; + + if (!can_play()) { + rb->splash(4*HZ, "No track to resume! This plugin will resume a track " + "at a specific time. Therefore, you need to first play" + " one, and then pause it and start the plugin again."); + quit = true; + } + + while(!quit) { + button = get_button(); + + if (button == PLA_QUIT) + quit = true; + + draw(); + if (waiting) { + if (rem_seconds() <= 0) { + quit = done = true; + play(); + } + } + else { + switch (button) { + case PLA_UP: + case PLA_UP_REPEAT: + alarm[current] = (alarm[current] + 1) % maxval[current]; + break; + + case PLA_DOWN: + case PLA_DOWN_REPEAT: + alarm[current] = (alarm[current] + maxval[current] - 1) + % maxval[current]; + break; + + case PLA_LEFT: + case PLA_LEFT_REPEAT: + case PLA_RIGHT: + case PLA_RIGHT_REPEAT: + current = (current + 1) % 2; + break; + + case PLA_FIRE: { + if (rem_seconds() < 0) + alarm[0] += 24; + + waiting = true; + break; + } + + default: + if (rb->default_event_handler(button) == SYS_USB_CONNECTED) + quit = usb = true; + break; + } + } + } + + return (usb) ? PLUGIN_USB_CONNECTED + : (done ? PLUGIN_GOTO_WPS : PLUGIN_OK); +} + diff --git a/manual/plugins/alarmclock.tex b/manual/plugins/alarmclock.tex new file mode 100644 index 0000000000..58d9b3a3db --- /dev/null +++ b/manual/plugins/alarmclock.tex @@ -0,0 +1,48 @@ +\subsection{Alarm Clock} + +This plugin is an alarm clock, which resumes a paused song at a given time. + +\subsubsection{Key configuration} +\begin{table} +\begin{btnmap}{}{} + \opt{RECORDER_PAD,IAUDIO_X5_PAD,IRIVER_H300_PAD,IPOD_4G_PAD,IPOD_3G_PAD% + ,GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD,SANSA_C200_PAD% + ,SANSA_E200_PAD,IRIVER_H10_PAD,SANSA_FUZE_PAD} + {\ButtonLeft{} / \ButtonRight} + \opt{COWON_D2_PAD}{\TouchMidRight{} / \TouchMidLeft} + \opt{HAVEREMOTEKEYMAP}{& } + & Switch between hours/minutes selection \\ + \opt{RECORDER_PAD,IRIVER_H300_PAD,IAUDIO_X5_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD% + ,MROBE100_PAD}{\ButtonUp{} / \ButtonDown} + \opt{IPOD_3G_PAD,IPOD_4G_PAD,SANSA_E200_PAD,SANSA_FUZE_PAD} + {\ButtonScrollFwd{} / \ButtonScrollBack} + \opt{SANSA_C200_PAD}{\ButtonVolUp{} / \ButtonVolDown} + \opt{IRIVER_H10_PAD}{\ButtonScrollUp{} / \ButtonScrollDown} + \opt{COWON_D2_PAD}{\ButtonMinus{} / \ButtonPlus} + \opt{HAVEREMOTEKEYMAP}{& } + & Increase/Decrease hours/minutes \\ + \opt{RECORDER_PAD}{\ButtonPlay} + \opt{IRIVER_H10_PAD}{\ButtonRew} + \opt{IRIVER_H300_PAD,IAUDIO_X5_PAD,IPOD_4G_PAD,IPOD_3G_PAD,SANSA_C200_PAD% + ,SANSA_E200_PAD,GIGABEAT_PAD,GIGABEAT_S_PAD,MROBE100_PAD% + ,SANSA_FUZE_PAD} + {\ButtonSelect} + \opt{COWON_D2_PAD}{\ButtonPlus{} or \TouchBottomMiddle} + \opt{HAVEREMOTEKEYMAP}{& } + & Set the alarm \\ + \opt{RECORDER_PAD,IRIVER_H300_PAD}{\ButtonOff} + \opt{IPOD_4G_PAD,IPOD_3G_PAD}{\ButtonMenu + \ButtonSelect} + \opt{IAUDIO_X5_PAD,IRIVER_H10_PAD,SANSA_E200_PAD,SANSA_C200_PAD,GIGABEAT_PAD% + ,MROBE100_PAD}{\ButtonPower} + \opt{SANSA_FUZE_PAD}{Long \ButtonHome} + \opt{GIGABEAT_S_PAD}{\ButtonBack} + \opt{COWON_D2_PAD}{\ButtonPower{} or \TouchBottomRight} + \opt{HAVEREMOTEKEYMAP}{& } + & Exit \\ +\end{btnmap} +\end{table} + +\subsubsection{Setting up an alarm} +First select a track, and play it. Then, pause it, and launch the ``alarmclock'' +plugin. Enter a 24h-time (eg. 13:58), and set the alarm. Music playback will +resume when reaching the selected time. diff --git a/manual/plugins/main.tex b/manual/plugins/main.tex index 6bce439c56..8d1057cfa9 100644 --- a/manual/plugins/main.tex +++ b/manual/plugins/main.tex @@ -200,6 +200,8 @@ option from the \setting{Context Menu} (see \reference{ref:Contextmenu}).} \section{Applications} +\opt{rtc}{\input{plugins/alarmclock.tex}} + \opt{archosplayer,archosrecorder,archosfmrecorder}{\input{plugins/alpinecdc.tex}} {\input{plugins/batterybenchmark.tex}}