From 9814089f6f45ef3225c101724d197502f175daad Mon Sep 17 00:00:00 2001 From: Hardeep Sidhu Date: Wed, 30 Jun 2004 02:42:11 +0000 Subject: Major clock update by Zakk Roberts (patch #932605) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4814 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/clock.c | 2715 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 2180 insertions(+), 535 deletions(-) (limited to 'apps/plugins/clock.c') diff --git a/apps/plugins/clock.c b/apps/plugins/clock.c index 1df0f709d4..3dae622c60 100644 --- a/apps/plugins/clock.c +++ b/apps/plugins/clock.c @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: clock.c,v 1.0 2003/12/8 + * $Id: clock.c,v 2.0 2003/12/8 * * Copyright (C) 2003 Zakk Roberts * @@ -16,77 +16,2057 @@ * KIND, either express or implied. * ****************************************************************************/ + +/******************************** +RELEASE NOTES ******************* +********************************* + +******************************** +VERSION 2.2 * STABLE *********** +******************************** +Few small bugs taken care of. +Release version. + +Features: +-New mode, "Binary" +-New mode selector - access via PLAY +-New feature, "Counter" - F2 to start/stop, Hold F2 to reset. +-New redesigned 9-page help screen. +-Small bugs fixed. + +********************************* +VERSION 2.1 * STABLE ************ +********************************* +Even more bugs fixed. Almost bug-free :) + +Features: +-Another new mode!! LCD imitation (similar to Digital) +-American/European date modes added +-lots of bugs fixed + +********************************* +VERSION 2.0: * BETA ************* +********************************* + +Major update. Code pretty much rewritten. Lots of bugs fixed. + +New Features: ******************* +-New mode, Fullscreen! +-Seperate settings for each mode +-Credits at F2 +-Options at F3 +-Startup / Shutdown logo (choose one by hitting ON) +-CLEANER code! + +Analog specific changes: ******** +-removed outer border option +-added 12/24h readout (and am/pm bitmaps for 12h mode) + +Digital specific changes: ******* +-now centers date and second readouts +-second readout options, "Digital" (text), "Bar" (progressbar), "Inverse" (inverts the display as the seconds go by) +-12/24h modes as well here (and of course the am/pm bitmaps) + +******************************** +VERSION 1.0 * "ALPHA" (STABLE) * +******************************** +Release Version. + +Features analog / digital modes, +and a few options. +********************************/ #include "plugin.h" #include "time.h" #ifdef HAVE_LCD_BITMAP -void draw_7seg_time(int hour, int minute, int x, int y, int width, int height, -bool colon); -void loadSettings(void); +/* prototypes */ +void show_logo(bool animate, bool show_clock_text); +void exit_logo(void); + +/* used in help screen */ +int screen = 1; + +/* counter misc */ +int start_tick = 0; +int passed_time = 0; +int counter = 0; +int displayed_value = 0; +int count_h, count_m, count_s; +char count_text[8]; +bool counting = false; static struct plugin_api* rb; -/* Used for hands to define lengths at a given time */ -static unsigned char yhour[] = { -47,47,46,46,46,45,44,43,42,41,39,38,36,35,33,32,31,29,28,26,25,23,22,21,20,19,18,18,18,17,17,17,18,18,18,19,20,21,22,23,25,26,28,29,31,32,33,35,36,38,39,41,42,43,44,45,46,46,46,47, +/*********************************************************** + * Used for hands to define lengths at a given time - ANALOG + ***********************************************************/ +static unsigned char xminute[] = { +56,59,61,64,67,70,72,75,77,79,80,82,83,84,84,84,84,84,83,82,80,79,77,75,72,70,67,64,61,59,56,53,51,48,45,42,40,37,35,33,32,30,29,28,28,28,28,28,29,30,32,33,35,37,40,42,45,48,51,53, }; static unsigned char yminute[] = { 55,54,54,53,53,51,50,49,47,45,43,41,39,36,34,32,30,28,25,23,21,19,17,15,14,13,11,11,10,10,9,10,10,11,11,13,14,15,17,19,21,23,25,28,30,32,34,36,39,41,43,45,47,49,50,51,53,53,54,54, }; +static unsigned char yhour[] = { +47,47,46,46,46,45,44,43,42,41,39,38,36,35,33,32,31,29,28,26,25,23,22,21,20,19,18,18,18,17,17,17,18,18,18,19,20,21,22,23,25,26,28,29,31,32,33,35,36,38,39,41,42,43,44,45,46,46,46,47, +}; static unsigned char xhour[] = { 56,58,59,61,63,65,67,68,70,71,72,73,74,74,75,75,75,74,74,73,72,71,70,68,67,65,63,61,59,58,56,54,53,51,49,47,45,44,42,41,40,39,38,38,37,37,37,38,38,39,40,41,42,44,45,47,49,51,53,54, }; -static unsigned char xminute[] = { -56,59,61,64,67,70,72,75,77,79,80,82,83,84,84,84,84,84,83,82,80,79,77,75,72,70,67,64,61,59,56,53,51,48,45,42,40,37,35,33,32,30,29,28,28,28,28,28,29,30,32,33,35,37,40,42,45,48,51,53, + +/************************************************************** + * Used for hands to define lengths at a give time - FULLSCREEN + **************************************************************/ +static unsigned char xminute_full[] = { +56,58,61,65,69,74,79,84,91,100,110,110,110,110,110,110,110,110,110,110,110,100,91,84,79,74,69,65,61,58,56,54,51,47,43,38,33,28,21,12,1,1,1,1,1,1,1,1,1,1,1,12,21,28,33,38,43,47,51,54 +}; +static unsigned char yminute_full[] = { +62,62,62,62,62,62,62,62,62,62,62,53,45,40,36,32,28,24,19,11,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,11,19,24,28,32,36,40,45,53,62,62,62,62,62,62,62,62,62,62 +}; +static unsigned char xhour_full[] = { +56,58,60,63,66,69,73,78,84,91,100,100,100,100,100,100,100,100,100,100,100,91,84,78,73,69,66,63,60,58,56,54,52,49,46,43,39,34,28,21,12,12,12,12,12,12,12,12,12,12,12,21,28,34,39,43,46,49,52,54 +}; +static unsigned char yhour_full[] = { +52,52,52,52,52,52,52,52,52,52,52,46,41,37,34,32,30,27,23,18,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,18,23,27,30,32,34,37,41,46,52,52,52,52,52,52,52,52,52,52 +}; + +/************************************ + * Used for second-progressbar + ************************************/ +static unsigned char seconds100[] = { +1,2,4,5,7,8,11,13,14,16,17,19,22,23,25,26,28,29,32,34,35,37,38,39,42,43,45,46,48,49,51,52,54,55,57,58,60,61,63,64,66,67,69,72,73,75,76,78,79,82,84,85,87,88,91,93,94,96,97,99 +}; + +/************************************ + * Used for seconds-inverse mode + ************************************/ +static unsigned char seconds112[] = { +1,2,4,6,8,10,12,14,16,18,20,21,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,91,92,94,96,98,100,102,104,106,108,110,111,112 +}; + +/**************************** + * BITMAPS + ****************************/ +/**************************** + * "0" bitmap - for binary + ****************************/ +static unsigned char bitmap_0[] = { +0xc0, 0xf0, 0x3c, 0x0e, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0e, 0x3c, 0xf0, +0xc0, 0x00, +0x1f, 0x7f, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x7f, +0x1f, 0x00, +0x00, 0x00, 0x01, 0x03, 0x03, 0x06, 0x06, 0x06, 0x06, 0x03, 0x03, 0x01, 0x00, +0x00, 0x00 }; +/**************************** + * "1" bitmap - for binary + ****************************/ +static unsigned char bitmap_1[] = { +0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x00 }; +/**************************** + * PM indicator (moon + text) + ****************************/ +static unsigned char pm[] = { 0xFF,0xFF,0x33,0x33,0x33,0x1E,0x0C,0x00,0xFF,0xFF,0x06,0x0C,0x06,0xFF,0xFF }; +/**************************** + * AM Indicator (sun and text + ****************************/ +static unsigned char am[] = { 0xFE,0xFF,0x1B,0x1B,0xFF,0xFE,0x00,0x00,0xFF,0xFF,0x06,0x0C,0x06,0xFF,0xFF }; + +/***************************************** + * We've got 4 different clock logos... + * The currently used one is #4, + * "clockbox" -- the others are kept here + * in case the logo selector is ever + * brought back or we want to switch.. + ****************************************/ +/* Logo #1 - Standard (by Zakk Roberts) */ +const unsigned char clocklogo_1[] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, +0xf8, 0xfc, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xe0, 0xc0, 0x00, +0x80, 0xe0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, +0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x3e, 0x3e, 0x3e, 0x1e, 0x0e, 0x00, 0x00, +0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf0, +0xf8, 0xfc, 0xfc, 0x7e, 0x3e, 0x3e, 0x3e, 0x3e, 0xbe, 0xbe, 0x3e, 0x3e, 0x3e, +0x3e, 0x7e, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x80, 0xe0, +0xf0, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, +0x7e, 0x7e, 0x7e, 0x7e, 0x3e, 0x3e, 0x3e, 0x1e, 0x0e, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, +0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x00, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x3f, 0xc0, 0xc0, 0xc0, +0xc0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xc7, 0x83, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, +0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, +0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, +0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, +0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, +0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, +0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1e, 0x1c, 0x00, 0x00, +0x00, 0x1f, 0x1f, 0x1f, 0x0f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x1f, +0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, +0x1f, 0x1f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, +0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, +0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1e, 0x1c, 0x00, 0x00, 0x00, 0x1f, +0x1f, 0x1f, 0x0f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x03, 0x07, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f +}; + +/* Logo #2 - Digital Segments (by Zakk Roberts) */ +const unsigned char clocklogo_2[] = { +0x00, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0xfb, 0xf7, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, +0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, +0xfe, 0xfc, 0xf8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0xfb, 0xf7, +0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xf7, 0xfb, +0xfd, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfd, 0xfb, 0xf7, 0x0f, 0x0f, 0x0f, 0x0f, +0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, +0x00, 0xfe, 0xfc, 0xf8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +0xe0, 0xf0, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xbf, 0x1f, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xbf, 0x1f, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x1f, 0x0f, 0x07, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0f, +0x1f, 0xbf, 0x00, 0x00, 0x00, 0xbf, 0x1f, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xbf, 0x5f, 0xef, 0xf7, 0xf0, 0xf0, 0xf0, 0xe0, 0x40, 0x00, 0x06, 0x07, +0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xff, 0xff, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xfc, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, +0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xff, 0xff, 0xfe, 0xfd, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x3c, +0xfc, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, +0xc0, 0x00, 0x40, 0x40, 0x4f, 0x17, 0x1b, 0xdd, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, +0x1e, 0x1e, 0x1e, 0xde, 0x1e, 0x5e, 0x5c, 0x58, 0x10, 0xc0, 0x00, 0x00, 0xc0, +0x0f, 0x57, 0x5b, 0x5d, 0x1e, 0x1e, 0x1e, 0x1e, 0xde, 0x1e, 0x1e, 0x1e, 0x9e, +0x1e, 0x1e, 0x1c, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd7, 0x1b, 0x5d, +0x5e, 0x5e, 0x1e, 0xde, 0x1e, 0x1e, 0xde, 0x1e, 0x5e, 0x5e, 0x5e, 0x1d, 0xdb, +0x17, 0x0f, 0xc0, 0x00, 0x40, 0x4f, 0x57, 0x1b, 0x1d, 0x1e, 0x1e, 0xde, 0x1e, +0x1e, 0x1e, 0x9e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1c, 0x18, 0x10, 0x00, 0x00, 0x00, +0x00, 0x0f, 0x07, 0x03, 0x01, 0x40, 0x40, 0x40, 0x00, 0xc0, 0x00, 0x00, 0x00, +0x00, 0xc1, 0x01, 0x41, 0x40, 0x40, 0x00, 0xc0, +0x1d, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x1d, 0x00, 0x10, 0x10, 0x10, 0x00, +0x00, 0x00, 0x00, 0x1d, 0x00, 0x10, 0x10, 0x10, 0x00, 0x1d, 0x00, 0x00, 0x1d, +0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x02, 0x00, 0x0d, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x02, +0x00, 0x02, 0x05, 0x18, 0x00, 0x00, 0x1d, 0x00, 0x10, 0x10, 0x10, 0x00, 0x1d, +0x00, 0x00, 0x1d, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, +0x02, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x1c, 0x00, 0x12, 0x10, 0x12, 0x00, 0x01, 0x00, 0x10, 0x10, +0x00, 0x1d, 0x00, 0x14, 0x10, 0x11, 0x00, 0x1d +}; + +/* Logo #3 - Electroplate (by Adam S. & Zakk Roberts) + * Definition: (N) any artifact that has been plated with a thin coat of metal by electrolysis */ +const unsigned char clocklogo_3[] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0xfc, +0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x5c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xf8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x1c, 0x3c, 0xfc, 0xfc, 0xfc, +0xfc, 0xf8, 0xe8, 0xb8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xb0, +0xf0, 0xd0, 0x70, 0x50, 0x70, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf8, 0xff, 0xff, 0xff, +0xf8, 0xf0, 0xf0, 0xf0, 0xa0, 0xe0, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0x70, 0xf0, +0xb0, 0xf0, 0x70, 0x70, 0x70, 0x60, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xaa, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, +0xe0, 0xe0, 0x60, 0xe0, 0x20, 0x00, 0x00, 0x00, +0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xfb, 0x0e, 0x01, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfe, +0xff, 0xff, 0xff, 0xff, 0xff, 0x6b, 0x0f, 0x02, 0x01, 0x00, 0xff, 0xff, 0xff, +0xe0, 0xe0, 0xe1, 0xe3, 0xef, 0xff, 0xff, 0xff, 0xfd, 0xf6, 0xf8, 0xe0, 0xe0, +0xc0, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xfd, 0x0f, 0x01, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xaa, 0xff, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0x5f, 0xf7, +0x3f, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x03, 0x1f, 0x3f, 0x7f, 0xff, 0xff, 0xfe, 0xfb, 0xee, 0xf8, 0xd0, +0xe0, 0xa0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, +0xff, 0xff, 0xff, 0xff, 0x7f, 0xd5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, +0x1f, 0x3f, 0x7f, 0xff, 0xff, 0xfd, 0xf6, 0xf8, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, +0xf1, 0xf1, 0xf1, 0xb9, 0xfd, 0x5f, 0x7f, 0x2f, 0x3f, 0x0b, 0x07, 0x01, 0x01, +0x00, 0x00, 0x03, 0x1f, 0x3f, 0x7f, 0xff, 0xff, 0xfe, 0xfb, 0xee, 0xf8, 0xd0, +0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, +0xff, 0x7f, 0xff, 0xaa, 0x7f, 0x03, 0x03, 0x0f, 0x3f, 0x7f, 0x7f, 0xff, 0xfd, +0xf6, 0xfc, 0xd8, 0xe0, 0x40, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* Logo #4 - "Clockbox" (by Adam S.) */ +const unsigned char clocklogo_4[] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, +0x78, 0x78, 0x3c, 0x3c, 0xfc, 0xfc, 0xfc, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, +0x1e, 0x3c, 0x3c, 0x3c, 0x7c, 0x7c, 0xf8, 0xf8, 0xf0, 0x30, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0x3f, 0x3f, 0x7f, 0x73, 0xf1, 0xe0, +0xe0, 0xc0, 0xc0, 0x80, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, +0xfe, 0xff, 0xff, 0x7f, 0x03, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, +0x80, 0xf0, 0xf8, 0xfc, 0xfe, 0x3e, 0x0e, 0x0f, 0x07, 0x07, 0x0f, 0x1f, 0xfe, +0xfe, 0xfc, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xf8, 0xfc, 0x7e, 0x1e, +0x0f, 0x0f, 0x07, 0x0f, 0x0f, 0x0f, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x00, 0xf0, +0xff, 0xff, 0xff, 0xff, 0xe1, 0xf0, 0xf8, 0x7c, 0x3e, 0x1f, 0x0f, 0x07, 0x03, +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x01, 0x0f, 0x1f, 0x3f, 0x3f, 0x3f, 0x3f, 0x0e, 0x00, 0x40, 0x7c, 0x7f, +0x7f, 0x7f, 0x77, 0x70, 0x70, 0x70, 0x70, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, +0x0f, 0x3f, 0x7f, 0x7f, 0xfd, 0xf0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf8, 0xff, 0xff, +0xdf, 0xcf, 0xc3, 0xc0, 0xc0, 0x80, 0x80, 0x1f, 0x3f, 0x7f, 0x7f, 0xf8, 0xf0, +0xf0, 0xf0, 0xf0, 0xf0, 0xf8, 0xf8, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0xff, +0x7f, 0x3f, 0x07, 0x03, 0x0f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf0, 0xc0, 0x00, 0x00, +0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x1f, 0x3f, 0x7f, 0xff, 0xff, 0xfc, 0xf0, 0xe0, 0xc0, 0x80, 0x80, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, +0xc0, 0xe0, 0xf0, 0xf0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfe, 0xff, 0xff, 0x7f, 0x73, +0x71, 0x71, 0xf9, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfc, +0xfe, 0xff, 0xff, 0x07, 0x03, 0x01, 0x01, 0x01, 0x01, 0xc3, 0xff, 0xff, 0xff, +0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xc7, 0xff, 0xff, 0xff, 0xfc, +0xfe, 0xdf, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, +0x07, 0x07, 0x0f, 0x0f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, +0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1f, 0x1f, 0x1f, 0x1f, 0x1c, 0x1c, +0x1c, 0x1e, 0x1f, 0x0f, 0x0f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, +0x0f, 0x1f, 0x1f, 0x1e, 0x1c, 0x1c, 0x1c, 0x1e, 0x1f, 0x0f, 0x07, 0x07, 0x01, +0x00, 0x00, 0x00, 0x10, 0x1c, 0x1e, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x01, 0x07, +0x1f, 0x1f, 0x1f, 0x1c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +/* settings saved to this location */ static char default_filename[] = "/.rockbox/rocks/.clock_settings"; +/* names of contributors */ +char* credits[] = { +"Zakk Roberts", +"Linus N. Feltzing", +"BlueChip", +"T.P. Diffenbach", +"David McIntyre", +"Justin D. Young", +"Lee Pilgrim", +"top_bloke", +"Adam S.", +"Scott Myran", +"Tony Kirk", +"Jason Tye" +}; + +/* ...and how they helped */ +char* jobs[] = { +"Code", +"Code", +"Code", +"Code", +"Code", +"Code", +"Code", +"Code", +"Logo", +"Design", +"Design", +"Design" +}; + +bool done = false; /* This bool is used for most of the while loops */ +int logo = 4; /* must be set before we show the logo */ + +/************************************ + * This is saved to default_filename + ************************************/ struct saved_settings { - bool is_date_displayed; - bool are_digits_displayed; - bool is_time_displayed; - bool is_rect_displayed; - bool analog_clock; + /* general */ + int clock; /* 1: analog, 2: digital led, 3: digital lcd, 4: full, 5: binary */ + bool backlight_on; + + /* analog */ + bool analog_digits; + int analog_date; /* 0: off, 1: american, 2: european */ + bool analog_secondhand; + int analog_time; /* 0: off, 1: 24h, 2: 12h */ + + /* digital */ + int digital_seconds; /* 0: off, 1: digital, 2: bar, 3: fullscreen */ + int digital_date; /* 0: off, 1: american, 2: european */ + bool digital_blinkcolon; + bool digital_12h; + + /* LCD */ + int lcd_seconds; /* 0: off, 1: lcd, 2: bar, 3: fullscreen */ + int lcd_date; /* 0: off, 1: american, 2: european */ + bool lcd_blinkcolon; + bool lcd_12h; + + /* fullscreen */ + bool fullscreen_border; + bool fullscreen_secondhand; + bool fullscreen_invertseconds; } settings; +/************************* + * Setting default values + *************************/ +void reset_settings(void) +{ + /* general */ + settings.clock = 1; /* 1: analog, 2: digital led, 3: digital lcd, 4: full, 5: binary */ + settings.backlight_on = true; + + /* analog */ + settings.analog_digits = false; + settings.analog_date = 0; /* 0: off, 1: american, 2: european */ + settings.analog_secondhand = true; + settings.analog_time = false; /* 0: off, 1: 24h, 2: 12h */ + + /* digital */ + settings.digital_seconds = 1; /* 0: off, 1: digital, 2: bar, 3: fullscreen */ + settings.digital_date = 1; /* 0: off, 1: american, 2: european */ + settings.digital_blinkcolon = false; + settings.digital_12h = true; + + /* LCD */ + settings.lcd_seconds = 1; /* 0: off, 1: lcd, 2: bar, 3: fullscreen */ + settings.lcd_date = 1; /* 0: off, 1: american, 2: european */ + settings.lcd_blinkcolon = false; + settings.lcd_12h = true; + + /* fullscreen */ + settings.fullscreen_border = true; + settings.fullscreen_secondhand = true; + settings.fullscreen_invertseconds = false; +} +/********************************* + * Saves "saved_settings" to disk + *********************************/ void save_settings(void) { + rb->lcd_clear_display(); + + show_logo(true, true); + rb->lcd_puts(0, 7, "Saving..."); + + rb->lcd_update(); + int fd; - fd = rb->creat(default_filename, O_WRONLY); + if(fd >= 0) { rb->write (fd, &settings, sizeof(struct saved_settings)); rb->close(fd); + rb->lcd_puts(0, 7, "Save Succeeded"); + } + else + rb->lcd_puts(0, 7, "Save Failed"); + + rb->lcd_update(); + + rb->sleep(HZ); + + exit_logo(); +} + +/*********************************** + * Loads "saved_settings" from disk + ***********************************/ +void load_settings(void) +{ + int fd; + fd = rb->open(default_filename, O_RDONLY); + + rb->lcd_setfont(FONT_SYSFIXED); + + rb->lcd_puts(0, 6, "Clock v2.2"); + + if(fd >= 0) /* does file exist? */ + { + if(rb->filesize(fd) == sizeof(struct saved_settings)) /* if so, is it the right size? */ + { + rb->lcd_puts(0, 7, "Loading..."); + rb->read(fd, &settings, sizeof(struct saved_settings)); + rb->close(fd); + show_logo(true, true); + rb->lcd_puts(0, 6, "Clock v2.2"); + rb->lcd_puts(0, 7, "Loaded settings"); + } + else /* bail out */ + { + rb->lcd_puts(0, 7, "Old settings file"); + reset_settings(); + } + } + else /* bail out */ + { + rb->lcd_puts(0, 7, "Can't find settings"); + reset_settings(); + } + + rb->lcd_update(); + + rb->sleep(HZ*2); + + exit_logo(); +} + +/************************************************************** + * 7-Segment LED/LCD imitation code, by Linus Nielson Feltzing + **************************************************************/ +/* + a 0 b + #########c + # #` + # # + 1# #2 + # # + # 3 # + c ######### d + # # + # # + 4# #5 + # # + # 6 # + e ######### f +*/ +static unsigned int point_coords[6][2] = +{ + {0, 0}, /* a */ + {1, 0}, /* b */ + {0, 1}, /* c */ + {1, 1}, /* d */ + {0, 2}, /* e */ + {1, 2} /* f */ +}; + +/********************************************* + * The end points (a-f) for each segment line + *********************************************/ +static unsigned int seg_points[7][2] = +{ + {0,1}, /* a to b */ + {0,2}, /* a to c */ + {1,3}, /* b to d */ + {2,3}, /* c to d */ + {2,4}, /* c to e */ + {3,5}, /* d to f */ + {4,5} /* e to f */ +}; + +/*********************************************************************** + * Lists that tell which segments (0-6) to enable for each digit (0-9), + * the list is terminated with -1 + ***********************************************************************/ +static int digit_segs[10][8] = +{ + {0,1,2,4,5,6, -1}, /* 0 */ + {2,5, -1}, /* 1 */ + {0,2,3,4,6, -1}, /* 2 */ + {0,2,3,5,6, -1}, /* 3 */ + {1,2,3,5, -1}, /* 4 */ + {0,1,3,5,6, -1}, /* 5 */ + {0,1,3,4,5,6, -1}, /* 6 */ + {0,2,5, -1}, /* 7 */ + {0,1,2,3,4,5,6, -1}, /* 8 */ + {0,1,2,3,5,6, -1} /* 9 */ +}; + +/************************************ + * Draws one segment - LED imitation + ************************************/ +void draw_seg_led(int seg, int x, int y, int width, int height) +{ + int p1 = seg_points[seg][0]; + int p2 = seg_points[seg][1]; + int x1 = point_coords[p1][0]; + int y1 = point_coords[p1][1]; + int x2 = point_coords[p2][0]; + int y2 = point_coords[p2][1]; + + /* It draws parallel lines of different lengths for thicker segments */ + if(seg == 0 || seg == 3 || seg == 6) + { + rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2, + x + x2 * width - 1 , y + y2 * height / 2); + + rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 - 1, + x + x2 * width - 2, y + y2 * height / 2 - 1); + rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 1, + x + x2 * width - 2, y + y2 * height / 2 + 1); + + rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 - 2, + x + x2 * width - 3, y + y2 * height / 2 - 2); + rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 + 2, + x + x2 * width - 3, y + y2 * height / 2 + 2); } else { - rb->splash(HZ, true, "Setting save failed"); + rb->lcd_drawline(x + x1 * width, y + y1 * height / 2 + 1, + x + x2 * width , y + y2 * height / 2 - 1); + + rb->lcd_drawline(x + x1 * width - 1, y + y1 * height / 2 + 2, + x + x2 * width - 1, y + y2 * height / 2 - 2); + rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2 + 2, + x + x2 * width + 1, y + y2 * height / 2 - 2); + + rb->lcd_drawline(x + x1 * width - 2, y + y1 * height / 2 + 3, + x + x2 * width - 2, y + y2 * height / 2 - 3); + + rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 3, + x + x2 * width + 2, y + y2 * height / 2 - 3); + } +} + +/************************************ + * Draws one segment - LCD imitation + ************************************/ +void draw_seg_lcd(int seg, int x, int y, int width, int height) +{ + int p1 = seg_points[seg][0]; + int p2 = seg_points[seg][1]; + int x1 = point_coords[p1][0]; + int y1 = point_coords[p1][1]; + int x2 = point_coords[p2][0]; + int y2 = point_coords[p2][1]; + + if(seg == 0) + { + rb->lcd_drawline(x + x1 * width, y + y1 * height / 2 - 1, + x + x2 * width, y + y2 * height / 2 - 1); + rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2, + x + x2 * width - 1, y + y2 * height / 2); + rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 1, + x + x2 * width - 2, y + y2 * height / 2 + 1); + rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 + 2, + x + x2 * width - 3, y + y2 * height / 2 + 2); + } + else if(seg == 3) + { + rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2, + x + x2 * width - 1, y + y2 * height / 2); + rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 - 1, + x + x2 * width - 2, y + y2 * height / 2 - 1); + rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 1, + x + x2 * width - 2, y + y2 * height / 2 + 1); + rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 - 2, + x + x2 * width - 3, y + y2 * height / 2 - 2); + rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 + 2, + x + x2 * width - 3, y + y2 * height / 2 + 2); + } + else if(seg == 6) + { + rb->lcd_drawline(x + x1 * width, y + y1 * height / 2 + 1, + x + x2 * width, y + y2 * height / 2 + 1); + rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2, + x + x2 * width - 1, y + y2 * height / 2); + rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 - 1, + x + x2 * width - 2, y + y2 * height / 2 - 1); + rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 - 2, + x + x2 * width - 3, y + y2 * height / 2 - 2); + + } + else if(seg == 1 || seg == 4) + { + rb->lcd_drawline(x + x1 * width - 1, y + y1 * height / 2, + x + x2 * width - 1, y + y2 * height / 2); + rb->lcd_drawline(x + x1 * width, y + y1 * height / 2 + 1, + x + x2 * width, y + y2 * height / 2 - 1); + rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2 + 2, + x + x2 * width + 1, y + y2 * height / 2 - 2); + rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 3, + x + x2 * width + 2, y + y2 * height / 2 - 3); + } + else if(seg == 2 || seg == 5) + { + rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2, + x + x2 * width + 1, y + y2 * height / 2); + rb->lcd_drawline(x + x1 * width, y + y1 * height / 2 + 1, + x + x2 * width, y + y2 * height / 2 - 1); + rb->lcd_drawline(x + x1 * width - 1, y + y1 * height / 2 + 2, + x + x2 * width - 1, y + y2 * height / 2 - 2); + rb->lcd_drawline(x + x1 * width - 2, y + y1 * height / 2 + 3, + x + x2 * width - 2, y + y2 * height / 2 - 3); + } +} + +/****************** + * Draws one digit + ******************/ +void draw_7seg_digit(int digit, int x, int y, int width, int height, bool lcd_display) +{ + int i; + int c; + + for(i = 0;digit_segs[digit][i] >= 0;i++) + { + c = digit_segs[digit][i]; + + if(!lcd_display) + draw_seg_led(c, x, y, width, height); + else + draw_seg_lcd(c, x, y, width, height); + } +} + +/****************************************************** + * Draws the entire 7-segment hour-minute time display + ******************************************************/ +void draw_7seg_time(int hour, int minute, int x, int y, int width, int height, +bool colon, bool lcd) +{ + int xpos = x; + + /* Draw PM indicator */ + if(settings.digital_12h) + { + if(hour > 12) + rb->lcd_bitmap(pm, 97, 55, 15, 8, true); + else + rb->lcd_bitmap(am, 1, 55, 15, 8, true); + } + + /* Now change to 12H mode if requested */ + if(settings.digital_12h) + if(hour > 12) + hour -= 12; + + draw_7seg_digit(hour / 10, xpos, y, width, height, lcd); + xpos += width + 6; + draw_7seg_digit(hour % 10, xpos, y, width, height, lcd); + xpos += width + 6; + + if(colon) + { + rb->lcd_drawline(xpos, y + height/3 + 2, + xpos, y + height/3 + 2); + rb->lcd_drawline(xpos+1, y + height/3 + 1, + xpos+1, y + height/3 + 3); + rb->lcd_drawline(xpos+2, y + height/3, + xpos+2, y + height/3 + 4); + rb->lcd_drawline(xpos+3, y + height/3 + 1, + xpos+3, y + height/3 + 3); + rb->lcd_drawline(xpos+4, y + height/3 + 2, + xpos+4, y + height/3 + 2); + + rb->lcd_drawline(xpos, y + height-height/3 + 2, + xpos, y + height-height/3 + 2); + rb->lcd_drawline(xpos+1, y + height-height/3 + 1, + xpos+1, y + height-height/3 + 3); + rb->lcd_drawline(xpos+2, y + height-height/3, + xpos+2, y + height-height/3 + 4); + rb->lcd_drawline(xpos+3, y + height-height/3 + 1, + xpos+3, y + height-height/3 + 3); + rb->lcd_drawline(xpos+4, y + height-height/3 + 2, + xpos+4, y + height-height/3 + 2); + } + + xpos += 12; + + draw_7seg_digit(minute / 10, xpos, y, width, height, lcd); + xpos += width + 6; + draw_7seg_digit(minute % 10, xpos, y, width, height, lcd); + xpos += width + 6; +} + +/************** + * Binary mode + **************/ +void binary(int hour, int minute, int second) +{ + /* temporary modifiable versions of ints */ + int temphour = hour; + int tempmin = minute; + int tempsec = second; + + rb->lcd_clear_display(); + + /***************** + * HOUR + *****************/ + if(temphour >= 32) + { + rb->lcd_bitmap(bitmap_1, 0, 1, 15, 20, true); + temphour -= 32; + } + else + rb->lcd_bitmap(bitmap_0, 0, 1, 15, 20, true); + if(temphour >= 16) + { + rb->lcd_bitmap(bitmap_1, 19, 1, 15, 20, true); + temphour -= 16; + } + else + rb->lcd_bitmap(bitmap_0, 19, 1, 15, 20, true); + if(temphour >= 8) + { + rb->lcd_bitmap(bitmap_1, 38, 1, 15, 20, true); + temphour -= 8; + } + else + rb->lcd_bitmap(bitmap_0, 38, 1, 15, 20, true); + if(temphour >= 4) + { + rb->lcd_bitmap(bitmap_1, 57, 1, 15, 20, true); + temphour -= 4; + } + else + rb->lcd_bitmap(bitmap_0, 57, 1, 15, 20, true); + if(temphour >= 2) + { + rb->lcd_bitmap(bitmap_1, 76, 1, 15, 20, true); + temphour -= 2; + } + else + rb->lcd_bitmap(bitmap_0, 76, 1, 15, 20, true); + if(temphour >= 1) + { + rb->lcd_bitmap(bitmap_1, 95, 1, 15, 20, true); + temphour -= 1; + } + else + rb->lcd_bitmap(bitmap_0, 95, 1, 15, 20, true); + + /**************** + * MINUTES + ****************/ + if(tempmin >= 32) + { + rb->lcd_bitmap(bitmap_1, 0, 21, 15, 20, true); + tempmin -= 32; + } + else + rb->lcd_bitmap(bitmap_0, 0, 21, 15, 20, true); + if(tempmin >= 16) + { + rb->lcd_bitmap(bitmap_1, 19, 21, 15, 20, true); + tempmin -= 16; + } + else + rb->lcd_bitmap(bitmap_0, 19, 21, 15, 20, true); + if(tempmin >= 8) + { + rb->lcd_bitmap(bitmap_1, 38, 21, 15, 20, true); + tempmin -= 8; + } + else + rb->lcd_bitmap(bitmap_0, 38, 21, 15, 20, true); + if(tempmin >= 4) + { + rb->lcd_bitmap(bitmap_1, 57, 21, 15, 20, true); + tempmin -= 4; + } + else + rb->lcd_bitmap(bitmap_0, 57, 21, 15, 20, true); + if(tempmin >= 2) + { + rb->lcd_bitmap(bitmap_1, 76, 21, 15, 20, true); + tempmin -= 2; + } + else + rb->lcd_bitmap(bitmap_0, 76, 21, 15, 20, true); + if(tempmin >= 1) + { + rb->lcd_bitmap(bitmap_1, 95, 21, 15, 20, true); + tempmin -= 1; + } + else + rb->lcd_bitmap(bitmap_0, 95, 21, 15, 20, true); + + /**************** + * SECONDS + ****************/ + if(tempsec >= 32) + { + rb->lcd_bitmap(bitmap_1, 0, 42, 15, 20, true); + tempsec -= 32; + } + else + rb->lcd_bitmap(bitmap_0, 0, 42, 15, 20, true); + if(tempsec >= 16) + { + rb->lcd_bitmap(bitmap_1, 19, 42, 15, 20, true); + tempsec -= 16; + } + else + rb->lcd_bitmap(bitmap_0, 19, 42, 15, 20, true); + if(tempsec >= 8) + { + rb->lcd_bitmap(bitmap_1, 38, 42, 15, 20, true); + tempsec -= 8; + } + else + rb->lcd_bitmap(bitmap_0, 38, 42, 15, 20, true); + if(tempsec >= 4) + { + rb->lcd_bitmap(bitmap_1, 57, 42, 15, 20, true); + tempsec -= 4; + } + else + rb->lcd_bitmap(bitmap_0, 57, 42, 15, 20, true); + if(tempsec >= 2) + { + rb->lcd_bitmap(bitmap_1, 76, 42, 15, 20, true); + tempsec -= 2; + } + else + rb->lcd_bitmap(bitmap_0, 76, 42, 15, 20, true); + if(tempsec >= 1) + { + rb->lcd_bitmap(bitmap_1, 95, 42, 15, 20, true); + tempsec -= 1; + } + else + rb->lcd_bitmap(bitmap_0, 95, 42, 15, 20, true); + + rb->lcd_update(); +} + +/***************** + * Shows the logo + *****************/ +void show_logo(bool animate, bool show_clock_text) +{ + int x_position; + unsigned char *clogo = 0; + + /* decide which logo we're using - usually #4 */ + if(logo == 1) + clogo = (unsigned char *)clocklogo_1; + else if(logo == 2) + clogo = (unsigned char *)clocklogo_2; + else if(logo == 3) + clogo = (unsigned char *)clocklogo_3; + else + clogo = (unsigned char *)clocklogo_4; + + /* animate logo */ + if(animate) + { + /* move down the screen */ + for(x_position = 0; x_position <= 25; x_position++) + { + rb->lcd_clearline(0, x_position/2-1, 111, x_position/2-1); + rb->lcd_clearline(0, x_position/2+38, 111, x_position/2+38); + rb->lcd_bitmap(clogo, 0, x_position/2, 112, 37, true); + if(show_clock_text) + rb->lcd_puts(0, 6, "Clock v2.2"); + rb->lcd_update(); + } + /* bounce back up a little */ + for(x_position = 25; x_position >= 18; x_position--) + { + rb->lcd_clearline(0, x_position/2-1, 111, x_position/2-1); + rb->lcd_clearline(0, x_position/2+38, 111, x_position/2+38); + rb->lcd_bitmap(clogo, 0, x_position/2, 112, 37, true); + if(show_clock_text) + rb->lcd_puts(0, 6, "Clock v2.2"); + rb->lcd_update(); + } + /* and go back down again */ + for(x_position = 18; x_position <= 20; x_position++) + { + rb->lcd_clearline(0, x_position/2-1, 111, x_position/2-1); + rb->lcd_clearline(0, x_position/2+38, 111, x_position/2+38); + rb->lcd_bitmap(clogo, 0, x_position/2, 112, 37, true); + if(show_clock_text) + rb->lcd_puts(0, 6, "Clock v2.2"); + rb->lcd_update(); + } + } + else /* don't animate, just show */ + { + rb->lcd_bitmap(clogo, 0, 10, 112, 37, true); + rb->lcd_update(); + } +} + +/********************* + * Logo flies off lcd + *********************/ +void exit_logo(void) +{ + int x_position; + + unsigned char *clogo = 0; + + if(logo == 1) + clogo = (unsigned char *)clocklogo_1; + else if(logo == 2) + clogo = (unsigned char *)clocklogo_2; + else if(logo == 3) + clogo = (unsigned char *)clocklogo_3; + else + clogo = (unsigned char *)clocklogo_4; + + /* fly downwards */ + for(x_position = 20; x_position <= 128; x_position++) + { + rb->lcd_clearline(0, x_position/2-1, 111, x_position/2-1); + rb->lcd_bitmap(clogo, 0, x_position/2, 112, 37, true); + rb->lcd_update(); + } +} + +/******************** + * Rolls the credits + ********************/ +/* The following function is pretty confusing, so + * it's extra well commented. */ +bool roll_credits(void) +{ + int j, namepos, jobpos; /* namepos/jobpos are x coords for strings of text */ + int btn; + int numnames = 12; /* amount of people in the credits array */ + int pause; + + /* used to center the text */ + char name[20]; + char job[15]; + int name_w, name_h; + int job_w, job_h; + + /* Shows "[Credits] X/X" */ + char elapsednames[16]; + + for(j=0; j < numnames; j++) + { + rb->lcd_clear_display(); + + show_logo(false, false); + + rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d", j+1, numnames); + rb->lcd_puts(0, 0, elapsednames); + + /* used to center the text */ + rb->snprintf(name, sizeof(name), "%s", credits[j]); + rb->snprintf(job, sizeof(job), "%s", jobs[j]); + rb->lcd_getstringsize(name, &name_w, &name_h); + rb->lcd_getstringsize(job, &job_w, &job_h); + + /* line 1 flies in */ + for (namepos=0; namepos < LCD_WIDTH/2-name_w/2; namepos++) + { + rb->lcd_clearrect(0, 48, 112, 8); /* clear any trails left behind */ + rb->lcd_putsxy(namepos, 48, name); /* show their name */ + rb->lcd_update(); + + /* exit on keypress */ + btn = rb->button_get(false); + if (btn != BUTTON_NONE && !(btn & BUTTON_REL)) + return false; + } + + /* now line 2 flies in */ + for(jobpos=LCD_WIDTH; jobpos > LCD_WIDTH/2-(job_w+2)/2; jobpos--) /* we use (job_w+2) to ensure it fits on the LCD */ + { + rb->lcd_clearrect(0, 56, 112, 8); /* clear trails */ + rb->lcd_putsxy(jobpos, 56, job); /* show their job */ + rb->lcd_update(); + + /* exit on keypress */ + btn = rb->button_get(false); + if (btn != BUTTON_NONE && !(btn & BUTTON_REL)) + return false; + } + + /* pause (2s) and scan for button presses */ + for (pause = 0; pause < 10; pause++) + { + rb->sleep((HZ*2)/10); /* wait a moment */ + + btn = rb->button_get(false); + if (btn != BUTTON_NONE && !(btn & BUTTON_REL)) + return false; + } + + /* fly out both lines at same time */ + namepos=(LCD_WIDTH/2-name_w/2)+5; + jobpos=(LCD_WIDTH/2-(job_w+2)/2)-5; + while(namepos 0-job_w) + { + rb->lcd_clearrect(0, 48, 112, 16); /* clear trails */ + rb->lcd_putsxy(namepos, 48, name); + rb->lcd_putsxy(jobpos, 56, job); + rb->lcd_update(); + + /* exit on keypress */ + btn = rb->button_get(false); + if (btn != BUTTON_NONE && !(btn & BUTTON_REL)) + return false; + + namepos++; + jobpos--; + } + + /* pause (.5s) */ + rb->sleep(HZ/2); + + /* and scan for button presses */ + btn = rb->button_get(false); + if ( (!btn) && (!(btn&BUTTON_REL)) ) + return false; + } + return true; +} + +/***************************************** + * Shows the logo, then rolls the credits + *****************************************/ +bool show_credits(void) +{ + int j = 0; + int btn; + + rb->lcd_clear_display(); + + /* show the logo with an animation and the clock 2.2 text */ + show_logo(true, true); + + rb->lcd_puts(0, 7, "Credit Roll..."); + + rb->lcd_update(); + + /* pause while button scanning */ + for (j = 0; j < 10; j++) + { + rb->sleep((HZ*2)/10); + + btn = rb->button_get(false); + if (btn != BUTTON_NONE && !(btn & BUTTON_REL)) + return false; + } + + /* then roll the credits */ + roll_credits(); + + return false; +} + +/******************* + * F1 Screen - HELP + *******************/ +bool f1_screen(void) +{ + done = false; + + while (!done) + { + rb->lcd_clear_display(); + + /* page one */ + if(screen == 1) + { + rb->lcd_puts(0, 0, "Using Clock v2.2:"); + rb->lcd_puts(0, 1, "To navigate this"); + rb->lcd_puts(0, 2, "help, use LEFT and"); + rb->lcd_puts(0, 3, "RIGHT. F1 returns"); + rb->lcd_puts(0, 4, "you to the clock."); + rb->lcd_puts(0, 6, ""); + rb->lcd_puts(0, 7, "<< ---- 1/9 NEXT >>"); + } + else if(screen == 2) + { + rb->lcd_puts(0, 0, "At any mode, [F1]"); + rb->lcd_puts(0, 1, "will show you this"); + rb->lcd_puts(0, 2, "help screen. [F2]"); + rb->lcd_puts(0, 3, "will start/stop"); + rb->lcd_puts(0, 4, "the Counter. Hold"); + rb->lcd_puts(0, 5, "F2 to reset the"); + rb->lcd_puts(0, 6, "Counter."); + rb->lcd_puts(0, 7, "<< BACK 2/9 NEXT >>"); + } + else if(screen == 3) + { + rb->lcd_puts(0, 0, "At any mode, [F3]"); + rb->lcd_puts(0, 1, "opens the Options"); + rb->lcd_puts(0, 2, "screen. In Options"); + rb->lcd_puts(0, 3, "move the cursor"); + rb->lcd_puts(0, 4, "with UP/DOWN and"); + rb->lcd_puts(0, 5, "use PLAY to toggle"); + rb->lcd_puts(0, 6, "selected option."); + rb->lcd_puts(0, 7, "<< BACK 3/9 NEXT >>"); + } + else if(screen == 4) + { + rb->lcd_puts(0, 0, "[ON] at any mode"); + rb->lcd_puts(0, 1, "will present you"); + rb->lcd_puts(0, 2, "with a credits roll"); + rb->lcd_puts(0, 3, "[PLAY] from any"); + rb->lcd_puts(0, 4, "mode will show the"); + rb->lcd_puts(0, 5, "MODE SELECTOR. Use"); + rb->lcd_puts(0, 6, "UP/DOWN to select"); + rb->lcd_puts(0, 7, "<< BACK 4/9 NEXT >>"); + } + else if(screen == 5) + { + rb->lcd_puts(0, 0, "a mode and PLAY to"); + rb->lcd_puts(0, 1, "go to it."); + rb->lcd_puts(0, 2, "_-=CLOCK MODES=-_"); + rb->lcd_puts(0, 3, "*ANALOG: Shows a"); + rb->lcd_puts(0, 4, "small round clock"); + rb->lcd_puts(0, 5, "in the center of"); + rb->lcd_puts(0, 6, "LCD. Options appear"); + rb->lcd_puts(0, 7, "<< BACK 5/9 NEXT >>"); + } + else if(screen == 6) + { + rb->lcd_puts(0, 0, "around it."); + rb->lcd_puts(0, 1, "*DIGITAL: Shows an"); + rb->lcd_puts(0, 2, "LCD imitation with"); + rb->lcd_puts(0, 3, "virtual 'segments'."); + rb->lcd_puts(0, 4, "*LCD: Shows another"); + rb->lcd_puts(0, 5, "imitation of an"); + rb->lcd_puts(0, 6, "LCD display."); + rb->lcd_puts(0, 7, "<< BACK 6/9 NEXT >>"); + } + else if(screen == 7) + { + rb->lcd_puts(0, 0, "*FULLSCREEN: Like"); + rb->lcd_puts(0, 1, "Analog mode, but"); + rb->lcd_puts(0, 2, "uses the whole LCD."); + rb->lcd_puts(0, 3, "Less options are"); + rb->lcd_puts(0, 4, "available in this"); + rb->lcd_puts(0, 5, "mode."); + rb->lcd_puts(0, 6, "*BINARY: Shows a"); + rb->lcd_puts(0, 7, "<< BACK 7/9 NEXT >>"); + } + else if(screen == 8) + { + rb->lcd_puts(0, 0, "binary clock. For"); + rb->lcd_puts(0, 1, "help on reading"); + rb->lcd_puts(0, 2, "binary, see:"); + rb->lcd_puts_scroll(0, 3, "http://en.wikipedia.org/wiki/Binary_numeral_system"); + rb->lcd_puts(0, 4, "_-=OTHER KEYS=-_"); + rb->lcd_puts(0, 5, "[DWN] will disable"); + rb->lcd_puts(0, 6, "Rockbox's idle"); + rb->lcd_puts(0, 7, "<< BACK 8/9 NEXT >>"); + } + else if(screen == 9) + { + rb->lcd_puts(0, 0, "poweroff feature."); + rb->lcd_puts(0, 1, "[UP] will reenable"); + rb->lcd_puts(0, 2, "it. [LEFT] will"); + rb->lcd_puts(0, 3, "turn off the back-"); + rb->lcd_puts(0, 4, " light, [RIGHT]"); + rb->lcd_puts(0, 5, "will turn it on."); + rb->lcd_puts(0, 6, "[OFF] exits plugin."); + rb->lcd_puts(0, 7, "<< BACK 9/9 ---- >>"); + } + + rb->lcd_update(); + + switch (rb->button_get(true)) + { + case BUTTON_F1: /* exit */ + case BUTTON_OFF: + done = true; + break; + + case BUTTON_LEFT: + if(screen > 1) + screen --; + break; + + case BUTTON_RIGHT: + if(screen < 9) + screen++; + break; + + case SYS_USB_CONNECTED: /* leave for usb */ + return PLUGIN_USB_CONNECTED; + rb->usb_screen(); + break; + } + } + return true; +} + +/************************** + * F2 Screen - Pick a Logo + * [[ NO LONGER USED ]] + **************************/ +void f2_screen(void) +{ + rb->lcd_clear_display(); + rb->splash(HZ, true, "LEFT/RIGHT to choose logo"); + rb->lcd_update(); + rb->lcd_clear_display(); + rb->splash(HZ, true, "F2 to select and exit"); + rb->lcd_update(); + rb->lcd_clear_display(); + + /* let's make sure that the logo isn't invalid */ + if(logo > 4) + logo = 1; + + done = false; + + while(!done) + { + show_logo(false, false); + + rb->lcd_clearrect(0, 48, 112, 16); + + if(logo == 1) + { + rb->lcd_puts(0, 0, "1) 'Default'"); + rb->lcd_puts(0, 6, "By Zakk Roberts"); + } + else if(logo == 2) + { + rb->lcd_puts(0, 0, "2) 'Digital'"); + rb->lcd_puts(0, 6, "By Zakk Roberts"); + } + else if(logo == 3) + { + rb->lcd_puts(0, 0, "3) 'Electroplate'"); + rb->lcd_puts(0, 6, "By Adam S. and"); + rb->lcd_puts(0, 7, "Zakk Roberts"); + } + else + { + rb->lcd_puts(0, 0, "4) 'Clockbox'"); + rb->lcd_puts(0, 6, "By Adam S."); + } + + rb->lcd_update(); + + switch(rb->button_get_w_tmo(HZ/4)) + { + case BUTTON_F2: + case BUTTON_OFF: + done = true; + break; + + case BUTTON_RIGHT: + if(logo < 4) + logo++; + break; + + case BUTTON_LEFT: + if(logo > 1) + logo--; + break; + } + } +} + +/********************** + * F3 Screen - OPTIONS + **********************/ +bool f3_screen(void) +{ + done = false; + + int invert_analog = 1; + int invert_digital = 1; + int invert_lcd = 1; + int invert_fullscreen = 1; + + while (!done) + { + rb->lcd_clear_display(); + + if(settings.clock == 1) + { + rb->lcd_puts(0, 0, "OPTIONS (Analog)"); + rb->lcd_puts(0, 1, "UP/DOWN & PLAY"); + rb->lcd_puts(0, 2, "F3/OFF: Done"); + rb->lcd_puts(2, 4, "Digits"); + + if(settings.analog_date == 0) + rb->lcd_puts(2, 5, "Date"); + else if(settings.analog_date == 1) + rb->lcd_puts(2, 5, "Date: American"); + else + rb->lcd_puts(2, 5, "Date: European"); + + if(settings.analog_time == 0) + rb->lcd_puts(2, 6, "Time Readout"); + else if(settings.analog_time == 1) + rb->lcd_puts(2, 6, "Time Readout 24h"); + else + rb->lcd_puts(2, 6, "Time Readout 12h"); + + rb->lcd_puts(2, 7, "Second Hand"); + + /* Draw checkboxes using the new checkbox() function */ + rb->checkbox(1, 33, 8, 6, settings.analog_digits); + if(settings.analog_date != 0) + rb->checkbox(1, 41, 8, 6, true); + else + rb->checkbox(1, 41, 8, 6, false); + rb->checkbox(1, 49, 8, 6, settings.analog_time); + rb->checkbox(1, 57, 8, 6, settings.analog_secondhand); + + /* Draw line selector */ + switch(invert_analog) + { + case 1: + rb->lcd_invertrect(0, 32, 112, 8); break; + + case 2: + rb->lcd_invertrect(0, 40, 112, 8); break; + + case 3: + rb->lcd_invertrect(0, 48, 112, 8); break; + + case 4: + rb->lcd_invertrect(0, 56, 112, 8); break; + } + + rb->lcd_update(); + + switch(rb->button_get_w_tmo(HZ/4)) + { + case BUTTON_UP: + if(invert_analog > 1) + invert_analog--; + else + invert_analog = 4; + break; + + case BUTTON_DOWN: + if(invert_analog < 4) + invert_analog++; + else + invert_analog = 1; + break; + + case BUTTON_PLAY: + if(invert_analog == 1) + settings.analog_digits = !settings.analog_digits; + else if(invert_analog == 2) + { + if(settings.analog_date < 2) + settings.analog_date++; + else + settings.analog_date = 0; + } + else if(invert_analog == 3) + { + if(settings.analog_time < 2) + settings.analog_time++; + else + settings.analog_time = 0; + } + else + settings.analog_secondhand = !settings.analog_secondhand; + break; + + case BUTTON_F3: + case BUTTON_OFF: + done = true; + break; + } + } + else if(settings.clock == 2) + { + rb->lcd_puts(0, 0, "OPTIONS (Digital)"); + rb->lcd_puts(0, 1, "UP/DOWN & PLAY"); + rb->lcd_puts(0, 2, "F3/OFF: Done"); + + if(settings.digital_date == 0) + rb->lcd_puts(2, 4, "Date"); + else if(settings.digital_date == 1) + rb->lcd_puts(2, 4, "Date: American"); + else + rb->lcd_puts(2, 4, "Date: European"); + + if(settings.digital_seconds == 0) + rb->lcd_puts(2, 5, "Seconds"); + else if(settings.digital_seconds == 1) + rb->lcd_puts(2, 5, "Seconds: DIGITAL"); + else if(settings.digital_seconds == 2) + rb->lcd_puts(2, 5, "Seconds: BAR"); + else + rb->lcd_puts(2, 5, "Seconds: INVERSE"); + + rb->lcd_puts(2, 6, "Blinking Colon"); + rb->lcd_puts(2, 7, "12-Hour Format"); + + /* Draw checkboxes */ + if(settings.digital_date != 0) + rb->checkbox(1, 33, 8, 6, true); + else + rb->checkbox(1, 33, 8, 6, false); + if(settings.digital_seconds != 0) + rb->checkbox(1, 41, 8, 6, true); + else + rb->checkbox(1, 41, 8, 6, false); + rb->checkbox(1, 49, 8, 6, settings.digital_blinkcolon); + rb->checkbox(1, 57, 8, 6, settings.digital_12h); + + /* Draw a line selector */ + switch(invert_digital) + { + case 1: + rb->lcd_invertrect(0, 32, 112, 8); break; + + case 2: + rb->lcd_invertrect(0, 40, 112, 8); break; + + case 3: + rb->lcd_invertrect(0, 48, 112, 8); break; + + case 4: + rb->lcd_invertrect(0, 56, 112, 8); break; + } + + rb->lcd_update(); + + switch(rb->button_get_w_tmo(HZ/4)) + { + case BUTTON_UP: + if(invert_digital == 1) + invert_digital = 4; + else + invert_digital--; + break; + + case BUTTON_DOWN: + if(invert_digital == 4) + invert_digital = 1; + else + invert_digital++; + break; + + case BUTTON_PLAY: + if(invert_digital == 1) + { + if(settings.digital_date < 2) + settings.digital_date++; + else + settings.digital_date = 0; + } + else if(invert_digital == 2) + { + if(settings.digital_seconds < 3) + settings.digital_seconds++; + else + settings.digital_seconds = 0; + } + else if(invert_digital == 3) + settings.digital_blinkcolon = !settings.digital_blinkcolon; + else + settings.digital_12h = !settings.digital_12h; + break; + + case BUTTON_F3: + case BUTTON_OFF: + done = true; + break; + } + } + else if(settings.clock == 3) + { + rb->lcd_puts(0, 0, "OPTIONS (LCD)"); + rb->lcd_puts(0, 1, "UP/DOWN & PLAY"); + rb->lcd_puts(0, 2, "F3/OFF: Done"); + + if(settings.lcd_date == 0) + rb->lcd_puts(2, 4, "Date"); + else if(settings.lcd_date == 1) + rb->lcd_puts(2, 4, "Date: American"); + else + rb->lcd_puts(2, 4, "Date: European"); + + if(settings.lcd_seconds == 0) + rb->lcd_puts(2, 5, "Seconds"); + else if(settings.lcd_seconds == 1) + rb->lcd_puts(2, 5, "Seconds: DIGITAL"); + else if(settings.lcd_seconds == 2) + rb->lcd_puts(2, 5, "Seconds: BAR"); + else + rb->lcd_puts(2, 5, "Seconds: INVERSE"); + + rb->lcd_puts(2, 6, "Blinking Colon"); + rb->lcd_puts(2, 7, "12-Hour Format"); + + /* Draw checkboxes */ + if(settings.lcd_date != 0) + rb->checkbox(1, 33, 8, 6, true); + else + rb->checkbox(1, 33, 8, 6, false); + if(settings.lcd_seconds != 0) + rb->checkbox(1, 41, 8, 6, true); + else + rb->checkbox(1, 41, 8, 6, false); + rb->checkbox(1, 49, 8, 6, settings.lcd_blinkcolon); + rb->checkbox(1, 57, 8, 6, settings.lcd_12h); + + /* Draw a line selector */ + switch(invert_lcd) + { + case 1: + rb->lcd_invertrect(0, 32, 112, 8); break; + + case 2: + rb->lcd_invertrect(0, 40, 112, 8); break; + + case 3: + rb->lcd_invertrect(0, 48, 112, 8); break; + + case 4: + rb->lcd_invertrect(0, 56, 112, 8); break; + } + + rb->lcd_update(); + + switch(rb->button_get_w_tmo(HZ/4)) + { + case BUTTON_UP: + if(invert_lcd == 1) + invert_lcd = 4; + else + invert_lcd--; + break; + + case BUTTON_DOWN: + if(invert_lcd == 4) + invert_lcd = 1; + else + invert_lcd++; + break; + + case BUTTON_PLAY: + if(invert_lcd == 1) + { + if(settings.lcd_date < 2) + settings.lcd_date++; + else + settings.lcd_date = 0; + } + else if(invert_lcd == 2) + { + if(settings.lcd_seconds < 3) + settings.lcd_seconds++; + else + settings.lcd_seconds = 0; + } + else if(invert_lcd == 3) + settings.lcd_blinkcolon = !settings.lcd_blinkcolon; + else + settings.lcd_12h = !settings.lcd_12h; + break; + + case BUTTON_F3: + case BUTTON_OFF: + done = true; + break; + } + } + else if(settings.clock == 4) + { + rb->lcd_puts(0, 0, "OPTIONS (Full)"); + rb->lcd_puts(0, 1, "UP/DOWN & PLAY"); + rb->lcd_puts(0, 2, "F3/OFF: Done"); + + rb->lcd_puts(2, 4, "Border"); + rb->lcd_puts(2, 5, "Second Hand"); + rb->lcd_puts(2, 6, "Invert Seconds"); + + rb->checkbox(1, 33, 8, 6, settings.fullscreen_border); + rb->checkbox(1, 41, 8, 6, settings.fullscreen_secondhand); + rb->checkbox(1, 49, 8, 6, settings.fullscreen_invertseconds); + + /* Draw a line selector + * There are 4 values here in case we decide to "up" the amount of settings */ + switch(invert_fullscreen) + { + case 1: + rb->lcd_invertrect(0, 32, 112, 8); break; + + case 2: + rb->lcd_invertrect(0, 40, 112, 8); break; + + case 3: + rb->lcd_invertrect(0, 48, 112, 8); break; + + case 4: + rb->lcd_invertrect(0, 56, 112, 8); break; + } + + rb->lcd_update(); + + switch(rb->button_get_w_tmo(HZ/4)) + { + case BUTTON_UP: + if(invert_fullscreen == 1) + invert_fullscreen = 3; + else + invert_fullscreen--; + break; + + case BUTTON_DOWN: + if(invert_fullscreen == 3) + invert_fullscreen = 1; + else + invert_fullscreen++; + break; + + case BUTTON_PLAY: + if(invert_fullscreen == 1) + settings.fullscreen_border = !settings.fullscreen_border; + else if(invert_fullscreen == 2) + settings.fullscreen_secondhand = !settings.fullscreen_secondhand; + else + settings.fullscreen_invertseconds = !settings.fullscreen_invertseconds; + break; + + case BUTTON_F3: + case BUTTON_OFF: + done = true; + break; + } + } + else + { + rb->lcd_puts(0, 0, "OPTIONS (Binary)"); + rb->lcd_puts(0, 1, "UP/DOWN & PLAY"); + rb->lcd_puts(0, 2, "F3/OFF: Done"); + + rb->lcd_puts(2, 4, "-- NO OPTIONS --"); + rb->lcd_puts(1, 6, "F3/OFF to return"); + + rb->lcd_update(); + + switch(rb->button_get_w_tmo(HZ/4)) + { + + case BUTTON_F3: + case BUTTON_OFF: + done = true; + break; + } + } + } + return true; +} + +/***************************************** + * Draws the extras, IE border, digits... + *****************************************/ +void draw_extras(int year, int day, int month, int hour, int minute, int second) +{ + char buf[11]; + int w, h; + int i; + int tempyear = 0; + + struct tm* current_time = rb->get_time(); + + int fill = seconds112[second]; + + char moday[8]; + char dateyr[6]; + char tmhrmin[7]; + char tmsec[3]; + + if(year == 2004) + tempyear = 04; + + /* american date readout */ + if(settings.analog_date == 1) + rb->snprintf(moday, sizeof(moday), "%02d/%02d", month, day); + else + rb->snprintf(moday, sizeof(moday), "%02d.%02d", day, month); + rb->snprintf(dateyr, sizeof(dateyr), "%d", year); + rb->snprintf(tmhrmin, sizeof(tmhrmin), "%02d:%02d", hour, minute); + rb->snprintf(tmsec, sizeof(tmsec), "%02d", second); + + /* Analog Extras */ + if(settings.clock == 1) + { + /* DIGITS around the face */ + if (settings.analog_digits) + { + rb->lcd_putsxy((LCD_WIDTH/2)-6, 0, "12"); + rb->lcd_putsxy(20, (LCD_HEIGHT/2)-4, "9"); + rb->lcd_putsxy((LCD_WIDTH/2)-4, 56, "6"); + rb->lcd_putsxy(86, (LCD_HEIGHT/2)-4, "3"); + } + + /* Digital readout */ + if (settings.analog_time != 0) + { + /* HH:MM */ + rb->lcd_putsxy(1, 4, tmhrmin); + /* SS */ + rb->lcd_putsxy(10, 12, tmsec); + + /* AM/PM indicator */ + if(settings.analog_time == 2) + { + if(current_time->tm_hour > 12) /* PM */ + rb->lcd_bitmap(pm, 96, 1, 15, 8, true); + else /* AM */ + rb->lcd_bitmap(am, 96, 1, 15, 8, true); + } + } + + /* Date readout */ + if(settings.analog_date != 0) + { + /* MM-DD (or DD.MM) */ + rb->lcd_putsxy(1, 48, moday); + rb->lcd_putsxy(3, 56, dateyr); + } + } + else if(settings.clock == 2) + { + /* Date readout */ + if(settings.digital_date == 1) /* american mode */ + { + rb->snprintf(buf, sizeof(buf), "%d/%d/%d", month, day, year); + rb->lcd_getstringsize(buf, &w, &h); + rb->lcd_putsxy((LCD_WIDTH/2)-(w/2), 56, buf); + } + else if(settings.digital_date == 2) /* european mode */ + { + rb->snprintf(buf, sizeof(buf), "%d.%d.%d", day, month, year); + rb->lcd_getstringsize(buf, &w, &h); + rb->lcd_putsxy((LCD_WIDTH/2)-(w/2), 56, buf); + } + + /* Second readout */ + if(settings.digital_seconds == 1) + { + rb->snprintf(buf, sizeof(buf), "%d", second); + rb->lcd_getstringsize(buf, &w, &h); + rb->lcd_putsxy((LCD_WIDTH/2)-(w/2), 5, buf); + } + + /* Second progressbar */ + if(settings.digital_seconds == 2) + { + rb->progressbar(0, 0, 112, 4, seconds100[second], 0); + } + + /* Invert the whole LCD as the seconds go */ + if(settings.digital_seconds == 3) + { + rb->lcd_invertrect(0, 0, fill, 64); + } + } + else if(settings.clock == 3) /* LCD mode */ + { + /* Date readout */ + if(settings.lcd_date == 1) /* american mode */ + { + rb->snprintf(buf, sizeof(buf), "%d/%d/%d", month, day, year); + rb->lcd_getstringsize(buf, &w, &h); + rb->lcd_putsxy((LCD_WIDTH/2)-(w/2), 56, buf); + } + else if(settings.lcd_date == 2) /* european mode */ + { + rb->snprintf(buf, sizeof(buf), "%d.%d.%d", day, month, year); + rb->lcd_getstringsize(buf, &w, &h); + rb->lcd_putsxy((LCD_WIDTH/2)-(w/2), 56, buf); + } + + /* Second readout */ + if(settings.lcd_seconds == 1) + { + rb->snprintf(buf, sizeof(buf), "%d", second); + rb->lcd_getstringsize(buf, &w, &h); + rb->lcd_putsxy((LCD_WIDTH/2)-(w/2), 5, buf); + } + + /* Second progressbar */ + if(settings.lcd_seconds == 2) + { + rb->progressbar(0, 0, 112, 4, seconds100[second], 0); + } + + /* Invert the whole LCD as the seconds go */ + if(settings.lcd_seconds == 3) + { + rb->lcd_invertrect(0, 0, fill, 64); + } + } + else if(settings.clock == 4) /* Fullscreen mode */ + { + if(settings.fullscreen_border) + { + /* Draw the circle */ + for(i=0; i < 60; i+=5) + { + rb->lcd_drawpixel(xminute_full[i], + yminute_full[i]); + rb->lcd_drawrect(xminute_full[i]-1, + yminute_full[i]-1, + 3, 3); + } + } + if(settings.fullscreen_invertseconds) + { + rb->lcd_invertrect(0, 0, fill, 64); + } + } +} + +/**************** + * Select a mode + ****************/ +void select_mode(void) +{ + done = false; + + int cursorpos = settings.clock; + bool a = false; /* (a)nalog */ + bool d = false; /* (d)igital */ + bool l = false; /* (l)cd */ + bool f = false; /* (f)ullscreen */ + bool b = false; /* (b)inary */ + + while(!done) + { + rb->lcd_clear_display(); + + rb->lcd_puts(0, 0, "MODE SELECTOR"); + rb->lcd_puts(2, 1, "Analog"); + rb->lcd_puts(2, 2, "Digital"); + rb->lcd_puts(2, 3, "LCD"); + rb->lcd_puts(2, 4, "Fullscreen"); + rb->lcd_puts(2, 5, "Binary"); + rb->lcd_puts(0, 6, "UP/DOWN: Choose"); + rb->lcd_puts(0, 7, "PLAY:Go|OFF:Cancel"); + + switch(settings.clock) + { + case 1: a=true; d=l=f=b=false; break; + case 2: d=true; a=l=f=b=false; break; + case 3: l=true; a=d=f=b=false; break; + case 4: f=true; a=d=l=b=false; break; + case 5: b=true; a=d=l=f=false; break; + } + + /* draw a checkbox next to current mode */ + rb->checkbox(1, 9, 8, 6, a); + rb->checkbox(1, 17, 8, 6, d); + rb->checkbox(1, 25, 8, 6, l); + rb->checkbox(1, 33, 8, 6, f); + rb->checkbox(1, 41, 8, 6, b); + + /* draw line selector */ + switch(cursorpos) + { + case 1: rb->lcd_invertrect(0, 8, 112, 8); break; + case 2: rb->lcd_invertrect(0, 16, 112, 8); break; + case 3: rb->lcd_invertrect(0, 24, 112, 8); break; + case 4: rb->lcd_invertrect(0, 32, 112, 8); break; + case 5: rb->lcd_invertrect(0, 40, 112, 8); break; + } + + rb->lcd_update(); + + switch(rb->button_get_w_tmo(HZ/4)) + { + case BUTTON_UP: + if(cursorpos > 1) + cursorpos--; + else + cursorpos = 5; + break; + + case BUTTON_DOWN: + if(cursorpos < 5) + cursorpos++; + else + cursorpos = 1; + break; + + case BUTTON_PLAY: + settings.clock = cursorpos; + done = true; + break; + + case BUTTON_OFF: + done = true; + break; + } } } -void load_settings(void) +void show_counter(void) { - int fd; - fd = rb->open(default_filename, O_RDONLY); - - /* if file exists, then load. */ - if(fd >= 0) + if(counting) { - rb->read (fd, &settings, sizeof(struct saved_settings)); - rb->close(fd); + passed_time = *rb->current_tick - start_tick; } - /* Else, loading failed */ else - { - rb->splash(HZ, true, "Setting load failed, using default settings."); - } + passed_time = 0; + + displayed_value = counter + passed_time; + displayed_value = displayed_value / HZ; + + count_s = displayed_value % 60; + count_m = displayed_value % 3600 / 60; + count_h = displayed_value / 3600; + + rb->snprintf(count_text, sizeof(count_text), "%d:%02d:%02d", count_h, count_m, count_s); + + if(settings.clock == 1) + rb->lcd_puts(11, 7, count_text); + else if(settings.clock == 2) + rb->lcd_putsxy(1, 5, count_text); + else if(settings.clock == 3) + rb->lcd_putsxy(1, 5, count_text); + else if(settings.clock == 4) + rb->lcd_puts(6, 6, count_text); } +/********************************************************************** + * Plugin starts here + **********************************************************************/ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { /* time ints */ @@ -94,6 +2074,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) int hour; int minute; int second; + int temphour; int last_second = -1; int pos = 0; @@ -102,65 +2083,65 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) int day; int month; - char moday[6]; - char dateyr[5]; - char tmhrmin[5]; - char tmsec[2]; - char current_date[12]; + /* poweroff activated or not? */ + bool reset_timer = false; struct tm* current_time; - bool exit = false; - bool used = false; - TEST_PLUGIN_API(api); (void)parameter; rb = api; - /* load settings from disk */ load_settings(); - rb->lcd_clear_display(); - rb->splash(HZ, true, "F1 for INFO"); + /* universal font */ + rb->lcd_setfont(FONT_SYSFIXED); + + /* set backlight timeout */ + rb->backlight_set_timeout(settings.backlight_on); while (!PLUGIN_OK) { - /* universal font for better display */ - rb->lcd_setfont(FONT_SYSFIXED); - - /* start all the clock stuff */ - - /* Time info */ + /********************* + * Time info + *********************/ current_time = rb->get_time(); hour = current_time->tm_hour; minute = current_time->tm_min; second = current_time->tm_sec; - /* Date info */ - year = current_time->tm_year+1900; + temphour = hour; + + /********************* + * Date info + *********************/ + year = current_time->tm_year + 1900; day = current_time->tm_mday; - month = current_time->tm_mon+1; + month = current_time->tm_mon + 1; + + done = false; if(second != last_second) { rb->lcd_clear_display(); - rb->snprintf( moday, 5, "%d/%d", month, day ); - rb->snprintf( dateyr, 4, "%d", year ); - rb->snprintf( tmhrmin, 5, "%02d:%02d", hour, minute ); - rb->snprintf( tmsec, 2, "%02d", second ); - rb->snprintf( current_date, 12, "%d/%d/%d", month, day, year ); + show_counter(); - if(settings.analog_clock) + /************** + * Analog Mode + **************/ + if(settings.clock == 1) { - /* Now draw the analog clock */ - pos = 90-second; - if(pos >= 60) - pos -= 60; - /* Second hand */ - rb->lcd_drawline((LCD_WIDTH/2), (LCD_HEIGHT/2), - xminute[pos], yminute[pos]); + if(settings.analog_secondhand) + { + pos = 90-second; + if(pos >= 60) + pos -= 60; + + rb->lcd_drawline((LCD_WIDTH/2), (LCD_HEIGHT/2), + xminute[pos], yminute[pos]); + } pos = 90-minute; if(pos >= 60) @@ -224,525 +2205,189 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)-3); rb->lcd_drawpixel(LCD_WIDTH/2, LCD_HEIGHT/2); - /* Draw the digits around the clock */ - if (settings.are_digits_displayed) - { - rb->lcd_putsxy((LCD_WIDTH/2)-6, 1, "12"); - rb->lcd_putsxy(20, (LCD_HEIGHT/2)-4, "9"); - rb->lcd_putsxy((LCD_WIDTH/2)-4, 56, "6"); - rb->lcd_putsxy(86, (LCD_HEIGHT/2)-4, "3"); - } - /* Draw digital readout */ - if (settings.is_time_displayed) - { - /* HH:MM */ - rb->lcd_putsxy(1, 4, tmhrmin); - /* SS */ - rb->lcd_putsxy(10, 12, tmsec); - } } - else + /*************** + * Digital mode + ***************/ + else if(settings.clock == 2) { - draw_7seg_time(hour, minute, 8, 16, 16, 32, second & 1); + if(settings.digital_blinkcolon) + draw_7seg_time(hour, minute, 8, 16, 16, 32, second & 1, false); + else + draw_7seg_time(hour, minute, 8, 16, 16, 32, true, false); } - - /* Draw the border */ - if (settings.is_rect_displayed) + /*********** + * LCD mode + ***********/ + else if(settings.clock == 3) { - rb->lcd_drawrect(0, 0, 112, 64); - - /* top left corner */ - rb->lcd_drawpixel(1, 1); - rb->lcd_drawpixel(2, 2); - rb->lcd_drawpixel(1, 2); - rb->lcd_drawpixel(1, 3); - rb->lcd_drawpixel(2, 1); - rb->lcd_drawpixel(3, 1); - - /* bottom left corner */ - rb->lcd_drawpixel(1, 62); - rb->lcd_drawpixel(2, 61); - rb->lcd_drawpixel(1, 61); - rb->lcd_drawpixel(1, 60); - rb->lcd_drawpixel(2, 62); - rb->lcd_drawpixel(3, 62); - - /* top right corner */ - rb->lcd_drawpixel(110, 1); - rb->lcd_drawpixel(109, 2); - rb->lcd_drawpixel(110, 2); - rb->lcd_drawpixel(110, 3); - rb->lcd_drawpixel(109, 1); - rb->lcd_drawpixel(108, 1); - - /* bottom right corner */ - rb->lcd_drawpixel(110, 62); - rb->lcd_drawpixel(109, 61); - rb->lcd_drawpixel(110, 61); - rb->lcd_drawpixel(110, 60); - rb->lcd_drawpixel(109, 62); - rb->lcd_drawpixel(108, 62); + if(settings.lcd_blinkcolon) + draw_7seg_time(hour, minute, 8, 16, 16, 32, second & 1, true); + else + draw_7seg_time(hour, minute, 8, 16, 16, 32, true, true); } - - /* Draw the date */ - if (settings.is_date_displayed) + /****************** + * Fullscreen mode + ******************/ + else if(settings.clock == 4) { - if(settings.analog_clock) + /* Second hand */ + if(settings.fullscreen_secondhand) { - rb->lcd_putsxy(3, 53, moday); - rb->lcd_putsxy(80, 53, dateyr); + pos = 90-second; + if(pos >= 60) + pos -= 60; + + rb->lcd_drawline((LCD_WIDTH/2), (LCD_HEIGHT/2), + xminute_full[pos], yminute_full[pos]); } - else - rb->lcd_putsxy(25, 3, current_date); - } - if (settings.is_time_displayed) + pos = 90-minute; + if(pos >= 60) + pos -= 60; + + /* Minute hand, thicker than the second hand */ + rb->lcd_drawline(LCD_WIDTH/2, LCD_HEIGHT/2, + xminute_full[pos], yminute_full[pos]); + rb->lcd_drawline(LCD_WIDTH/2-1, LCD_HEIGHT/2-1, + xminute_full[pos], yminute_full[pos]); + rb->lcd_drawline(LCD_WIDTH/2+1, LCD_HEIGHT/2+1, + xminute_full[pos], yminute_full[pos]); + rb->lcd_drawline(LCD_WIDTH/2-1, LCD_HEIGHT/2+1, + xminute_full[pos], yminute_full[pos]); + rb->lcd_drawline(LCD_WIDTH/2+1, LCD_HEIGHT/2-1, + xminute_full[pos], yminute_full[pos]); + + if(hour > 12) + hour -= 12; + + hour = hour*5 + minute/12; + pos = 90-hour; + if(pos >= 60) + pos -= 60; + + /* Hour hand, thick as the minute hand but shorter */ + rb->lcd_drawline(LCD_WIDTH/2, LCD_HEIGHT/2, xhour_full[pos], yhour_full[pos]); + rb->lcd_drawline(LCD_WIDTH/2-1, LCD_HEIGHT/2-1, + xhour_full[pos], yhour_full[pos]); + rb->lcd_drawline(LCD_WIDTH/2+1, LCD_HEIGHT/2+1, + xhour_full[pos], yhour_full[pos]); + rb->lcd_drawline(LCD_WIDTH/2-1, LCD_HEIGHT/2+1, + xhour_full[pos], yhour_full[pos]); + rb->lcd_drawline(LCD_WIDTH/2+1, LCD_HEIGHT/2-1, + xhour_full[pos], yhour_full[pos]); + + /* Draw the cover over the center */ + rb->lcd_drawline((LCD_WIDTH/2)-1, (LCD_HEIGHT/2)+3, + (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)+3); + rb->lcd_drawline((LCD_WIDTH/2)-3, (LCD_HEIGHT/2)+2, + (LCD_WIDTH/2)+3, (LCD_HEIGHT/2)+2); + rb->lcd_drawline((LCD_WIDTH/2)-4, (LCD_HEIGHT/2)+1, + (LCD_WIDTH/2)+4, (LCD_HEIGHT/2)+1); + rb->lcd_drawline((LCD_WIDTH/2)-4, LCD_HEIGHT/2, + (LCD_WIDTH/2)+4, LCD_HEIGHT/2); + rb->lcd_drawline((LCD_WIDTH/2)-4, (LCD_HEIGHT/2)-1, + (LCD_WIDTH/2)+4, (LCD_HEIGHT/2)-1); + rb->lcd_drawline((LCD_WIDTH/2)-3, (LCD_HEIGHT/2)-2, + (LCD_WIDTH/2)+3, (LCD_HEIGHT/2)-2); + rb->lcd_drawline((LCD_WIDTH/2)-1, (LCD_HEIGHT/2)-3, + (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)-3); + rb->lcd_drawpixel(LCD_WIDTH/2, LCD_HEIGHT/2); + } + /************** + * Binary mode + **************/ + else { - if(settings.analog_clock) - { - /* HH:MM */ - rb->lcd_putsxy(1, 4, tmhrmin); - /* SS */ - rb->lcd_putsxy(10, 12, tmsec); - } - else - { - /* Just seconds */ - rb->lcd_putsxy(50, 55, tmsec); - } + binary(hour, minute, second); } - - /* Draw all to LCD */ - rb->lcd_update(); } - switch (rb->button_get_w_tmo(HZ/6)) - { - /* OFF exits */ - case BUTTON_OFF: + if(settings.analog_time == 1 && temphour > 12) + temphour += 12; + + draw_extras(year, day, month, temphour, minute, second); - /* Tell the user what's going on */ - rb->lcd_clear_display(); - rb->splash(HZ/2, true, "Saving settings..."); - /* Save to disk */ - save_settings(); - rb->lcd_clear_display(); - rb->splash(HZ, true, "Saved!"); - /* ...and exit. */ + if(reset_timer) + rb->reset_poweroff_timer(); + + rb->lcd_update(); + + /************************** + * Scan for button presses + **************************/ + switch (rb->button_get_w_tmo(HZ/10)) + { + case BUTTON_OFF: /* save and exit */ + save_settings(); + rb->backlight_set_timeout(rb->global_settings->backlight_timeout); return PLUGIN_OK; break; - /* F1 & OFF exits without saving */ - case BUTTON_F1 | BUTTON_OFF: - return PLUGIN_OK; + case BUTTON_ON: /* credit roll */ + show_credits(); break; - /* F1 screen - plugin info */ - case BUTTON_F1: - while (!exit) + case BUTTON_F1: /* help */ + f1_screen(); + break; + + case BUTTON_F2: /* start/stop counter */ + if(settings.clock != 5) { - if(settings.analog_clock) + if(counting) { - rb->lcd_clear_display(); - rb->lcd_puts(0, 0, "F1 > Help"); - rb->lcd_puts(0, 1, "PLAY > Digital"); - rb->lcd_puts(0, 2, "FF > Show Time"); - rb->lcd_puts(0, 3, "DOWN > Border"); - rb->lcd_puts(0, 4, "REW > Digits"); - rb->lcd_puts(0, 5, "UP > Date"); - rb->lcd_puts(0, 6, "OFF > Save & Exit"); - rb->lcd_update(); + counting = false; + counter += passed_time; } else { - rb->lcd_clear_display(); - rb->lcd_puts(0, 0, "F1 > Help"); - rb->lcd_puts(0, 1, "PLAY > Analog"); - rb->lcd_puts(0, 3, "DOWN > Border"); - rb->lcd_puts(0, 4, "UP > Date"); - rb->lcd_puts(0, 5, "FF > Show Seconds"); - rb->lcd_puts(0, 7, "OFF > Save & Exit"); - rb->lcd_update(); - } - - switch (rb->button_get(true)) - { - case BUTTON_F1 | BUTTON_REL: - if (used) - exit = true; - used = true; - break; - - case BUTTON_OFF: - used = true; - break; - - case SYS_USB_CONNECTED: - return PLUGIN_USB_CONNECTED; - rb->usb_screen(); - break; + counting = true; + start_tick = *rb->current_tick; } } break; - /* options screen */ - case BUTTON_F3: - while (!exit) - { - if(settings.analog_clock) - { - rb->lcd_clear_display(); - rb->lcd_putsxy(7, 0, "FF > Show Time"); - rb->lcd_putsxy(7, 10, "DOWN> Show Frame"); - rb->lcd_putsxy(7, 20, "UP > Show Date"); - rb->lcd_putsxy(7, 30, "REW > Show Digits"); - - rb->lcd_putsxy(15, 46, "OFF > All OFF"); - rb->lcd_putsxy(17, 56, "ON > All ON"); - - rb->lcd_drawline(0, 41, 112, 41); - - /* draw checkmarks */ - if(settings.is_time_displayed) - { - rb->lcd_drawline(0, 4, 3, 7); - rb->lcd_drawline(3, 7, 5, 0); - } - if(settings.is_rect_displayed) - { - rb->lcd_drawline(0, 14, 3, 17); - rb->lcd_drawline(3, 17, 5, 10); - } - if(settings.is_date_displayed) - { - rb->lcd_drawline(0, 24, 3, 27); - rb->lcd_drawline(3, 27, 5, 20); - } - if(settings.are_digits_displayed) - { - rb->lcd_drawline(0, 34, 3, 37); - rb->lcd_drawline(3, 37, 5, 30); - } - - /* update the LCD after all this madness */ - rb->lcd_update(); - - /* ... and finally, setting options from screen: */ - switch (rb->button_get(true)) - { - case BUTTON_F3 | BUTTON_REL: - if (used) - exit = true; - used = true; - break; - - case BUTTON_RIGHT: - settings.is_time_displayed = - !settings.is_time_displayed; - break; - - case BUTTON_DOWN: - settings.is_rect_displayed = - !settings.is_rect_displayed; - break; - - case BUTTON_UP: - settings.is_date_displayed = - !settings.is_date_displayed; - break; - - case BUTTON_LEFT: - settings.are_digits_displayed = - !settings.are_digits_displayed; - break; - - case BUTTON_ON: - settings.is_time_displayed = true; - settings.is_rect_displayed = true; - settings.is_date_displayed = true; - settings.are_digits_displayed = true; - break; - - case BUTTON_OFF: - settings.is_time_displayed = false; - settings.is_rect_displayed = false; - settings.is_date_displayed = false; - settings.are_digits_displayed = false; - break; - - case SYS_USB_CONNECTED: - return PLUGIN_USB_CONNECTED; - rb->usb_screen(); - break; - } - } - else /* 7-Segment clock shown, less options */ - { - rb->lcd_clear_display(); - rb->lcd_putsxy(7, 0, "DOWN> Show Frame"); - rb->lcd_putsxy(7, 10, "UP > Show Date"); - rb->lcd_putsxy(7, 20, "FF > Seconds"); - rb->lcd_putsxy(15, 46, "OFF > All OFF"); - rb->lcd_putsxy(17, 56, "ON > All ON"); - rb->lcd_drawline(0, 41, 112, 41); - - /* draw checkmarks */ - if(settings.is_rect_displayed) - { - rb->lcd_drawline(0, 4, 3, 7); - rb->lcd_drawline(3, 7, 5, 0); - } - if(settings.is_date_displayed) - { - rb->lcd_drawline(0, 14, 3, 17); - rb->lcd_drawline(3, 17, 5, 10); - } - if(settings.is_time_displayed) - { - rb->lcd_drawline(0, 24, 3, 27); - rb->lcd_drawline(3, 27, 5, 20); - } - - /* And finally, update the LCD */ - rb->lcd_update(); - - switch (rb->button_get(true)) - { - case BUTTON_F3 | BUTTON_REL: - if (used) - exit = true; - used = true; - break; - - case BUTTON_DOWN: - settings.is_rect_displayed = - !settings.is_rect_displayed; - break; - - case BUTTON_UP: - settings.is_date_displayed = - !settings.is_date_displayed; - break; - - case BUTTON_RIGHT: - settings.is_time_displayed = - !settings.is_time_displayed; - break; - - case BUTTON_ON: - settings.is_time_displayed = true; - settings.is_rect_displayed = true; - settings.is_date_displayed = true; - break; - - case BUTTON_OFF: - settings.is_time_displayed = false; - settings.is_rect_displayed = false; - settings.is_date_displayed = false; - break; - - case SYS_USB_CONNECTED: - return PLUGIN_USB_CONNECTED; - rb->usb_screen(); - break; - } - } - } + case BUTTON_F2 | BUTTON_REPEAT: /* reset counter */ + counter = 0; break; - /* Toggle analog/digital */ - case BUTTON_PLAY: - settings.analog_clock = !settings.analog_clock; + case BUTTON_F3: /* options */ + f3_screen(); break; - /* Show time */ - case BUTTON_RIGHT: - settings.is_time_displayed = !settings.is_time_displayed; + case BUTTON_UP: /* enable idle poweroff */ + reset_timer = false; + rb->splash(HZ*2, true, "Idle Poweroff ENABLED"); break; - /* Show border */ - case BUTTON_DOWN: - settings.is_rect_displayed = !settings.is_rect_displayed ; + case BUTTON_DOWN: /* disable idle poweroff */ + reset_timer = true; + rb->splash(HZ*2, true, "Idle Poweroff DISABLED"); break; - /* Show date */ - case BUTTON_UP: - settings.is_date_displayed = !settings.is_date_displayed; + case BUTTON_LEFT: /* backlight off */ + settings.backlight_on = false; + rb->splash(HZ, true, "Backlight OFF"); + rb->backlight_set_timeout(settings.backlight_on); break; - /* Show digits */ - case BUTTON_LEFT: - settings.are_digits_displayed = !settings.are_digits_displayed; + case BUTTON_RIGHT: /* backlight on */ + settings.backlight_on = true; + rb->splash(HZ, true, "Backlight ON"); + rb->backlight_set_timeout(settings.backlight_on); break; - /* USB plugged? */ - case SYS_USB_CONNECTED: + case BUTTON_PLAY: /* select a mode */ + select_mode(); + break; + + case SYS_USB_CONNECTED: /* usb plugged? */ rb->usb_screen(); return PLUGIN_USB_CONNECTED; break; } } } - -/* 7 Segment LED imitation code by Linus Nielsen Feltzing */ - -/* - a 0 b - ######### - # # - # # - 1# #2 - # # - # 3 # - c ######### d - # # - # # - 4# #5 - # # - # 6 # - e ######### f -*/ - -/* The coordinates of each end point (a-f) of the segment lines (0-6) */ -static unsigned int point_coords[6][2] = -{ - {0, 0}, /* a */ - {1, 0}, /* b */ - {0, 1}, /* c */ - {1, 1}, /* d */ - {0, 2}, /* e */ - {1, 2} /* f */ -}; - -/* The end points (a-f) for each segment line */ -static unsigned int seg_points[7][2] = -{ - {0,1}, /* a to b */ - {0,2}, /* a to c */ - {1,3}, /* b to d */ - {2,3}, /* c to d */ - {2,4}, /* c to e */ - {3,5}, /* d to f */ - {4,5} /* e to f */ -}; - -/* Lists that tell which segments (0-6) to enable for each digit (0-9), - the list is terminated with -1 */ -static int digit_segs[10][8] = -{ - {0,1,2,4,5,6, -1}, /* 0 */ - {2,5, -1}, /* 1 */ - {0,2,3,4,6, -1}, /* 2 */ - {0,2,3,5,6, -1}, /* 3 */ - {1,2,3,5, -1}, /* 4 */ - {0,1,3,5,6, -1}, /* 5 */ - {0,1,3,4,5,6, -1}, /* 6 */ - {0,2,5, -1}, /* 7 */ - {0,1,2,3,4,5,6, -1}, /* 8 */ - {0,1,2,3,5,6, -1} /* 9 */ -}; - -/* Draws one segment */ -void draw_seg(int seg, int x, int y, int width, int height) -{ - int p1 = seg_points[seg][0]; - int p2 = seg_points[seg][1]; - int x1 = point_coords[p1][0]; - int y1 = point_coords[p1][1]; - int x2 = point_coords[p2][0]; - int y2 = point_coords[p2][1]; - - /* It draws parallel lines of different lengths for thicker segments */ - if(seg == 0 || seg == 3 || seg == 6) - { - rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2, - x + x2 * width - 1 , y + y2 * height / 2); - - rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 - 1, - x + x2 * width - 2, y + y2 * height / 2 - 1); - rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 1, - x + x2 * width - 2, y + y2 * height / 2 + 1); - - rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 - 2, - x + x2 * width - 3, y + y2 * height / 2 - 2); - rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 + 2, - x + x2 * width - 3, y + y2 * height / 2 + 2); - } - else - { - rb->lcd_drawline(x + x1 * width, y + y1 * height / 2 + 1, - x + x2 * width , y + y2 * height / 2 - 1); - - rb->lcd_drawline(x + x1 * width - 1, y + y1 * height / 2 + 2, - x + x2 * width - 1, y + y2 * height / 2 - 2); - rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2 + 2, - x + x2 * width + 1, y + y2 * height / 2 - 2); - - rb->lcd_drawline(x + x1 * width - 2, y + y1 * height / 2 + 3, - x + x2 * width - 2, y + y2 * height / 2 - 3); - - rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 3, - x + x2 * width + 2, y + y2 * height / 2 - 3); - } -} - -/* Draws one digit */ -void draw_7seg_digit(int digit, int x, int y, int width, int height) -{ - int i; - int c; - - for(i = 0;digit_segs[digit][i] >= 0;i++) - { - c = digit_segs[digit][i]; - - draw_seg(c, x, y, width, height); - } -} - -/* Draws the entire 7-segment hour-minute time display */ -void draw_7seg_time(int hour, int minute, int x, int y, int width, int height, -bool colon) -{ - int xpos = x; - - draw_7seg_digit(hour / 10, xpos, y, width, height); - xpos += width + 6; - draw_7seg_digit(hour % 10, xpos, y, width, height); - xpos += width + 6; - - if(colon) - { - rb->lcd_drawline(xpos, y + height/3 + 2, - xpos, y + height/3 + 2); - rb->lcd_drawline(xpos+1, y + height/3 + 1, - xpos+1, y + height/3 + 3); - rb->lcd_drawline(xpos+2, y + height/3, - xpos+2, y + height/3 + 4); - rb->lcd_drawline(xpos+3, y + height/3 + 1, - xpos+3, y + height/3 + 3); - rb->lcd_drawline(xpos+4, y + height/3 + 2, - xpos+4, y + height/3 + 2); - - rb->lcd_drawline(xpos, y + height-height/3 + 2, - xpos, y + height-height/3 + 2); - rb->lcd_drawline(xpos+1, y + height-height/3 + 1, - xpos+1, y + height-height/3 + 3); - rb->lcd_drawline(xpos+2, y + height-height/3, - xpos+2, y + height-height/3 + 4); - rb->lcd_drawline(xpos+3, y + height-height/3 + 1, - xpos+3, y + height-height/3 + 3); - rb->lcd_drawline(xpos+4, y + height-height/3 + 2, - xpos+4, y + height-height/3 + 2); - } - - xpos += 12; - - draw_7seg_digit(minute / 10, xpos, y, width, height); - xpos += width + 6; - draw_7seg_digit(minute % 10, xpos, y, width, height); - xpos += width + 6; -} - #endif -- cgit v1.2.3