summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/misc.c330
-rw-r--r--apps/misc.h50
-rw-r--r--apps/plugin.h1
-rw-r--r--apps/plugins/lib/grey_core.c5
-rw-r--r--apps/recorder/radio.c1
-rw-r--r--apps/recorder/recording.c1
-rw-r--r--apps/settings.c1
-rw-r--r--firmware/SOURCES5
-rw-r--r--firmware/backlight.c10
-rw-r--r--firmware/export/general.h35
-rw-r--r--firmware/general.c117
-rw-r--r--firmware/usb.c11
-rw-r--r--uisimulator/sdl/lcd-bitmap.c8
-rw-r--r--uisimulator/sdl/lcd-charcells.c3
-rw-r--r--uisimulator/sdl/lcd-remote-bitmap.c12
15 files changed, 181 insertions, 409 deletions
diff --git a/apps/misc.c b/apps/misc.c
index b1d795708c..872d91592d 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -135,109 +135,6 @@ char *output_dyn_value(char *buf, int buf_size, int value,
return buf;
}
-/* Create a filename with a number part in a way that the number is 1
- * higher than the highest numbered file matching the same pattern.
- * It is allowed that buffer and path point to the same memory location,
- * saving a strcpy(). Path must always be given without trailing slash.
- * "num" can point to an int specifying the number to use or NULL or a value
- * less than zero to number automatically. The final number used will also
- * be returned in *num. If *num is >= 0 then *num will be incremented by
- * one. */
-char *create_numbered_filename(char *buffer, const char *path,
- const char *prefix, const char *suffix,
- int numberlen IF_CNFN_NUM_(, int *num))
-{
- DIR *dir;
- struct dirent *entry;
- int max_num;
- int pathlen;
- int prefixlen = strlen(prefix);
- char fmtstring[12];
-
- if (buffer != path)
- strncpy(buffer, path, MAX_PATH);
-
- pathlen = strlen(buffer);
-
-#ifdef IF_CNFN_NUM
- if (num && *num >= 0)
- {
- /* number specified */
- max_num = *num;
- }
- else
-#endif
- {
- /* automatic numbering */
- max_num = 0;
-
- dir = opendir(pathlen ? buffer : "/");
- if (!dir)
- return NULL;
-
- while ((entry = readdir(dir)))
- {
- int curr_num;
-
- if (strncasecmp((char *)entry->d_name, prefix, prefixlen)
- || strcasecmp((char *)entry->d_name + prefixlen + numberlen, suffix))
- continue;
-
- curr_num = atoi((char *)entry->d_name + prefixlen);
- if (curr_num > max_num)
- max_num = curr_num;
- }
-
- closedir(dir);
- }
-
- max_num++;
-
- snprintf(fmtstring, sizeof(fmtstring), "/%%s%%0%dd%%s", numberlen);
- snprintf(buffer + pathlen, MAX_PATH - pathlen, fmtstring, prefix,
- max_num, suffix);
-
-#ifdef IF_CNFN_NUM
- if (num)
- *num = max_num;
-#endif
-
- return buffer;
-}
-
-
-#if CONFIG_RTC
-/* Create a filename with a date+time part.
- It is allowed that buffer and path point to the same memory location,
- saving a strcpy(). Path must always be given without trailing slash.
- unique_time as true makes the function wait until the current time has
- changed. */
-char *create_datetime_filename(char *buffer, const char *path,
- const char *prefix, const char *suffix,
- bool unique_time)
-{
- struct tm *tm = get_time();
- static struct tm last_tm;
- int pathlen;
-
- while (unique_time && !memcmp(get_time(), &last_tm, sizeof (struct tm)))
- sleep(HZ/10);
-
- last_tm = *tm;
-
- if (buffer != path)
- strncpy(buffer, path, MAX_PATH);
-
- pathlen = strlen(buffer);
- snprintf(buffer + pathlen, MAX_PATH - pathlen,
- "/%s%02d%02d%02d-%02d%02d%02d%s", prefix,
- tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec, suffix);
-
- return buffer;
-}
-#endif /* CONFIG_RTC */
-
/* Ask the user if they really want to erase the current dynamic playlist
* returns true if the playlist should be replaced */
bool warn_on_pl_erase(void)
@@ -339,233 +236,6 @@ int fast_readline(int fd, char *buf, int buf_size, void *parameters,
return 0;
}
-#ifdef HAVE_LCD_BITMAP
-
-#if LCD_DEPTH == 16
-#define BMP_COMPRESSION 3 /* BI_BITFIELDS */
-#define BMP_NUMCOLORS 3
-#else /* LCD_DEPTH != 16 */
-#define BMP_COMPRESSION 0 /* BI_RGB */
-#if LCD_DEPTH <= 8
-#ifdef HAVE_LCD_SPLIT
-#define BMP_NUMCOLORS (2 << LCD_DEPTH)
-#else
-#define BMP_NUMCOLORS (1 << LCD_DEPTH)
-#endif
-#else /* LCD_DEPTH > 8 */
-#define BMP_NUMCOLORS 0
-#endif /* LCD_DEPTH > 8 */
-#endif /* LCD_DEPTH != 16 */
-
-#if LCD_DEPTH <= 4
-#define BMP_BPP 4
-#define BMP_LINESIZE ((LCD_WIDTH/2 + 3) & ~3)
-#elif LCD_DEPTH <= 8
-#define BMP_BPP 8
-#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3)
-#elif LCD_DEPTH <= 16
-#define BMP_BPP 16
-#define BMP_LINESIZE ((LCD_WIDTH*2 + 3) & ~3)
-#else
-#define BMP_BPP 24
-#define BMP_LINESIZE ((LCD_WIDTH*3 + 3) & ~3)
-#endif
-
-#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS)
-#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT)
-#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE)
-
-#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff
-#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff
-
-static const unsigned char bmpheader[] =
-{
- 0x42, 0x4d, /* 'BM' */
- LE32_CONST(BMP_TOTALSIZE), /* Total file size */
- 0x00, 0x00, 0x00, 0x00, /* Reserved */
- LE32_CONST(BMP_HEADERSIZE), /* Offset to start of pixel data */
-
- 0x28, 0x00, 0x00, 0x00, /* Size of (2nd) header */
- LE32_CONST(LCD_WIDTH), /* Width in pixels */
- LE32_CONST(LCD_HEIGHT+LCD_SPLIT_LINES), /* Height in pixels */
- 0x01, 0x00, /* Number of planes (always 1) */
- LE16_CONST(BMP_BPP), /* Bits per pixel 1/4/8/16/24 */
- LE32_CONST(BMP_COMPRESSION),/* Compression mode */
- LE32_CONST(BMP_DATASIZE), /* Size of bitmap data */
- 0xc4, 0x0e, 0x00, 0x00, /* Horizontal resolution (pixels/meter) */
- 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */
- LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */
- LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */
-
-#if LCD_DEPTH == 1
-#ifdef HAVE_NEGATIVE_LCD
- BMP_COLOR(LCD_BL_DARKCOLOR),
- BMP_COLOR(LCD_BL_BRIGHTCOLOR),
-#ifdef HAVE_LCD_SPLIT
- BMP_COLOR(LCD_BL_DARKCOLOR_2),
- BMP_COLOR(LCD_BL_BRIGHTCOLOR_2),
-#endif
-#else /* positive display */
- BMP_COLOR(LCD_BL_BRIGHTCOLOR),
- BMP_COLOR(LCD_BL_DARKCOLOR),
-#endif /* positive display */
-#elif LCD_DEPTH == 2
- BMP_COLOR(LCD_BL_BRIGHTCOLOR),
- BMP_COLOR_MIX(LCD_BL_BRIGHTCOLOR, LCD_BL_DARKCOLOR, 1, 3),
- BMP_COLOR_MIX(LCD_BL_BRIGHTCOLOR, LCD_BL_DARKCOLOR, 2, 3),
- BMP_COLOR(LCD_BL_DARKCOLOR),
-#elif LCD_DEPTH == 16
- 0x00, 0xf8, 0x00, 0x00, /* red bitfield mask */
- 0xe0, 0x07, 0x00, 0x00, /* green bitfield mask */
- 0x1f, 0x00, 0x00, 0x00, /* blue bitfield mask */
-#endif
-};
-
-static void (*screen_dump_hook)(int fh) = NULL;
-
-void screen_dump(void)
-{
- int fd, y;
- char filename[MAX_PATH];
-
- fb_data *src;
-#if LCD_DEPTH == 1
- unsigned mask;
- unsigned val;
-#elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT != HORIZONTAL_PACKING)
- int shift;
- unsigned val;
-#endif
-#if LCD_DEPTH <= 8
- unsigned char *dst, *dst_end;
- unsigned char linebuf[BMP_LINESIZE];
-#elif LCD_DEPTH <= 16
- unsigned short *dst, *dst_end;
- unsigned short linebuf[BMP_LINESIZE/2];
-#endif
-
-#if CONFIG_RTC
- create_datetime_filename(filename, "", "dump ", ".bmp", false);
-#else
- create_numbered_filename(filename, "", "dump_", ".bmp", 4
- IF_CNFN_NUM_(, NULL));
-#endif
-
- fd = creat(filename);
- if (fd < 0)
- return;
-
- if (screen_dump_hook)
- {
- screen_dump_hook(fd);
- }
- else
- {
- write(fd, bmpheader, sizeof(bmpheader));
-
- /* BMP image goes bottom up */
- for (y = LCD_HEIGHT - 1; y >= 0; y--)
- {
- memset(linebuf, 0, BMP_LINESIZE);
-
-#if defined(HAVE_LCD_SPLIT) && (LCD_SPLIT_LINES == 2)
- if (y == LCD_SPLIT_POS - 1)
- {
- write(fd, linebuf, BMP_LINESIZE);
- write(fd, linebuf, BMP_LINESIZE);
- }
-#endif
- dst = linebuf;
-
-#if LCD_DEPTH == 1
- dst_end = dst + LCD_WIDTH/2;
- src = lcd_framebuffer[y >> 3];
- mask = 1 << (y & 7);
-
- do
- {
- val = (*src++ & mask) ? 0x10 : 0;
- val |= (*src++ & mask) ? 0x01 : 0;
-#ifdef HAVE_LCD_SPLIT
- if (y < LCD_SPLIT_POS)
- val |= 0x22;
-#endif
- *dst++ = val;
- }
- while (dst < dst_end);
-
-#elif LCD_DEPTH == 2
- dst_end = dst + LCD_WIDTH/2;
-
-#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
- src = lcd_framebuffer[y];
-
- do
- {
- unsigned data = *src++;
-
- *dst++ = ((data >> 2) & 0x30) | ((data >> 4) & 0x03);
- *dst++ = ((data << 2) & 0x30) | (data & 0x03);
- }
- while (dst < dst_end);
-
-#elif LCD_PIXELFORMAT == VERTICAL_PACKING
- src = lcd_framebuffer[y >> 2];
- shift = 2 * (y & 3);
-
- do
- {
- val = ((*src++ >> shift) & 3) << 4;
- val |= ((*src++ >> shift) & 3);
- *dst++ = val;
- }
- while (dst < dst_end);
-
-#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
- src = lcd_framebuffer[y >> 3];
- shift = y & 7;
-
- do
- {
- unsigned data = (*src++ >> shift) & 0x0101;
-
- val = (((data >> 7) | data) & 3) << 4;
- data = (*src++ >> shift) & 0x0101;
- val |= ((data >> 7) | data) & 3;
- *dst++ = val;
- }
- while (dst < dst_end);
-
-#endif
-#elif LCD_DEPTH == 16
- dst_end = dst + LCD_WIDTH;
- src = lcd_framebuffer[y];
-
- do
- {
-#if (LCD_PIXELFORMAT == RGB565SWAPPED)
- /* iPod LCD data is big endian although the CPU is not */
- *dst++ = htobe16(*src++);
-#else
- *dst++ = htole16(*src++);
-#endif
- }
- while (dst < dst_end);
-
-#endif /* LCD_DEPTH */
- write(fd, linebuf, BMP_LINESIZE);
- }
- }
- close(fd);
-}
-
-void screen_dump_set_hook(void (*hook)(int fh))
-{
- screen_dump_hook = hook;
-}
-
-#endif /* HAVE_LCD_BITMAP */
-
/* parse a line from a configuration file. the line format is:
name: value
diff --git a/apps/misc.h b/apps/misc.h
index 99e709c2c8..998ee9ea8f 100644
--- a/apps/misc.h
+++ b/apps/misc.h
@@ -33,27 +33,6 @@
char *output_dyn_value(char *buf, int buf_size, int value,
const unsigned char **units, bool bin_scale);
-/* Create a filename with a number part in a way that the number is 1
- * higher than the highest numbered file matching the same pattern.
- * It is allowed that buffer and path point to the same memory location,
- * saving a strcpy(). Path must always be given without trailing slash.
- *
- * "num" can point to an int specifying the number to use or NULL or a value
- * less than zero to number automatically. The final number used will also
- * be returned in *num. If *num is >= 0 then *num will be incremented by
- * one. */
-#if defined(HAVE_RECORDING) && (CONFIG_RTC == 0)
-/* this feature is needed by recording without a RTC to prevent disk access
- when changing files */
-#define IF_CNFN_NUM_(...) __VA_ARGS__
-#define IF_CNFN_NUM
-#else
-#define IF_CNFN_NUM_(...)
-#endif
-char *create_numbered_filename(char *buffer, const char *path,
- const char *prefix, const char *suffix,
- int numberlen IF_CNFN_NUM_(, int *num));
-
/* Format time into buf.
*
* buf - buffer to format to.
@@ -62,17 +41,6 @@ char *create_numbered_filename(char *buffer, const char *path,
*/
void format_time(char* buf, int buf_size, long t);
-#if CONFIG_RTC
-/* Create a filename with a date+time part.
- It is allowed that buffer and path point to the same memory location,
- saving a strcpy(). Path must always be given without trailing slash.
- unique_time as true makes the function wait until the current time has
- changed. */
-char *create_datetime_filename(char *buffer, const char *path,
- const char *prefix, const char *suffix,
- bool unique_time);
-#endif /* CONFIG_RTC */
-
/* Ask the user if they really want to erase the current dynamic playlist
* returns true if the playlist should be replaced */
bool warn_on_pl_erase(void);
@@ -87,24 +55,6 @@ int read_line(int fd, char* buffer, int buffer_size);
int fast_readline(int fd, char *buf, int buf_size, void *parameters,
int (*callback)(int n, const char *buf, void *parameters));
-#ifdef HAVE_LCD_BITMAP
-/* Save a .BMP file containing the current screen contents. */
-void screen_dump(void);
-void screen_dump_set_hook(void (*hook)(int fh));
-#endif
-
-/* Make BMP colour map entries from R, G, B triples, without and with blending.
- * Not within HAVE_LCD_BITMAP because it is also used for the Player sim */
-#define RED_CMP(c) (((c) >> 16) & 0xff)
-#define GREEN_CMP(c) (((c) >> 8) & 0xff)
-#define BLUE_CMP(c) ((c) & 0xff)
-
-#define BMP_COLOR(c) BLUE_CMP(c), GREEN_CMP(c), RED_CMP(c), 0
-#define BMP_COLOR_MIX(c1, c2, num, den) \
- (BLUE_CMP(c2) - BLUE_CMP(c1)) * (num) / (den) + BLUE_CMP(c1), \
- (GREEN_CMP(c2) - GREEN_CMP(c1)) * (num) / (den) + GREEN_CMP(c1), \
- (RED_CMP(c2) - RED_CMP(c1)) * (num) / (den) + RED_CMP(c1), 0
-
bool settings_parseline(char* line, char** name, char** value);
long default_event_handler_ex(long event, void (*callback)(void *), void *parameter);
long default_event_handler(long event);
diff --git a/apps/plugin.h b/apps/plugin.h
index 82ce0d6ddf..9ebf793d3f 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -77,6 +77,7 @@ void* plugin_get_buffer(size_t *buffer_size);
#include "timer.h"
#include "playlist.h"
#ifdef HAVE_LCD_BITMAP
+#include "screendump.h"
#include "scrollbar.h"
#include "../recorder/bmp.h"
#endif
diff --git a/apps/plugins/lib/grey_core.c b/apps/plugins/lib/grey_core.c
index 88becb1336..18b2716d4d 100644
--- a/apps/plugins/lib/grey_core.c
+++ b/apps/plugins/lib/grey_core.c
@@ -718,12 +718,9 @@ void grey_deferred_lcd_update(void)
#define BMP_BPP 8
#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3)
#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS)
-#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT)
+#define BMP_DATASIZE (BMP_LINESIZE * (LCD_HEIGHT+LCD_SPLIT_LINES))
#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE)
-#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff
-#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff
-
static const unsigned char bmpheader[] =
{
0x42, 0x4d, /* 'BM' */
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
index 8c8c56cb34..f3270d1f5d 100644
--- a/apps/recorder/radio.c
+++ b/apps/recorder/radio.c
@@ -34,6 +34,7 @@
#include "mp3_playback.h"
#include "ctype.h"
#include "file.h"
+#include "general.h"
#include "errno.h"
#include "string.h"
#include "system.h"
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index c660867f2f..de979dda50 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -77,6 +77,7 @@
#include "sound_menu.h"
#include "viewport.h"
#include "list.h"
+#include "general.h"
#ifdef HAVE_RECORDING
/* This array holds the record timer interval lengths, in seconds */
diff --git a/apps/settings.c b/apps/settings.c
index 506fd5b59d..30b056da53 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -43,6 +43,7 @@
#include "ctype.h"
#include "file.h"
#include "system.h"
+#include "general.h"
#include "misc.h"
#ifdef HAVE_LCD_BITMAP
#include "icons.h"
diff --git a/firmware/SOURCES b/firmware/SOURCES
index a9a0b17632..4d33c7949b 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -2,6 +2,7 @@ ata_idle_notify.c
events.c
backlight.c
buffer.c
+general.c
powermgmt.c
system.c
usb.c
@@ -73,6 +74,9 @@ font_cache.c
font.c
hangul.c
lru.c
+#ifndef BOOTLOADER
+screendump.c
+#endif
#if LCD_DEPTH == 1
drivers/lcd-1bit-vert.c
#elif LCD_DEPTH == 2
@@ -201,7 +205,6 @@ sound.c
#if CONFIG_CODEC == SWCODEC
#ifndef BOOTLOADER
-general.c
pcm_sampr.c
pcm.c
#ifdef HAVE_RECORDING
diff --git a/firmware/backlight.c b/firmware/backlight.c
index 9c153e885a..513f643171 100644
--- a/firmware/backlight.c
+++ b/firmware/backlight.c
@@ -35,6 +35,7 @@
#include "timer.h"
#include "backlight.h"
#include "lcd.h"
+#include "screendump.h"
#ifdef HAVE_REMOTE_LCD
#include "lcd-remote.h"
@@ -57,9 +58,6 @@ int backlight_brightness = DEFAULT_BRIGHTNESS_SETTING;
#include "backlight-sw-fading.h"
#endif
#ifdef SIMULATOR
-/* TODO: find a better way to do it but we need a kernel thread somewhere to
- handle this */
-extern void screen_dump(void);
static inline void _backlight_on(void)
{
@@ -600,9 +598,13 @@ void backlight_thread(void)
#endif /* HAVE_REMOTE_LCD/ HAVE_REMOTE_LCD_AS_MAIN */
#endif /* !SIMULATOR */
#ifdef SIMULATOR
- /* This one here too for lack of a better place */
+ /* TODO: find a better way to do it but we need
+ * a kernel thread somewhere to handle this */
case SYS_SCREENDUMP:
screen_dump();
+#ifdef HAVE_REMOTE_LCD
+ remote_screen_dump();
+#endif
break;
#endif
case SYS_USB_CONNECTED:
diff --git a/firmware/export/general.h b/firmware/export/general.h
index d1bd14558c..8da4a0ad59 100644
--- a/firmware/export/general.h
+++ b/firmware/export/general.h
@@ -24,7 +24,9 @@
#include <stdbool.h>
#include <stddef.h>
+#include "config.h"
+#if CONFIG_CODEC == SWCODEC
/* round a signed/unsigned 32bit value to the closest of a list of values */
/* returns the index of the closest value */
int round_value_to_list32(unsigned long value,
@@ -36,5 +38,38 @@ int make_list_from_caps32(unsigned long src_mask,
const unsigned long *src_list,
unsigned long caps_mask,
unsigned long *caps_list);
+#endif /* CONFIG_CODEC == SWCODEC */
+
+/* Create a filename with a number part in a way that the number is 1
+ * higher than the highest numbered file matching the same pattern.
+ * It is allowed that buffer and path point to the same memory location,
+ * saving a strcpy(). Path must always be given without trailing slash.
+ *
+ * "num" can point to an int specifying the number to use or NULL or a value
+ * less than zero to number automatically. The final number used will also
+ * be returned in *num. If *num is >= 0 then *num will be incremented by
+ * one. */
+#if defined(HAVE_RECORDING) && (CONFIG_RTC == 0)
+/* this feature is needed by recording without a RTC to prevent disk access
+ when changing files */
+#define IF_CNFN_NUM_(...) __VA_ARGS__
+#define IF_CNFN_NUM
+#else
+#define IF_CNFN_NUM_(...)
+#endif
+char *create_numbered_filename(char *buffer, const char *path,
+ const char *prefix, const char *suffix,
+ int numberlen IF_CNFN_NUM_(, int *num));
+
+#if CONFIG_RTC
+/* Create a filename with a date+time part.
+ It is allowed that buffer and path point to the same memory location,
+ saving a strcpy(). Path must always be given without trailing slash.
+ unique_time as true makes the function wait until the current time has
+ changed. */
+char *create_datetime_filename(char *buffer, const char *path,
+ const char *prefix, const char *suffix,
+ bool unique_time);
+#endif /* CONFIG_RTC */
#endif /* GENERAL_H */
diff --git a/firmware/general.c b/firmware/general.c
index ff6594086e..1ff3340d27 100644
--- a/firmware/general.c
+++ b/firmware/general.c
@@ -18,11 +18,20 @@
* KIND, either express or implied.
*
****************************************************************************/
-#include <limits.h>
-#include "system.h"
+
#include "config.h"
#include "general.h"
+#include "dir.h"
+#include "limits.h"
+#include "sprintf.h"
+#include "stdlib.h"
+#include "string.h"
+#include "system.h"
+#include "time.h"
+#include "timefuncs.h"
+
+#if CONFIG_CODEC == SWCODEC
int round_value_to_list32(unsigned long value,
const unsigned long list[],
int count,
@@ -78,3 +87,107 @@ int make_list_from_caps32(unsigned long src_mask,
return count;
} /* make_list_from_caps32 */
+#endif /* CONFIG_CODEC == SWCODEC */
+
+/* Create a filename with a number part in a way that the number is 1
+ * higher than the highest numbered file matching the same pattern.
+ * It is allowed that buffer and path point to the same memory location,
+ * saving a strcpy(). Path must always be given without trailing slash.
+ * "num" can point to an int specifying the number to use or NULL or a value
+ * less than zero to number automatically. The final number used will also
+ * be returned in *num. If *num is >= 0 then *num will be incremented by
+ * one. */
+char *create_numbered_filename(char *buffer, const char *path,
+ const char *prefix, const char *suffix,
+ int numberlen IF_CNFN_NUM_(, int *num))
+{
+ DIR *dir;
+ struct dirent *entry;
+ int max_num;
+ int pathlen;
+ int prefixlen = strlen(prefix);
+ char fmtstring[12];
+
+ if (buffer != path)
+ strncpy(buffer, path, MAX_PATH);
+
+ pathlen = strlen(buffer);
+
+#ifdef IF_CNFN_NUM
+ if (num && *num >= 0)
+ {
+ /* number specified */
+ max_num = *num;
+ }
+ else
+#endif
+ {
+ /* automatic numbering */
+ max_num = 0;
+
+ dir = opendir(pathlen ? buffer : "/");
+ if (!dir)
+ return NULL;
+
+ while ((entry = readdir(dir)))
+ {
+ int curr_num;
+
+ if (strncasecmp((char *)entry->d_name, prefix, prefixlen)
+ || strcasecmp((char *)entry->d_name + prefixlen + numberlen, suffix))
+ continue;
+
+ curr_num = atoi((char *)entry->d_name + prefixlen);
+ if (curr_num > max_num)
+ max_num = curr_num;
+ }
+
+ closedir(dir);
+ }
+
+ max_num++;
+
+ snprintf(fmtstring, sizeof(fmtstring), "/%%s%%0%dd%%s", numberlen);
+ snprintf(buffer + pathlen, MAX_PATH - pathlen, fmtstring, prefix,
+ max_num, suffix);
+
+#ifdef IF_CNFN_NUM
+ if (num)
+ *num = max_num;
+#endif
+
+ return buffer;
+}
+
+
+#if CONFIG_RTC
+/* Create a filename with a date+time part.
+ It is allowed that buffer and path point to the same memory location,
+ saving a strcpy(). Path must always be given without trailing slash.
+ unique_time as true makes the function wait until the current time has
+ changed. */
+char *create_datetime_filename(char *buffer, const char *path,
+ const char *prefix, const char *suffix,
+ bool unique_time)
+{
+ struct tm *tm = get_time();
+ static struct tm last_tm;
+ int pathlen;
+
+ while (unique_time && !memcmp(get_time(), &last_tm, sizeof (struct tm)))
+ sleep(HZ/10);
+
+ last_tm = *tm;
+
+ if (buffer != path)
+ strncpy(buffer, path, MAX_PATH);
+
+ pathlen = strlen(buffer);
+ snprintf(buffer + pathlen, MAX_PATH - pathlen,
+ "/%s%02d%02d%02d-%02d%02d%02d%s", prefix,
+ tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec, suffix);
+
+ return buffer;
+}
+#endif /* CONFIG_RTC */
diff --git a/firmware/usb.c b/firmware/usb.c
index a1e552a321..a720215731 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -42,7 +42,8 @@
#ifdef HAVE_USBSTACK
#include "usb_core.h"
#endif
-#include "logf.h"
+#include "logf.h"
+#include "screendump.h"
/* Conditions under which we want the entire driver */
#if !defined(BOOTLOADER) || (CONFIG_CPU == SH7034) || \
@@ -55,11 +56,6 @@
#ifdef HAVE_LCD_BITMAP
bool do_screendump_instead_of_usb = false;
-#if defined(USB_FULL_INIT) && defined(BOOTLOADER)
-static void screen_dump(void) {}
-#else
-void screen_dump(void); /* Nasty again. Defined in apps/ too */
-#endif
#endif
#if !defined(SIMULATOR) && !defined(USB_NONE)
@@ -262,6 +258,9 @@ static void usb_thread(void)
{
usb_state = USB_SCREENDUMP;
screen_dump();
+#ifdef HAVE_REMOTE_LCD
+ remote_screen_dump();
+#endif
break;
}
#endif
diff --git a/uisimulator/sdl/lcd-bitmap.c b/uisimulator/sdl/lcd-bitmap.c
index 8caac784ef..378889c417 100644
--- a/uisimulator/sdl/lcd-bitmap.c
+++ b/uisimulator/sdl/lcd-bitmap.c
@@ -22,7 +22,7 @@
#include "debug.h"
#include "uisdl.h"
#include "lcd-sdl.h"
-#include "misc.h"
+#include "screendump.h"
SDL_Surface* lcd_surface;
@@ -166,14 +166,12 @@ void sim_lcd_init(void)
SIM_LCD_WIDTH * display_zoom,
SIM_LCD_HEIGHT * display_zoom,
LCD_DEPTH, 0, 0, 0, 0);
-#else
+#elif LCD_DEPTH <= 8
lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
SIM_LCD_WIDTH * display_zoom,
SIM_LCD_HEIGHT * display_zoom,
8, 0, 0, 0, 0);
-#endif
-#if LCD_DEPTH <= 8
#ifdef HAVE_BACKLIGHT
sdl_set_gradient(lcd_surface, &lcd_bl_color_dark,
&lcd_bl_color_bright, 0, NUM_SHADES);
@@ -189,7 +187,7 @@ void sim_lcd_init(void)
&lcd_color2_bright, NUM_SHADES, NUM_SHADES);
#endif
#endif /* !HAVE_BACKLIGHT */
-#endif /* LCD_DEPTH < 8 */
+#endif /* LCD_DEPTH */
}
#if LCD_DEPTH < 8
diff --git a/uisimulator/sdl/lcd-charcells.c b/uisimulator/sdl/lcd-charcells.c
index 19d27d5152..30aa0a6a81 100644
--- a/uisimulator/sdl/lcd-charcells.c
+++ b/uisimulator/sdl/lcd-charcells.c
@@ -22,7 +22,8 @@
#include "debug.h"
#include "lcd.h"
#include "lcd-charcell.h"
-#include "misc.h"
+#inclued "screendump.h"
+#include "misc.h"
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
diff --git a/uisimulator/sdl/lcd-remote-bitmap.c b/uisimulator/sdl/lcd-remote-bitmap.c
index f5c2225ab2..ecb9904a40 100644
--- a/uisimulator/sdl/lcd-remote-bitmap.c
+++ b/uisimulator/sdl/lcd-remote-bitmap.c
@@ -22,7 +22,7 @@
#include "uisdl.h"
#include "lcd-sdl.h"
#include "lcd-remote-bitmap.h"
-#include "misc.h"
+#include "screendump.h"
SDL_Surface *remote_surface;
@@ -39,7 +39,7 @@ SDL_Color remote_color_bright = {RED_CMP(LCD_REMOTE_BRIGHTCOLOR),
GREEN_CMP(LCD_REMOTE_BRIGHTCOLOR),
BLUE_CMP(LCD_REMOTE_BRIGHTCOLOR), 0};
-#define GRADIENT_MAX 128
+#define NUM_SHADES 129
#if LCD_REMOTE_DEPTH == 2
/* Only defined for positive, non-split LCD for now */
@@ -49,7 +49,7 @@ static const unsigned char colorindex[4] = {128, 85, 43, 0};
static unsigned long get_lcd_remote_pixel(int x, int y)
{
#if LCD_REMOTE_DEPTH == 1
- return lcd_remote_framebuffer[y/8][x] & (1 << (y & 7)) ? 0 : GRADIENT_MAX;
+ return lcd_remote_framebuffer[y/8][x] & (1 << (y & 7)) ? 0 : (NUM_SHADES-1);
#elif LCD_REMOTE_DEPTH == 2
#if LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED
unsigned bits = (lcd_remote_framebuffer[y/8][x] >> (y & 7)) & 0x0101;
@@ -76,10 +76,10 @@ void sim_remote_backlight(int value)
{
if (value > 0) {
sdl_set_gradient(remote_surface, &remote_bl_color_dark,
- &remote_bl_color_bright, 0, GRADIENT_MAX+1);
+ &remote_bl_color_bright, 0, NUM_SHADES);
} else {
sdl_set_gradient(remote_surface, &remote_color_dark,
- &remote_color_bright, 0, GRADIENT_MAX+1);
+ &remote_color_bright, 0, NUM_SHADES);
}
sdl_gui_update(remote_surface, 0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT,
@@ -97,6 +97,6 @@ void sim_lcd_remote_init(void)
8, 0, 0, 0, 0);
sdl_set_gradient(remote_surface, &remote_bl_color_dark,
- &remote_bl_color_bright, 0, GRADIENT_MAX+1);
+ &remote_bl_color_bright, 0, NUM_SHADES);
}