Index: apps/recorder/bmp.c =================================================================== --- apps/recorder/bmp.c (revision 22166) +++ apps/recorder/bmp.c (working copy) @@ -459,7 +459,7 @@ int padded_width; int read_width; int depth, numcolors, compression, totalsize; - int ret; + off_t ret, fstart; bool return_size = format & FORMAT_RETURN_SIZE; unsigned char *bitmap = bm->data; @@ -502,6 +502,7 @@ dither = true; } #endif + fstart = lseek(fd, 0, SEEK_CUR); /* read fileheader */ ret = read(fd, &bmph, sizeof(struct bmp_header)); if (ret < 0) { @@ -683,7 +684,7 @@ } /* Search to the beginning of the image data */ - lseek(fd, (off_t)letoh32(bmph.off_bits), SEEK_SET); + lseek(fd, (off_t)letoh32(bmph.off_bits) + fstart, SEEK_SET); memset(bitmap, 0, totalsize); Index: apps/plugins/CATEGORIES =================================================================== --- apps/plugins/CATEGORIES (revision 22166) +++ apps/plugins/CATEGORIES (working copy) @@ -49,6 +49,7 @@ midi2wav,viewers midi,viewers minesweeper,games +moonrock,apps mosaique,demos mp3_encoder,apps mpegplayer,viewers Index: apps/plugins/SOURCES =================================================================== --- apps/plugins/SOURCES (revision 22166) +++ apps/plugins/SOURCES (working copy) @@ -92,6 +92,7 @@ wormlet.c #if CONFIG_RTC +moonrock.c calendar.c #endif /* CONFIG_RTC */ Index: apps/plugins/moonrock.c =================================================================== --- apps/plugins/moonrock.c (revision 0) +++ apps/plugins/moonrock.c (revision 0) @@ -0,0 +1,437 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Federico Pelupessy + * Moon picture from Wikipedia, public domain, + * (original upload 5 November 2007 by Tomruen) + * moon phase code based on moontool.c by John Walker + * + * 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 "math.h" +#include +#include "string.h" +#include "bmp.h" + +#include "lib/pluginlib_actions.h" +#include "lib/fixedpoint.h" +#include "lib/feature_wrappers.h" + +#define PICSIZE MIN(LCD_WIDTH,LCD_HEIGHT) +#define BMPSKIP 58678 + +PLUGIN_HEADER + +const struct button_mapping* plugin_contexts[]={generic_actions}; + +#define QUIT_ACTION PLA_QUIT +#define DATE_ACTION PLA_START +#define TOGGLE_VIEW_ACTION PLA_FIRE + +#if defined(HAVE_LCD_BITMAP) && LCD_DEPTH>1 +static fb_data bmp_buf[240*240]; +#endif + +int get_frame_no(double phase) +{ + static const int nframe=59; + static const double frame_phase[]={ + -0.00610101, 0.009140, 0.024328, 0.039472, 0.054583, 0.069671, 0.084748, + 0.099827, 0.114924, 0.130053, 0.145234, 0.160486, 0.175832, 0.191294, + 0.206898, 0.222671, 0.238641, 0.254835, 0.271280, 0.288003, 0.305025, + 0.322366, 0.340040, 0.358052, 0.376402, 0.395078, 0.414059, 0.433312, + 0.452797, 0.472463, 0.492251, 0.512099, 0.531941, 0.551713, 0.571354, + 0.590809, 0.610032, 0.628986, 0.647642, 0.665986, 0.684008, 0.701710, + 0.719100, 0.736192, 0.753004, 0.769556, 0.785873, 0.801977, 0.817892, + 0.833641, 0.849246, 0.864728, 0.880106, 0.895399, 0.910622, 0.925790, + 0.940917, 0.956015, 0.971095, 0.993899 + }; + int i; + + if(phase<0) phase=0.; + if(phase>1) phase=1.; + + if(phase>=frame_phase[nframe]) phase=phase-1.; + + i=0; + while(phase>frame_phase[i+1]) + { + i++; + } + if( (phase-frame_phase[i]) < (frame_phase[i+1]-phase) ) return i; + return (i+1)%59; +} + +/* Astronomical constants */ +#define EPOCH 2444238.5 /* 1980 January 0.0 */ + +/* Constants defining the Sun's apparent orbit */ + +#define ELONGE 278.833540 /* Ecliptic longitude of the Sun at epoch 1980.0 */ +#define ELONGP 282.596403 /* Ecliptic longitude of the Sun at perigee */ +#define ECCENT 0.016718 /* Eccentricity of Earth's orbit */ +#define SUNSMAX 1.495985e8 /* Semi-major axis of Earth's orbit, km */ +#define SUNANGSIZ 0.533128 /* Sun's angular size, degrees, at + semi-major axis distance */ +/* Elements of the Moon's orbit, epoch 1980.0 */ +#define MMLONG 64.975464 /* Moon's mean longitude at the epoch */ +#define MMLONGP 349.383063 /* Mean longitude of the perigee at the epoch */ +#define MLNODE 151.950429 /* Mean longitude of the node at the epoch */ +#define MINC 5.145396 /* Inclination of the Moon's orbit */ +#define MECC 0.054900 /* Eccentricity of the Moon's orbit */ +#define MANGSIZ 0.5181 /* Moon's angular size at distance a + from Earth */ +#define MSMAX 384401.0 /* Semi-major axis of Moon's orbit in km */ +#define MPARALLAX 0.9507 /* Parallax at distance a from Earth */ +#define SYNMONTH 29.53058868 /* Synodic month (new Moon to new Moon) */ +#define LUNATBASE 2423436.0 /* Base date for E. W. Brown's numbered + series of lunations (1923 January 16) */ + +/* Properties of the Earth */ + +#define EARTHRAD 6378.16 /* Radius of Earth in kilometres */ + +/* Handy mathematical functions */ + +#define PI 3.14159265358979323846 + +#define SGN(x) (((x) < 0) ? -1 : ((x) > 0 ? 1 : 0)) /* Extract sign */ +//#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /* Absolute val */ +#define FIXANGLE(a) ((a) < 0 ? 360.*((a)/360.-(long)((a)/360.)+1) : 360.*((a)/360.-(long)((a)/360.))) + /* angle to 0-30 */ +#define FIXRANGLE(a) ((a) < 0 ? 2*PI*((a)/2/PI-(long)((a)/2/PI)+1) : 2*PI*((a)/2/PI-(long)((a)/2/PI))) + /* angle to 0-2PI */ +#define TORAD(d) ((d) * (PI / 180.0)) /* Deg->Rad */ +#define TODEG(d) ((d) * (180.0 / PI)) /* Rad->Deg */ + +double sin(double x) +{ + long s,c; + unsigned long xx; + xx=0xffffffff*(FIXRANGLE(x)/(2*PI)); + s=fp_sincos(xx,&c); + return s*1.0/LONG_MAX; +} + +double cos(double x) +{ + long s,c; + unsigned long xx; + xx=0xffffffff*(FIXRANGLE(x)/(2*PI)); + s=fp_sincos(xx,&c); + return c*1.0/LONG_MAX; +} + +#define dsin(x) (sin(TORAD((x)))) /* Sin from deg */ +#define dcos(x) (cos(TORAD((x)))) /* Cos from deg */ + +/* JDATE -- Convert (GMT) date and time to Julian day and fraction. */ +long jdate(struct tm *t) +{ + long c, m, y; + + y = t->tm_year + 1900; + m = t->tm_mon + 1; + if (m > 2) { + m = m - 3; + } else { + m = m + 9; + y--; + } + c = y / 100L; /* Compute century */ + y -= 100L * c; + return (t->tm_mday + (c * 146097L) / 4 + (y * 1461L) / 4 + + (m * 153L + 2) / 5 + 1721119L); +} + +/* JTIME -- Convert (GMT) date and time to astronomical + Julian time (i.e. Julian date plus day fraction, + expressed as a double). */ +double jtime(struct tm *t) +{ + return (jdate(t) - 0.5) + + (t->tm_sec + 60L * (t->tm_min + 60L * t->tm_hour)) / 86400.0; +} + +/* PHASE -- Calculate phase of moon as a fraction: + The argument is the time for which the phase is + requested, expressed as a Julian date and fraction. Returns the terminator + phase angle as a percentage of a full circle (i.e., 0 to 1), and + stores into pointer arguments the illuminated fraction of the + Moon's disc, the Moon's age in days and fraction, the distance + of the Moon from the centre of the Earth, and the angular + diameter subtended by the Moon as seen by an observer at the centre of + the Earth. +*/ + +double moon_phase( + double pdate, /* Date for which to calculate phase */ + double *pphase, /* Illuminated fraction */ + double *mage, /* Age of moon in days */ + double *dist, /* Distance in kilometres */ + double *angdia, /* Angular diameter in degrees */ + double *sudist, /* Distance to Sun */ + double *suangdia) /* Sun's angular diameter */ +{ + double Day, N, M, Ec, Lambdasun, ml, MM, /* MN,*/ Ev, Ae, A3, MmP, + mEc, A4, lP, V, lPP, + /* NP, y, x, Lambdamoon, BetaM, */ + MoonAge, MoonPhase, + MoonDist, MoonDFrac, MoonAng, + /* MoonPar,*/ + F, SunDist, SunAng,Mrad; + + /* Calculation of the Sun's position */ + + Day = pdate - EPOCH; /* Date within epoch */ + N = FIXANGLE((360 / 365.2422) * Day); /* Mean anomaly of the Sun */ + M = FIXANGLE(N + ELONGE - ELONGP); /* Convert from perigee + co-ordinates to epoch 1980.0 */ + Mrad=TORAD(M); + Ec = Mrad+2*ECCENT*sin(Mrad)+ + 1.25*ECCENT*ECCENT*sin(2*Mrad)+ + ECCENT*ECCENT*ECCENT*sin(3*Mrad); /* gives true anomaly accurate to ~arcsec + (compared to usual formula, that is) */ + /* if(Mrad > PI) Ec=Ec-2*PI; */ + Ec = TODEG(Ec); + + Lambdasun = FIXANGLE(Ec + ELONGP); /* Sun's geocentric ecliptic + longitude */ + /* Orbital distance factor */ + F = (1 + ECCENT * dcos(Ec)) / (1 - ECCENT * ECCENT); + SunDist = SUNSMAX / F; /* Distance to Sun in km */ + SunAng = F * SUNANGSIZ; /* Sun's angular size in degrees */ + + /* Calculation of the Moon's position */ + + /* Moon's mean longitude */ + ml = FIXANGLE(13.1763966 * Day + MMLONG); + + /* Moon's mean anomaly */ + MM = FIXANGLE(ml - 0.1114041 * Day - MMLONGP); + + /* Moon's ascending node mean longitude */ + /* MN = FIXANGLE(MLNODE - 0.0529539 * Day); */ + + /* Evection */ + Ev = 1.2739 * dsin(2 * (ml - Lambdasun) - MM); + + /* Annual equation */ + Ae = 0.1858 * dsin(M); + + /* Correction term */ + A3 = 0.37 * dsin(M); + + /* Corrected anomaly */ + MmP = MM + Ev - Ae - A3; + + /* Correction for the equation of the centre */ + mEc = 6.2886 * dsin(MmP); + + /* Another correction term */ + A4 = 0.214 * dsin(2 * MmP); + + /* Corrected longitude */ + lP = ml + Ev + mEc - Ae + A4; + + /* Variation */ + V = 0.6583 * dsin(2 * (lP - Lambdasun)); + + /* True longitude */ + lPP = lP + V; + + /* Corrected longitude of the node */ + /* NP = MN - 0.16 * dsin(M); */ + + /* Y inclination coordinate */ + /* y = dsin(lPP - NP) * dcos(MINC); */ + + /* X inclination coordinate */ + /* x = dcos(lPP - NP); */ + + /* Ecliptic longitude */ + /* Lambdamoon = TODEG(atan2(y, x)); */ + /* Lambdamoon += NP; */ + + /* Ecliptic latitude */ + /* BetaM = TODEG(asin(sin(TORAD(lPP - NP)) * sin(TORAD(MINC)))); */ + + /* Calculation of the phase of the Moon */ + + /* Age of the Moon in degrees */ + MoonAge = lPP - Lambdasun; + + /* Phase of the Moon */ + MoonPhase = (1 - dcos(MoonAge)) / 2; + + /* Calculate distance of moon from the centre of the Earth */ + + MoonDist = (MSMAX * (1 - MECC * MECC)) / + (1 + MECC * dcos(MmP + mEc)); + + /* Calculate Moon's angular diameter */ + + MoonDFrac = MoonDist / MSMAX; + MoonAng = MANGSIZ / MoonDFrac; + + /* Calculate Moon's parallax */ + /* MoonPar = MPARALLAX / MoonDFrac; */ + + *pphase = MoonPhase; + *mage = SYNMONTH * (FIXANGLE(MoonAge) / 360.0); + *dist = MoonDist; + *angdia = MoonAng; + *sudist = SunDist; + *suangdia = SunAng; + return FIXANGLE(MoonAge) / 360.0; +} + +/* this is the plugin entry point */ +enum plugin_status plugin_start(const void* parameter) +{ + (void)parameter; + struct tm tm,tm1; + int font_w,font_h,iphase,action; + double phase,jd,cphase, aom, cdist, cangdia, csund, csuang; + bool viewbmp=true; + bool refresh=true; + bool done=false; + bool getaction; +#if defined(HAVE_LCD_BITMAP) && LCD_DEPTH>1 + int ret,fd; + static struct bitmap input_bmp; +#endif + char output[20]; + static const char *desc[] = { + "new moon", "waxing crescent", + "first quarter","waxing gibbous", + "full moon","waning gibbous","last quarter", + "waning crescent" + }; + + rb->memcpy( &tm, rb->get_time(), sizeof(struct tm)); + +#if defined(HAVE_LCD_BITMAP) && LCD_DEPTH>1 + input_bmp.width = PICSIZE; + input_bmp.height = PICSIZE; + input_bmp.format = FORMAT_NATIVE; + input_bmp.data = (char*)bmp_buf; + fd=rb->open(PLUGIN_APPS_DIR "/moonrock.dat", O_RDONLY); +#endif + + + while(!done) + { +#if LCD_DEPTH>=2 + rb->lcd_set_backdrop(NULL); + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->lcd_clear_display(); + + jd=jtime(&tm); + phase=moon_phase(jd, &cphase, &aom, &cdist, &cangdia, &csund, &csuang); + + /* it is too ugly on monochrome... */ +#if defined(HAVE_LCD_BITMAP) && LCD_DEPTH>1 + if(fd>=0 && viewbmp) + { + rb->lcd_getstringsize( (unsigned char *) "Calculating..", &font_w, &font_h); + rb->lcd_putsxy((LCD_WIDTH/2) - (font_w)/2, LCD_HEIGHT/2-font_h/2, + (unsigned char *) "Calculating.."); + rb->lcd_update(); + + if(refresh) + { + iphase=get_frame_no(phase); + rb->lseek(fd, (off_t) (iphase*BMPSKIP),SEEK_SET); + ret = scaled_read_bmp_fd(fd, &input_bmp, sizeof(bmp_buf), + FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT, + NULL); + + if (ret < 0) + { + rb->splash(HZ, "Could not read bmp"); + return PLUGIN_ERROR; + } + + refresh=false; + } + + rb->lcd_bitmap(bmp_buf, + MAX(0,(LCD_WIDTH-input_bmp.width)/2), + MAX(0,(LCD_HEIGHT-input_bmp.height)/2), + input_bmp.width,input_bmp.height); + + } else +#endif + { + rb->lcd_clear_display(); + iphase=8*phase+0.5; + iphase=iphase%8; + rb->snprintf(output,sizeof(output),"%s", desc[iphase]); + + rb->lcd_getstringsize(output, &font_w, &font_h); + rb->lcd_putsxy((LCD_WIDTH/2) - (font_w)/2, LCD_HEIGHT/2-font_h, + (unsigned char *) output); + + rb->snprintf(output,sizeof(output),"(%d%% illuminated)", + (int)(cphase*100+0.5)); + + rb->lcd_getstringsize(output, &font_w, &font_h); + rb->lcd_putsxy((LCD_WIDTH/2) - (font_w)/2, LCD_HEIGHT/2+1, + (unsigned char *) output); + } + + rb->lcd_update(); + + getaction = false; + while(!getaction) { + action = pluginlib_getaction(TIMEOUT_BLOCK, plugin_contexts, 1); + switch(action) + { + case QUIT_ACTION: + done=true; + getaction = true; + break; + case TOGGLE_VIEW_ACTION: + viewbmp=!viewbmp; + getaction = true; + break; + case DATE_ACTION: + rb->memcpy( &tm1, &tm, sizeof(struct tm)); + rb->set_time_screen((char*) "Moonrock date/time (GMT)" ,&tm1); + if(tm1.tm_year != -1) + { + rb->memcpy( &tm, &tm1, sizeof(struct tm)); + refresh=true; + } + getaction=true; + break; + default: + break; + } + } + } + +#if defined(HAVE_LCD_BITMAP) && LCD_DEPTH>1 + if(fd>0) rb->close(fd); +#endif + + return PLUGIN_OK; +} Index: apps/plugin.c =================================================================== --- apps/plugin.c (revision 22166) +++ apps/plugin.c (working copy) @@ -564,6 +564,7 @@ set_time, #if CONFIG_RTC mktime, + set_time_screen, #endif plugin_get_buffer, plugin_get_audio_buffer, Index: apps/plugin.h =================================================================== --- apps/plugin.h (revision 22166) +++ apps/plugin.h (working copy) @@ -105,6 +105,8 @@ #include "yesno.h" +#include "screens.h" + #if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID) #include "usbstack/usb_hid_usage_tables.h" #endif @@ -712,6 +714,7 @@ int (*set_time)(const struct tm *tm); #if CONFIG_RTC time_t (*mktime)(struct tm *t); + bool (*set_time_screen)(const char* title, struct tm *tm); #endif void* (*plugin_get_buffer)(size_t *buffer_size); void* (*plugin_get_audio_buffer)(size_t *buffer_size);