From fb29f601f1d5e4c74af9c0d7f53cdf9b57f2cb85 Mon Sep 17 00:00:00 2001 From: inmarket Date: Sun, 5 Jan 2014 00:02:53 +1000 Subject: [PATCH 01/23] Start of GFILE module --- include/gfile/gfile.h | 185 ++++++++++++++++++++++++++++++++ include/gfile/options.h | 114 ++++++++++++++++++++ src/gfile/gfile.c | 225 +++++++++++++++++++++++++++++++++++++++ src/gfile/gfile.mk | 1 + src/gfile/inc_fatfs.c | 15 +++ src/gfile/inc_nativefs.c | 81 ++++++++++++++ src/gfile/inc_ramfs.c | 15 +++ src/gfile/inc_romfs.c | 97 +++++++++++++++++ 8 files changed, 733 insertions(+) create mode 100644 include/gfile/gfile.h create mode 100644 include/gfile/options.h create mode 100644 src/gfile/gfile.c create mode 100644 src/gfile/gfile.mk create mode 100644 src/gfile/inc_fatfs.c create mode 100644 src/gfile/inc_nativefs.c create mode 100644 src/gfile/inc_ramfs.c create mode 100644 src/gfile/inc_romfs.c diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h new file mode 100644 index 00000000..675342fb --- /dev/null +++ b/include/gfile/gfile.h @@ -0,0 +1,185 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file include/gfile/gfile.h + * @brief GFILE - File IO Routines header file. + * + * @addtogroup GFILE + * + * @brief Module which contains Operating system independent FILEIO + * + * @{ + */ + +#ifndef _GFILE_H +#define _GFILE_H + +#include "gfx.h" + +#if GFX_USE_GMISC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Type definitions */ +/*===========================================================================*/ + +/** + * @brief A file pointer + */ + +typedef struct GFILE { + const struct GFILEVMT * vmt; + uint16_t flags; + #define GFILEFLG_OPEN 0x0001 + #define GFILEFLG_READ 0x0002 + #define GFILEFLG_WRITE 0x0004 + #define GFILEFLG_APPEND 0x0008 + #define GFILEFLG_CANSEEK 0x0010 + #define GFILEFLG_DELONCLOSE 0x0020 + #define GFILEFLG_FAILONBLOCK 0x0040 + short err; + void * obj; + long int pos; +} GFILE; + +typedef struct GFILEVMT { + const struct GFILEVMT * next; + char prefix; + uint16_t flags; + #define GFSFLG_WRITEABLE 0x0001 + #define GFSFLG_CASESENSITIVE 0x0002 + #define GFSFLG_SEEKABLE 0x0004 + #define GFSFLG_FAST 0x0010 + #define GFSFLG_SMALL 0x0020 + bool_t del(const char *fname); + bool_t exists(const char *fname); + long int filesize(const char *fname); + bool_t ren(const char *oldname, const char *newname); + bool_t open(GFILE *f, const char *fname, const char *mode); + void close(GFILE *f); + int read(GFILE *f, char *buf, int size); + int write(GFILE *f, char *buf, int size); + bool_t setpos(GFILE *f, long int pos); + long int getsize(GFILE *f); + bool_t eof(GFILE *f); +} GFILEVMT; + +typedef void GFILE; + +extern GFILE *gfileStdIn; +extern GFILE *gfileStdErr; +extern GFILE *gfileStdOut; + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +//TODO +//FILE * tmpfile ( void ); // Auto-deleting +//char * tmpnam ( char * str ); +//L_tmpnam - Minimum length for temporary file name +//FILENAME_MAX - Maximum length of file names (constant ) +// FOPEN_MAX - Potential limit of simultaneous open streams (constant ) +// TMP_MAX - Number of temporary files (constant ) +//FILE * freopen ( const char * filename, const char * mode, FILE * stream ); +//setbuf +//setvbuf +//fflush +//fscanf +//scanf +//sscanf +//vscanf +//vsscanf +//fgetc +//fgets +//fputc +//fputs +//getc +//getchar +//puts +//ungetc +//void perror (const char * str); + +//"r" read: Open file for input operations. The file must exist. +//"w" write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file. +//"a" append: Open file for output at the end of a file. Output operations always write data at the end of the file, expanding it. Repositioning operations (fseek, fsetpos, rewind) are ignored. The file is created if it does not exist. +//"r+" read/update: Open a file for update (both for input and output). The file must exist. +//"w+" write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file. +//"a+" append/update: Open a file for update (both for input and output) with all output operations writing data at the end of the file. Repositioning operations (fseek, fsetpos, rewind) affects the next input operations, but output operations move the position back to the end of file. The file is created if it does not exist. +//"...b" A binary stream +//"...x" Added to "w" - fail if file exists + + +#ifdef __cplusplus +extern "C" { +#endif + + bool_t gfileExists(const char *fname); + bool_t gfileDelete(const char *fname); + long int gfileGetFilesize(const char *fname); + bool_t gfileRename(const char *oldname, const char *newname); + GFILE *gfileOpen(const char *fname, const char *mode); + void gfileClose(GFILE *f); + size_t gfileRead(GFILE *f, char *buf, size_t len); + size_t gfileWrite(GFILE *f, const char *buf, size_t len); + long int gfileGetPos(GFILE *f); + bool_t gfileSetPos(GFILE *f, long int pos); + long int gfileGetSize(GFILE *f); + + int vfnprintg(GFILE *f, size_t maxlen, const char *fmt, va_list arg); + int fnprintg(GFILE *f, size_t maxlen, const char *fmt, ...); + #define vfprintg(f,m,a) vfnprintg(f,0,m,a) + #define fprintg(f,m,...) fnprintg(f,0,m,...) + #define vprintg(m,a) vfnprintg(gfileStdOut,0,m,a) + #define printg(m,...) fnprintg(gfileStdOut,0,m,...) + + int vsnprintg(char *buf, size_t maxlen, const char *fmt, va_list arg); + int snprintg(char *buf, size_t maxlen, const char *fmt, ...); + #define vsprintg(s,m,a) vsnprintg(s,0,m,a) + #define sprintg(s,m,...) snprintg(s,0,m,...) + + #if GFILE_NEED_STDIO && !defined(GFILE_IMPLEMENTATION) + #define FILE GFILE + #define fopen(n,m) gfileOpen(n,m) + #define fclose(f) gfileClose(f) + size_t fread(void * ptr, size_t size, size_t count, FILE *f); + size_t fwrite(const void * ptr, size_t size, size_t count, FILE *f); + int fseek(FILE *f, size_t offset, int origin); + #define SEEK_SET 0 + #define SEEK_CUR 1 + #define SEEK_END 2 + #define remove(n) (!gfileDelete(n)) + #define rename(o,n) (!gfileRename(o,n)) + #define fflush(f) (0) + #define ftell(f) gfileGetPos(f) + typedef long int fpos_t; + int fgetpos(FILE *f, fpos_t *pos); + #define fsetpos(f, pos) (!gfileSetPos(f, *pos)) + #define rewind(f) gfileSetPos(f, 0); + #define clearerr(f) do {f->err = 0; } while(0) + #define feof(f) (f->flags & GFILEFLG_EOF) + #define ferror(f) (f->err) + + #define vfprintf(f,m,a) vfnprintg(f,0,m,a) + #define fprintf(f,m,...) fnprintg(f,0,m,...) + #define vprintf(m,a) vfnprintg(gfileStdOut,0,m,a) + #define printf(m,...) fnprintg(gfileStdOut,0,m,...) + #define vsnprintf(s,n,m,a) vsnprintg(s,n,m,a) + #define snprintf(s,n,m,...) snprintg(s,n,m,...) + #define vsprintf(s,m,a) vsnprintg(s,0,m,a) + #define sprintf(s,m,...) snprintg(s,0,m,...) + #endif + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_USE_MISC */ + +#endif /* _GMISC_H */ +/** @} */ + diff --git a/include/gfile/options.h b/include/gfile/options.h new file mode 100644 index 00000000..176c6270 --- /dev/null +++ b/include/gfile/options.h @@ -0,0 +1,114 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file include/gfile/options.h + * @brief GFILE - File IO options header file. + * + * @addtogroup GFILE + * @{ + */ + +#ifndef _GFILE_OPTIONS_H +#define _GFILE_OPTIONS_H + +/** + * @name GFILE Functionality to be included + * @{ + */ + /** + * @brief Include printg, fprintg, sprintg etc functions + * @details Defaults to FALSE + */ + #ifndef GFILE_NEED_PRINTG + #define GFILE_NEED_PRINTG FALSE + #endif + /** + * @brief Include scang, fscang, sscang etc functions + * @details Defaults to FALSE + */ + #ifndef GFILE_NEED_SCANG + #define GFILE_NEED_SCANG FALSE + #endif + /** + * @brief Map all the stdio functions to their GFILE equivalent + * @details Defaults to FALSE + * @note This replaces the functions in stdio.h with equivalents + * - Do not include stdio.h as it has different conflicting definitions. + */ + #ifndef GFILE_NEED_STDIO + #define GFILE_NEED_STDIO FALSE + #endif + /** + * @brief Include the ROM file system + * @details Defaults to FALSE + * @note To ensure that you are opening a file on the ROM file system, prefix + * its name with "S|" (the letter 'S', followed by a vertical bar). + * @note This requires a file called romfs_files.h to be included in the + * users project. This file includes all the files converted to .h files + * using the file2c utility using the "-r" flag. + */ + #ifndef GFILE_NEED_ROMFS + #define GFILE_NEED_ROMFS FALSE + #endif + /** + * @brief Include the RAM file system + * @details Defaults to FALSE + * @note To ensure that you are opening a file on the RAM file system, prefix + * its name with "R|" (the letter 'R', followed by a vertical bar). + * @note You must also define GFILE_RAMFS_SIZE with the size of the file system + * to be allocated in RAM. + */ + #ifndef GFILE_NEED_RAMFS + #define GFILE_NEED_RAMFS FALSE + #endif + /** + * @brief Include the FAT file system driver + * @details Defaults to FALSE + * @note To ensure that you are opening a file on the FAT file system, prefix + * its name with "F|" (the letter 'F', followed by a vertical bar). + * @note You must separately include the FATFS library and code. + */ + #ifndef GFILE_NEED_FATFS + #define GFILE_NEED_FATFS FALSE + #endif + /** + * @brief Include the operating system's native file system + * @details Defaults to FALSE + * @note To ensure that you are opening a file on the native file system, prefix + * its name with "N|" (the letter 'N', followed by a vertical bar). + * @note If defined then the gfileStdOut and gfileStdErr handles + * use the operating system equivalent stdio and stderr. + * If it is not defined the gfileStdOut and gfileStdErr io is discarded. + */ + #ifndef GFILE_NEED_NATIVEFS + #define GFILE_NEED_NATIVEFS FALSE + #endif +/** + * @} + * + * @name GFILE Optional Parameters + * @{ + */ + /** + * @brief The maximum number of open files + * @note This count excludes gfileStdIn, gfileStdOut and gfileStdErr + * (if open by default). + */ + #ifndef GFILE_MAX_GFILES + #define GFILE_MAX_GFILES 3 + #endif + /** + * @brief The size in bytes of the RAM file system + */ + #ifndef GFILE_RAMFS_SIZE + #define GFILE_RAMFS_SIZE 0 + #endif +/** @} */ + +#endif /* _GFILE_OPTIONS_H */ +/** @} */ diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c new file mode 100644 index 00000000..bf76e8bc --- /dev/null +++ b/src/gfile/gfile.c @@ -0,0 +1,225 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gfile/gfile.c + * @brief GFILE code. + * + */ + +#define GFILE_IMPLEMENTATION +#include "gfx.h" + +#if GFX_USE_GFILE + +// The chain of FileSystems +#define GFILE_CHAINHEAD 0 + +// The table of GFILE's +static GFILE gfileArr[GFILE_MAX_GFILES]; +GFILE *gfileStdIn; +GFILE *gfileStdOut; +GFILE *gfileStdErr; + +/** + * The order of the file-systems below determines the order + * that they are searched to find a file. + * The last defined is the first searched. + */ + +/******************************************************** + * The RAM file-system VMT + ********************************************************/ +#if GFILE_NEED_RAMFS + #include "../src/gfile/inc_ramfs.c" +#endif + +/******************************************************** + * The FAT file-system VMT + ********************************************************/ +#ifndef GFILE_NEED_FATFS + #include "../src/gfile/inc_fatfs.c" +#endif + +/******************************************************** + * The native file-system + ********************************************************/ +#if GFILE_NEED_NATIVEFS + #include "../src/gfile/inc_nativefs.c" +#endif + +/******************************************************** + * The ROM file-system VMT + ********************************************************/ +#if GFILE_NEED_ROMFS + #include "../src/gfile/inc_romfs.c" +#endif + +/******************************************************** + * IO routines + ********************************************************/ + +/** + * The chain of file systems. + */ +static const GFILEVMT const * FsChain = GFILE_CHAINHEAD; + +/** + * The init routine + */ +void _gfileInit(void) { + #if GFILE_NEED_NATIVEFS + NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ; + NativeStdIn.vmt = &FsNativeVMT; + NativeStdIn.obj = (void *)stdin; + NativeStdIn.pos = 0; + gfileStdIn = &NativeStdIn; + NativeStdOut.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND; + NativeStdOut.vmt = &FsNativeVMT; + NativeStdOut.obj = (void *)stdout; + NativeStdOut.pos = 0; + gfileStdOut = &NativeStdOut; + NativeStdErr.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND; + NativeStdErr.vmt = &FsNativeVMT; + NativeStdErr.obj = (void *)stderr; + NativeStdErr.pos = 0; + gfileStdErr = &NativeStdErr; + #endif +} + +bool_t gfileExists(const char *fname) { + const GFILEVMT *p; + + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->exists && p->exists(fname+2); + } + } else { + for(p = FsChain; p; p = p->next) { + if (p->exists && p->exists(fname)) + return TRUE; + } + } + return FALSE; +} + +bool_t gfileDelete(const char *fname) { + const GFILEVMT *p; + + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->del && p->del(fname+2); + } + } else { + for(p = FsChain; p; p = p->next) { + if (p->del && p->del(fname)) + return TRUE; + } + } + return FALSE; +} + +long int gfileGetFilesize(const char *fname) { + const GFILEVMT *p; + + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->filesize ? p->filesize(fname+2) : -1; + } + } else { + long int res; + + for(p = FsChain; p; p = p->next) { + if (p->filesize && (res = p->filesize(fname)) != -1) + return res; + } + } + return -1; +} + +bool_t gfileRename(const char *oldname, const char *newname) { + const GFILEVMT *p; + + if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1])) { + char ch; + + if (oldname[0] && oldname[1] == '|') { + ch = oldname[0]; + oldname += 2; + if (newname[0] && newname[1] == '|') { + if (newname[0] != ch) + return FALSE; + newname += 2; + } + } else { + ch = newname[0]; + newname += 2; + } + for(p = FsChain; p; p = p->next) { + if (p->prefix == ch) + return p->ren && p->ren(oldname, newname); + } + } else { + for(p = FsChain; p; p = p->next) { + if (p->ren && p->ren(oldname,newname)) + return TRUE; + } + } + return FALSE; +} + +GFILE *gfileOpen(const char *fname, const char *mode) { + +} + +void gfileClose(GFILE *f) { + +} + +size_t gfileRead(GFILE *f, char *buf, size_t len) { + +} + +size_t gfileWrite(GFILE *f, const char *buf, size_t len) { + +} + +long int gfileGetPos(GFILE *f) { + +} + +bool_t gfileSetPos(GFILE *f, long int pos) { + +} + +long int gfileGetSize(GFILE *f) { + +} + +/******************************************************** + * printg routines + ********************************************************/ +#if GFILE_NEED_PRINTG +#endif + +/******************************************************** + * scang routines + ********************************************************/ +#if GFILE_NEED_SCANG +#endif + +/******************************************************** + * stdio emulation routines + ********************************************************/ +#ifndef GFILE_NEED_STDIO + #define GFILE_NEED_STDIO FALSE +#endif + +#endif /* GFX_USE_GFILE */ diff --git a/src/gfile/gfile.mk b/src/gfile/gfile.mk new file mode 100644 index 00000000..381bd6f6 --- /dev/null +++ b/src/gfile/gfile.mk @@ -0,0 +1 @@ +GFXSRC += $(GFXLIB)/src/gfile/gfile.c diff --git a/src/gfile/inc_fatfs.c b/src/gfile/inc_fatfs.c new file mode 100644 index 00000000..d49cfe7a --- /dev/null +++ b/src/gfile/inc_fatfs.c @@ -0,0 +1,15 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The FAT file-system VMT + ********************************************************/ +#error "GFILE: FATFS Not implemented yet" diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c new file mode 100644 index 00000000..7828ff84 --- /dev/null +++ b/src/gfile/inc_nativefs.c @@ -0,0 +1,81 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The native file-system + ********************************************************/ + +#include +#include +#include +#include + +static GFILE NativeStdIn; +static GFILE NativeStdOut; +static GFILE NativeStdErr; + +static bool_t NativeDel(const char *fname); +static bool_t NativeExists(const char *fname); +static long int NativeFilesize(const char *fname); +static bool_t NativeRen(const char *oldname, const char *newname); +static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode); +static void NativeClose(GFILE *f); +static int NativeRead(GFILE *f, char *buf, int size); +static int NativeWrite(GFILE *f, char *buf, int size); +static bool_t NativeSetpos(GFILE *f, long int pos); +static long int NativeGetsize(GFILE *f); +static bool_t NativeEof(GFILE *f); + +static const GFILEVMT FsNativeVMT = { + GFILE_CHAINHEAD, // next + 'N', // prefix + #if !defined(WIN32) && !GFX_USE_OS_WIN32 + GFSFLG_CASESENSITIVE| + #endif + GFSFLG_WRITEABLE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + NativeDel, NativeExists, NativeFilesize, NativeRen, + NativeOpen, NativeClose, NativeRead, NativeWrite, + NativeSetpos, NativeGetsize, NativeEof, +}; +#undef GFILE_CHAINHEAD +#define GFILE_CHAINHEAD &FsNativeVMT + +static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; } +static bool_t NativeExists(const char *fname) { return access(fname, 0) ? FALSE : TRUE; } +static long int NativeFilesize(const char *fname) { + struct stat st; + if (stat(fname, &st)) return -1; + return st.st_size; +} +static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE }; +static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode) { + FILE *fd; + + if (!(fd = fopen(fname, mode))) + return FALSE; + f->vmt = &FsNativeVMT; + f->obj = (void *)fd; + return TRUE; +} +static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } +static int NativeRead(GFILE *f, char *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static bool_t NativeSetpos(GFILE *f, long int pos) { + if (fseek((FILE *)f->obj, pos, SEEK_SET)) return FALSE; + f->pos = pos; + return TRUE; +} +static long int NativeGetsize(GFILE *f) { + struct stat st; + if (fstat(fileno((FILE *)f->obj), &st)) return -1; + return st.st_size; +} +static bool_t NativeEof(GFILE *f) { return feof((FILE *)f->obj) ? TRUE : FALSE; } diff --git a/src/gfile/inc_ramfs.c b/src/gfile/inc_ramfs.c new file mode 100644 index 00000000..b0f0d052 --- /dev/null +++ b/src/gfile/inc_ramfs.c @@ -0,0 +1,15 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The RAM file-system VMT + ********************************************************/ +#error "GFILE: RAMFS Not implemented yet" diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c new file mode 100644 index 00000000..321dc9b1 --- /dev/null +++ b/src/gfile/inc_romfs.c @@ -0,0 +1,97 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The ROM file-system VMT + ********************************************************/ + +#include + +typedef struct ROMFS_DIRENTRY { + const struct ROMFS_DIRENTRY * next; + const char * name; + long int size; + const char * file; +} ROMFS_DIRENTRY; + +#define ROMFS_DIRENTRY_HEAD 0 + +#include "romfs_files.h" + +static const ROMFS_DIRENTRY const *FsROMHead = ROMFS_DIRENTRY_HEAD; + +static bool_t ROMExists(const char *fname); +static long int ROMFilesize(const char *fname); +static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode); +static void ROMClose(GFILE *f); +static int ROMRead(GFILE *f, char *buf, int size); +static bool_t ROMSetpos(GFILE *f, long int pos); +static long int ROMGetsize(GFILE *f); +static bool_t ROMEof(GFILE *f); + +static const GFILEVMT FsROMVMT = { + GFILE_CHAINHEAD, // next + 'S', // prefix + GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + 0, ROMExists, ROMFilesize, 0, + ROMOpen, ROMClose, ROMRead, 0, + ROMSetpos, ROMGetsize, ROMEof, +}; +#undef GFILE_CHAINHEAD +#define GFILE_CHAINHEAD &FsROMVMT + +static ROMFS_DIRENTRY *ROMFindFile(const char *fname) { + const ROMFS_DIRENTRY *p; + + for(p = FsROMHead; p; p = p->next) { + if (!strcmp(p->name, fname)) + break; + } + return p; +} +static bool_t ROMExists(const char *fname) { return ROMFindFile(fname) != 0; } +static long int ROMFilesize(const char *fname) { + const ROMFS_DIRENTRY *p; + + if (!(p = ROMFindFile(fname))) return -1; + return p->size; +} +static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode) { + const ROMFS_DIRENTRY *p; + + // Check mode + if (mode[0] != 'r') return FALSE; + while(*++mode) { + switch(*mode) { + case '+': case 'w': case 'a': + return FALSE; + } + } + + if (!(p = ROMFindFile(fname))) return FALSE; + f->vmt = &FsROMVMT; + f->obj = (void *)p; + return TRUE; +} +static void ROMClose(GFILE *f) { (void)f; } +static int ROMRead(GFILE *f, char *buf, int size) { + const ROMFS_DIRENTRY *p; + + p = (const ROMFS_DIRENTRY *)f->obj; + if (p->size - f->pos < size) + size = p->size - f->pos; + if (size <= 0) return 0; + memcpy(buf, p->file+f->pos, size); + return size; +} +static bool_t ROMSetpos(GFILE *f, long int pos) { return pos <= ((const ROMFS_DIRENTRY *)f->obj)->size; } +static long int ROMGetsize(GFILE *f) { return ((const ROMFS_DIRENTRY *)f->obj)->size; } +static bool_t ROMEof(GFILE *f) { return f->pos >= ((const ROMFS_DIRENTRY *)f->obj)->size; } From ca8ca49825c01cc7698c8b363b022b7d35b912cf Mon Sep 17 00:00:00 2001 From: inmarket Date: Thu, 9 Jan 2014 08:52:26 +1000 Subject: [PATCH 02/23] Increase size of gwin flags to 32 bits. --- include/gwin/gwin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/gwin/gwin.h b/include/gwin/gwin.h index e964bc3a..f97919e5 100644 --- a/include/gwin/gwin.h +++ b/include/gwin/gwin.h @@ -42,7 +42,7 @@ typedef struct GWindowObject { coord_t x, y; // @< Screen relative position coord_t width, height; // @< Dimensions of this window color_t color, bgcolor; // @< The current drawing colors - uint16_t flags; // @< Window flags (the meaning is private to the GWIN class) + uint32_t flags; // @< Window flags (the meaning is private to the GWIN class) #if GDISP_NEED_TEXT font_t font; // @< The current font #endif From c5ab2adbf0c14a6d0d4e2245a616d01de4b88214 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 24 Jan 2014 19:33:28 +1000 Subject: [PATCH 03/23] More code for GFile --- include/gfile/gfile.h | 34 ++++++-------- src/gfile/gfile.c | 95 ++++++++++++++++++++++++++++++++++++++-- src/gfile/inc_nativefs.c | 23 ++++++++-- src/gfile/inc_romfs.c | 14 +----- 4 files changed, 128 insertions(+), 38 deletions(-) diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h index 675342fb..5b49a6b3 100644 --- a/include/gfile/gfile.h +++ b/include/gfile/gfile.h @@ -34,13 +34,17 @@ typedef struct GFILE { const struct GFILEVMT * vmt; uint16_t flags; - #define GFILEFLG_OPEN 0x0001 - #define GFILEFLG_READ 0x0002 - #define GFILEFLG_WRITE 0x0004 - #define GFILEFLG_APPEND 0x0008 - #define GFILEFLG_CANSEEK 0x0010 - #define GFILEFLG_DELONCLOSE 0x0020 - #define GFILEFLG_FAILONBLOCK 0x0040 + #define GFILEFLG_OPEN 0x0001 // File is open + #define GFILEFLG_READ 0x0002 // Read the file + #define GFILEFLG_WRITE 0x0004 // Write the file + #define GFILEFLG_APPEND 0x0008 // Append on each write + #define GFILEFLG_BINARY 0x0010 // Treat as a binary file + #define GFILEFLG_DELONCLOSE 0x0020 // Delete on close + #define GFILEFLG_CANSEEK 0x0040 // Seek operations are valid + #define GFILEFLG_FAILONBLOCK 0x0080 // Fail on a blocking call + #define GFILEFLG_MUSTEXIST 0x0100 // On open file must exist + #define GFILEFLG_MUSTNOTEXIST 0x0200 // On open file must not exist + #define GFILEFLG_TRUNC 0x0400 // On open truncate the file short err; void * obj; long int pos; @@ -48,18 +52,18 @@ typedef struct GFILE { typedef struct GFILEVMT { const struct GFILEVMT * next; - char prefix; - uint16_t flags; + uint8_t flags; #define GFSFLG_WRITEABLE 0x0001 #define GFSFLG_CASESENSITIVE 0x0002 #define GFSFLG_SEEKABLE 0x0004 #define GFSFLG_FAST 0x0010 #define GFSFLG_SMALL 0x0020 + char prefix; bool_t del(const char *fname); bool_t exists(const char *fname); long int filesize(const char *fname); bool_t ren(const char *oldname, const char *newname); - bool_t open(GFILE *f, const char *fname, const char *mode); + bool_t open(GFILE *f, const char *fname); void close(GFILE *f); int read(GFILE *f, char *buf, int size); int write(GFILE *f, char *buf, int size); @@ -104,16 +108,6 @@ extern GFILE *gfileStdOut; //ungetc //void perror (const char * str); -//"r" read: Open file for input operations. The file must exist. -//"w" write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file. -//"a" append: Open file for output at the end of a file. Output operations always write data at the end of the file, expanding it. Repositioning operations (fseek, fsetpos, rewind) are ignored. The file is created if it does not exist. -//"r+" read/update: Open a file for update (both for input and output). The file must exist. -//"w+" write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file. -//"a+" append/update: Open a file for update (both for input and output) with all output operations writing data at the end of the file. Repositioning operations (fseek, fsetpos, rewind) affects the next input operations, but output operations move the position back to the end of file. The file is created if it does not exist. -//"...b" A binary stream -//"...x" Added to "w" - fail if file exists - - #ifdef __cplusplus extern "C" { #endif diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index bf76e8bc..83e487a1 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -147,7 +147,7 @@ long int gfileGetFilesize(const char *fname) { bool_t gfileRename(const char *oldname, const char *newname) { const GFILEVMT *p; - if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1])) { + if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { char ch; if (oldname[0] && oldname[1] == '|') { @@ -155,6 +155,7 @@ bool_t gfileRename(const char *oldname, const char *newname) { oldname += 2; if (newname[0] && newname[1] == '|') { if (newname[0] != ch) + // Both oldname and newname are fs specific but different ones. return FALSE; newname += 2; } @@ -175,12 +176,100 @@ bool_t gfileRename(const char *oldname, const char *newname) { return FALSE; } -GFILE *gfileOpen(const char *fname, const char *mode) { +static uint16_t mode2flags(const char *mode) { + uint16_t flags; + switch(mode[0]) { + case 'r': + flags = GFILEFLG_READ|GFILEFLG_MUSTEXIST; + while (*++mode) { + switch(mode[0]) { + case '+': flags |= GFILEFLG_WRITE; break; + case 'b': flags |= GFILEFLG_BINARY; break; + } + } + return flags; + case 'w': + flags = GFILEFLG_WRITE|GFILEFLG_TRUNC; + while (*++mode) { + switch(mode[0]) { + case '+': flags |= GFILEFLG_READ; break; + case 'b': flags |= GFILEFLG_BINARY; break; + case 'x': flags |= GFILEFLG_MUSTNOTEXIST; break; + } + } + return flags; + case 'a': + flags = GFILEFLG_WRITE|GFILEFLG_APPEND; + while (*++mode) { + switch(mode[0]) { + case '+': flags |= GFILEFLG_READ; break; + case 'b': flags |= GFILEFLG_BINARY; break; + case 'x': flags |= GFILEFLG_MUSTNOTEXIST; break; + } + } + return flags; + } + return 0; +} + +static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { + // If we want write but the fs doesn't allow it then return + if ((f->flags & GFILEFLG_WRITE) && !(p->flags & GFSFLG_WRITEABLE)) + return FALSE; + + // Try to open + if (!p->open || !p->open(f, fname)) + return FALSE; + + // File is open - fill in all the details + f->vmt = p; + f->err = 0; + f->pos = 0; + f->flags |= GFILEFLG_OPEN; + if (p->flags & GFSFLG_SEEKABLE) + f->flags |= GFILEFLG_CANSEEK; + return TRUE; +} + +GFILE *gfileOpen(const char *fname, const char *mode) { + GFILE *f; + const GFILEVMT *p; + + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + + // Get the requested mode + if (!(f->flags = mode2flags(mode))) + return FALSE; + + // Try to open the file + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return testopen(p, f, fname+2); + } + } else { + for(p = FsChain; p; p = p->next) { + if (testopen(p, f, fname)) + return TRUE; + } + } + + // File not found + return FALSE; + } + } + + // No available slot + return FALSE; } void gfileClose(GFILE *f) { - + // Make sure it is one of the system GFILE's + if (f < gfileArr || f >= &gfileArr[GFILE_MAX_GFILES]) + return; } size_t gfileRead(GFILE *f, char *buf, size_t len) { diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index 7828ff84..ccf1d40a 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -36,11 +36,11 @@ static bool_t NativeEof(GFILE *f); static const GFILEVMT FsNativeVMT = { GFILE_CHAINHEAD, // next - 'N', // prefix #if !defined(WIN32) && !GFX_USE_OS_WIN32 GFSFLG_CASESENSITIVE| #endif GFSFLG_WRITEABLE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + 'N', // prefix NativeDel, NativeExists, NativeFilesize, NativeRen, NativeOpen, NativeClose, NativeRead, NativeWrite, NativeSetpos, NativeGetsize, NativeEof, @@ -48,6 +48,23 @@ static const GFILEVMT FsNativeVMT = { #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsNativeVMT +static char *flags2mode(char *buf, uint16_t flags) { + if (flags & GFILEFLG_MUSTEXIST) + *buf = 'r'; + else if (flags & GFILEFLG_APPEND) + *buf = 'a'; + else + *buf = 'w'; + buf++; + if ((flags & (GFILEFLG_READ|GFILEFLG_WRITE)) == (GFILEFLG_READ|GFILEFLG_WRITE)) + *buf++ = '+'; + if (flags & GFILEFLG_BINARY) + *buf++ = 'b'; + if (flags & GFILEFLG_MUSTNOTEXIST) + *buf++ = 'x'; + *buf++ = 0; +} + static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; } static bool_t NativeExists(const char *fname) { return access(fname, 0) ? FALSE : TRUE; } static long int NativeFilesize(const char *fname) { @@ -56,12 +73,12 @@ static long int NativeFilesize(const char *fname) { return st.st_size; } static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE }; -static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode) { +static bool_t NativeOpen(GFILE *f, const char *fname) { FILE *fd; + char mode[5]; if (!(fd = fopen(fname, mode))) return FALSE; - f->vmt = &FsNativeVMT; f->obj = (void *)fd; return TRUE; } diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 321dc9b1..170b9a6c 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -39,8 +39,8 @@ static bool_t ROMEof(GFILE *f); static const GFILEVMT FsROMVMT = { GFILE_CHAINHEAD, // next - 'S', // prefix GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags + 'S', // prefix 0, ROMExists, ROMFilesize, 0, ROMOpen, ROMClose, ROMRead, 0, ROMSetpos, ROMGetsize, ROMEof, @@ -64,20 +64,10 @@ static long int ROMFilesize(const char *fname) { if (!(p = ROMFindFile(fname))) return -1; return p->size; } -static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode) { +static bool_t ROMOpen(GFILE *f, const char *fname) { const ROMFS_DIRENTRY *p; - // Check mode - if (mode[0] != 'r') return FALSE; - while(*++mode) { - switch(*mode) { - case '+': case 'w': case 'a': - return FALSE; - } - } - if (!(p = ROMFindFile(fname))) return FALSE; - f->vmt = &FsROMVMT; f->obj = (void *)p; return TRUE; } From 5bba108949ed1f97b18f1ea732553da369e8beb0 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 29 Jan 2014 00:37:16 +1000 Subject: [PATCH 04/23] More GFile code --- include/gfile/gfile.h | 68 ++--- include/gfile/options.h | 47 +++- src/gfile/gfile.c | 522 +++++++++++++++++++++++++++++++++------ src/gfile/inc_nativefs.c | 14 +- src/gfile/inc_romfs.c | 2 +- 5 files changed, 530 insertions(+), 123 deletions(-) diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h index 5b49a6b3..bc476956 100644 --- a/include/gfile/gfile.h +++ b/include/gfile/gfile.h @@ -45,7 +45,6 @@ typedef struct GFILE { #define GFILEFLG_MUSTEXIST 0x0100 // On open file must exist #define GFILEFLG_MUSTNOTEXIST 0x0200 // On open file must not exist #define GFILEFLG_TRUNC 0x0400 // On open truncate the file - short err; void * obj; long int pos; } GFILE; @@ -58,6 +57,7 @@ typedef struct GFILEVMT { #define GFSFLG_SEEKABLE 0x0004 #define GFSFLG_FAST 0x0010 #define GFSFLG_SMALL 0x0020 + #define GFSFLG_TEXTMODES 0x0040 char prefix; bool_t del(const char *fname); bool_t exists(const char *fname); @@ -66,7 +66,7 @@ typedef struct GFILEVMT { bool_t open(GFILE *f, const char *fname); void close(GFILE *f); int read(GFILE *f, char *buf, int size); - int write(GFILE *f, char *buf, int size); + int write(GFILE *f, const char *buf, int size); bool_t setpos(GFILE *f, long int pos); long int getsize(GFILE *f); bool_t eof(GFILE *f); @@ -112,37 +112,46 @@ extern GFILE *gfileStdOut; extern "C" { #endif - bool_t gfileExists(const char *fname); - bool_t gfileDelete(const char *fname); - long int gfileGetFilesize(const char *fname); - bool_t gfileRename(const char *oldname, const char *newname); - GFILE *gfileOpen(const char *fname, const char *mode); - void gfileClose(GFILE *f); - size_t gfileRead(GFILE *f, char *buf, size_t len); - size_t gfileWrite(GFILE *f, const char *buf, size_t len); + bool_t gfileExists(const char *fname); + bool_t gfileDelete(const char *fname); + long int gfileGetFilesize(const char *fname); + bool_t gfileRename(const char *oldname, const char *newname); + GFILE * gfileOpen(const char *fname, const char *mode); + void gfileClose(GFILE *f); + size_t gfileRead(GFILE *f, char *buf, size_t len); + size_t gfileWrite(GFILE *f, const char *buf, size_t len); long int gfileGetPos(GFILE *f); - bool_t gfileSetPos(GFILE *f, long int pos); + bool_t gfileSetPos(GFILE *f, long int pos); long int gfileGetSize(GFILE *f); + bool_t gfileEOF(GFILE *f); - int vfnprintg(GFILE *f, size_t maxlen, const char *fmt, va_list arg); - int fnprintg(GFILE *f, size_t maxlen, const char *fmt, ...); - #define vfprintg(f,m,a) vfnprintg(f,0,m,a) - #define fprintg(f,m,...) fnprintg(f,0,m,...) - #define vprintg(m,a) vfnprintg(gfileStdOut,0,m,a) - #define printg(m,...) fnprintg(gfileStdOut,0,m,...) + #if GFILE_NEED_PRINTG + int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg); + int fnprintg(GFILE *f, int maxlen, const char *fmt, ...); + #define vfprintg(f,m,a) vfnprintg(f,0,m,a) + #define fprintg(f,m,...) fnprintg(f,0,m,...) + #define vprintg(m,a) vfnprintg(gfileStdOut,0,m,a) + #define printg(m,...) fnprintg(gfileStdOut,0,m,...) + + #if GFILE_NEED_STRINGS + int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg); + int snprintg(char *buf, int maxlen, const char *fmt, ...); + #define vsprintg(s,m,a) vsnprintg(s,0,m,a) + #define sprintg(s,m,...) snprintg(s,0,m,...) + #endif + #endif - int vsnprintg(char *buf, size_t maxlen, const char *fmt, va_list arg); - int snprintg(char *buf, size_t maxlen, const char *fmt, ...); - #define vsprintg(s,m,a) vsnprintg(s,0,m,a) - #define sprintg(s,m,...) snprintg(s,0,m,...) #if GFILE_NEED_STDIO && !defined(GFILE_IMPLEMENTATION) #define FILE GFILE #define fopen(n,m) gfileOpen(n,m) #define fclose(f) gfileClose(f) - size_t fread(void * ptr, size_t size, size_t count, FILE *f); - size_t fwrite(const void * ptr, size_t size, size_t count, FILE *f); - int fseek(FILE *f, size_t offset, int origin); + size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f); + size_t gstdioWrite(const void * ptr, size_t size, size_t count, FILE *f); + #define fread(p,sz,cnt,f) gstdioRead(p,sz,cnt,f) + #define fwrite(p,sz,cnt,f) gstdioWrite(p,sz,cnt,f) + int gstdioSeek(FILE *f, size_t offset, int origin); + #define fseek(f,ofs,org) gstdioSeek(f,ofs,org) #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 @@ -150,13 +159,14 @@ extern "C" { #define rename(o,n) (!gfileRename(o,n)) #define fflush(f) (0) #define ftell(f) gfileGetPos(f) - typedef long int fpos_t; - int fgetpos(FILE *f, fpos_t *pos); + #define fpos_t long int + int gstdioGetpos(FILE *f, long int *pos); + #define fgetpos(f,pos) gstdioGetpos(f,pos) #define fsetpos(f, pos) (!gfileSetPos(f, *pos)) #define rewind(f) gfileSetPos(f, 0); - #define clearerr(f) do {f->err = 0; } while(0) - #define feof(f) (f->flags & GFILEFLG_EOF) - #define ferror(f) (f->err) + #define clearerr(f) (0) + #define feof(f) gfileEOF(f) + //#define ferror(f) (0) #define vfprintf(f,m,a) vfnprintg(f,0,m,a) #define fprintf(f,m,...) fnprintg(f,0,m,...) diff --git a/include/gfile/options.h b/include/gfile/options.h index 176c6270..a64937f1 100644 --- a/include/gfile/options.h +++ b/include/gfile/options.h @@ -21,12 +21,28 @@ * @{ */ /** - * @brief Include printg, fprintg, sprintg etc functions + * @brief Include printg, fprintg etc functions * @details Defaults to FALSE */ #ifndef GFILE_NEED_PRINTG #define GFILE_NEED_PRINTG FALSE #endif + /** + * @brief Include scang, fscang etc functions + * @details Defaults to FALSE + */ + #ifndef GFILE_NEED_SCANG + #define GFILE_NEED_SCANG FALSE + #endif + /** + * @brief Include the string sprintg/sscang functions + * @details Defaults to FALSE + * @pre To get sprintg functions you also need to define @p GFILE_NEED_PRINTG + * @pre To get sscang functions you also need to define @p GFILE_NEED_SCANG + */ + #ifndef GFILE_NEED_STRINGS + #define GFILE_NEED_STRINGS FALSE + #endif /** * @brief Include scang, fscang, sscang etc functions * @details Defaults to FALSE @@ -35,7 +51,7 @@ #define GFILE_NEED_SCANG FALSE #endif /** - * @brief Map all the stdio functions to their GFILE equivalent + * @brief Map many stdio functions to their GFILE equivalent * @details Defaults to FALSE * @note This replaces the functions in stdio.h with equivalents * - Do not include stdio.h as it has different conflicting definitions. @@ -46,7 +62,8 @@ /** * @brief Include the ROM file system * @details Defaults to FALSE - * @note To ensure that you are opening a file on the ROM file system, prefix + * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are + * opening a file on the ROM file system by prefixing * its name with "S|" (the letter 'S', followed by a vertical bar). * @note This requires a file called romfs_files.h to be included in the * users project. This file includes all the files converted to .h files @@ -58,7 +75,8 @@ /** * @brief Include the RAM file system * @details Defaults to FALSE - * @note To ensure that you are opening a file on the RAM file system, prefix + * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are + * opening a file on the RAM file system by prefixing * its name with "R|" (the letter 'R', followed by a vertical bar). * @note You must also define GFILE_RAMFS_SIZE with the size of the file system * to be allocated in RAM. @@ -69,7 +87,8 @@ /** * @brief Include the FAT file system driver * @details Defaults to FALSE - * @note To ensure that you are opening a file on the FAT file system, prefix + * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are + * opening a file on the FAT file system by prefixing * its name with "F|" (the letter 'F', followed by a vertical bar). * @note You must separately include the FATFS library and code. */ @@ -79,7 +98,8 @@ /** * @brief Include the operating system's native file system * @details Defaults to FALSE - * @note To ensure that you are opening a file on the native file system, prefix + * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are + * opening a file on the native file system by prefixing * its name with "N|" (the letter 'N', followed by a vertical bar). * @note If defined then the gfileStdOut and gfileStdErr handles * use the operating system equivalent stdio and stderr. @@ -94,6 +114,21 @@ * @name GFILE Optional Parameters * @{ */ + /** + * @brief Add floating point support to printg/scang etc. + */ + #ifndef GFILE_ALLOW_FLOATS + #define GFILE_ALLOW_FLOATS + #endif + /** + * @brief Can the device be specified as part of the file name. + * @note If this is on then a device letter and a vertical bar can be + * prefixed on a file name to specify that it must be on a + * specific device. + */ + #ifndef GFILE_ALLOW_DEVICESPECIFIC + #define GFILE_ALLOW_DEVICESPECIFIC FALSE + #endif /** * @brief The maximum number of open files * @note This count excludes gfileStdIn, gfileStdOut and gfileStdErr diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index 83e487a1..e42dc2af 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -91,87 +91,98 @@ void _gfileInit(void) { #endif } -bool_t gfileExists(const char *fname) { +bool_t gfileExists(const char *fname) { const GFILEVMT *p; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->exists && p->exists(fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->exists && p->exists(fname)) - return TRUE; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->exists && p->exists(fname+2); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->exists && p->exists(fname)) + return TRUE; } return FALSE; } -bool_t gfileDelete(const char *fname) { +bool_t gfileDelete(const char *fname) { const GFILEVMT *p; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->del && p->del(fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->del && p->del(fname)) - return TRUE; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->del && p->del(fname+2); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->del && p->del(fname)) + return TRUE; } return FALSE; } long int gfileGetFilesize(const char *fname) { const GFILEVMT *p; + long int res; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->filesize ? p->filesize(fname+2) : -1; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->filesize ? p->filesize(fname+2) : -1; + } + return -1; } - } else { - long int res; + #endif - for(p = FsChain; p; p = p->next) { - if (p->filesize && (res = p->filesize(fname)) != -1) - return res; - } + for(p = FsChain; p; p = p->next) { + if (p->filesize && (res = p->filesize(fname)) != -1) + return res; } return -1; } -bool_t gfileRename(const char *oldname, const char *newname) { +bool_t gfileRename(const char *oldname, const char *newname) { const GFILEVMT *p; - if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { - char ch; + #if GFILE_ALLOW_DEVICESPECIFIC + if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { + char ch; - if (oldname[0] && oldname[1] == '|') { - ch = oldname[0]; - oldname += 2; - if (newname[0] && newname[1] == '|') { - if (newname[0] != ch) - // Both oldname and newname are fs specific but different ones. - return FALSE; + if (oldname[0] && oldname[1] == '|') { + ch = oldname[0]; + oldname += 2; + if (newname[0] && newname[1] == '|') { + if (newname[0] != ch) + // Both oldname and newname are fs specific but different ones. + return FALSE; + newname += 2; + } + } else { + ch = newname[0]; newname += 2; } - } else { - ch = newname[0]; - newname += 2; - } - for(p = FsChain; p; p = p->next) { - if (p->prefix == ch) - return p->ren && p->ren(oldname, newname); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->ren && p->ren(oldname,newname)) - return TRUE; + for(p = FsChain; p; p = p->next) { + if (p->prefix == ch) + return p->ren && p->ren(oldname, newname); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->ren && p->ren(oldname,newname)) + return TRUE; } return FALSE; } @@ -233,32 +244,47 @@ static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { } GFILE *gfileOpen(const char *fname, const char *mode) { - GFILE *f; + uint16_t flags; + GFILE * f; const GFILEVMT *p; + // Get the requested mode + if (!(flags = mode2flags(mode))) + return FALSE; + + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + // Try to open the file + f->flags = flags; + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return testopen(p, f, fname+2); + } + // File not found + break; + } + } + + // No available slot + return FALSE; + } + #endif + // First find an available GFILE slot. for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { if (!(f->flags & GFILEFLG_OPEN)) { - // Get the requested mode - if (!(f->flags = mode2flags(mode))) - return FALSE; - // Try to open the file - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return testopen(p, f, fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (testopen(p, f, fname)) - return TRUE; - } + f->flags = flags; + for(p = FsChain; p; p = p->next) { + if (testopen(p, f, fname)) + return TRUE; } - // File not found - return FALSE; + break; } } @@ -267,48 +293,384 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } void gfileClose(GFILE *f) { - // Make sure it is one of the system GFILE's - if (f < gfileArr || f >= &gfileArr[GFILE_MAX_GFILES]) + if (!(f->flags & GFILEFLG_OPEN)) return; + if (f->vmt->close) + f->vmt->close(f); + f->flags = 0; } -size_t gfileRead(GFILE *f, char *buf, size_t len) { +size_t gfileRead(GFILE *f, char *buf, size_t len) { + size_t res; + if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) + return 0; + if (!f->vmt->read) + return 0; + if ((res = f->vmt->read(f, buf, len)) <= 0) + return 0; + f->pos += res; + return res; } -size_t gfileWrite(GFILE *f, const char *buf, size_t len) { +size_t gfileWrite(GFILE *f, const char *buf, size_t len) { + size_t res; + if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) + return 0; + if (!f->vmt->write) + return 0; + if ((res = f->vmt->write(f, buf, len)) <= 0) + return 0; + f->pos += res; + return res; } -long int gfileGetPos(GFILE *f) { - +long int gfileGetPos(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return 0; + return f->pos; } bool_t gfileSetPos(GFILE *f, long int pos) { - + if (!(f->flags & GFILEFLG_OPEN)) + return FALSE; + if (!f->vmt->setpos || !f->vmt->setpos(f, pos)) + return FALSE; + f->pos = pos; } -long int gfileGetSize(GFILE *f) { - +long int gfileGetSize(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return 0; + if (!f->vmt->getsize) + return 0; + return f->vmt->getsize(f); } +bool_t gfileEOF(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return TRUE; + if (!f->vmt->eof) + return TRUE; + return f->vmt->eof(f); +} + +/******************************************************** + * String VMT routines + ********************************************************/ +#if GFILE_NEED_STRINGS && (GFILE_NEED_PRINTG || GFILE_NEED_SCANG) + #include + + // Special String VMT + static int StringRead(GFILE *f, char *buf, int size) { + memcpy(buf, (char *)f->obj+f->pos, size); + return size; + } + static int StringWrite(GFILE *f, const char *buf, int size) { + memcpy((char *)f->obj+f->pos, buf, size); + return size; + } + static const GFILEVMT StringVMT = { + 0, // next + 0, // flags + '_', // prefix + 0, 0, 0, 0, + 0, 0, StringRead, StringWrite, + 0, 0, 0, + }; +#endif + /******************************************************** * printg routines ********************************************************/ #if GFILE_NEED_PRINTG + #include + + #define MAX_FILLER 11 + #define FLOAT_PRECISION 100000 + + int fnprintg(GFILE *f, int maxlen, const char *fmt, ...) { + int res; + va_list ap; + + va_start(ap, fmt); + res = vfnprintg(f, maxlen, fmt, ap); + va_end(ap); + return res; + } + + static char *ltoa_wd(char *p, long num, unsigned radix, long divisor) { + int i; + char * q; + + if (!divisor) divisor = num; + + q = p + MAX_FILLER; + do { + i = (int)(num % radix); + i += '0'; + if (i > '9') + i += 'A' - '0' - 10; + *--q = i; + num /= radix; + } while ((divisor /= radix) != 0); + + i = (int)(p + MAX_FILLER - q); + do { + *p++ = *q++; + } while (--i); + + return p; + } + + int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg) { + int ret; + char *p, *s, c, filler; + int i, precision, width; + bool_t is_long, left_align; + long l; + #if GFILE_ALLOW_FLOATS + float f; + char tmpbuf[2*MAX_FILLER + 1]; + #else + char tmpbuf[MAX_FILLER + 1]; + #endif + + ret = 0; + if (maxlen < 0) + return 0; + if (!maxlen) + maxlen = -1; + + while (*fmt) { + if (*fmt != '%') { + gfileWrite(f, fmt, 1); + ret++; if (--maxlen) return ret; + fmt++; + continue; + } + fmt++; + + p = s = tmpbuf; + left_align = FALSE; + filler = ' '; + width = 0; + precision = 0; + + if (*fmt == '-') { + fmt++; + left_align = TRUE; + } + if (*fmt == '.') { + fmt++; + filler = '0'; + } + + while (1) { + c = *fmt++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c == '*') + c = va_arg(ap, int); + else + break; + width = width * 10 + c; + } + if (c == '.') { + while (1) { + c = *fmt++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c == '*') + c = va_arg(ap, int); + else + break; + precision = precision * 10 + c; + } + } + /* Long modifier.*/ + if (c == 'l' || c == 'L') { + is_long = TRUE; + if (*fmt) + c = *fmt++; + } + else + is_long = (c >= 'A') && (c <= 'Z'); + + /* Command decoding.*/ + switch (c) { + case 0: + return ret; + case 'c': + filler = ' '; + *p++ = va_arg(ap, int); + break; + case 's': + filler = ' '; + if ((s = va_arg(ap, char *)) == 0) + s = "(null)"; + if (precision == 0) + precision = 32767; + for (p = s; *p && (--precision >= 0); p++); + break; + case 'D': + case 'd': + if (is_long) + l = va_arg(ap, long); + else + l = va_arg(ap, int); + if (l < 0) { + *p++ = '-'; + l = -l; + } + p = ltoa_wd(p, l, 10, 0); + break; + #if GFILE_ALLOW_FLOATS + case 'f': + f = (float) va_arg(ap, double); + if (f < 0) { + *p++ = '-'; + f = -f; + } + l = f; + p = ltoa_wd(p, l, 10, 0); + *p++ = '.'; + l = (f - l) * FLOAT_PRECISION; + p = ltoa_wd(p, l, 10, FLOAT_PRECISION / 10); + break; + #endif + case 'X': + case 'x': + c = 16; + goto unsigned_common; + case 'U': + case 'u': + c = 10; + goto unsigned_common; + case 'O': + case 'o': + c = 8; + unsigned_common: + if (is_long) + l = va_arg(ap, long); + else + l = va_arg(ap, int); + p = ltoa_wd(p, l, c, 0); + break; + default: + *p++ = c; + break; + } + + i = (int)(p - s); + if ((width -= i) < 0) + width = 0; + if (left_align == FALSE) + width = -width; + if (width < 0) { + if (*s == '-' && filler == '0') { + gfileWrite(f, s++, 1); + ret++; if (--maxlen) return ret; + i--; + } + do { + gfileWrite(f, &filler, 1); + ret++; if (--maxlen) return ret; + } while (++width != 0); + } + while (--i >= 0) { + gfileWrite(f, s++, 1); + ret++; if (--maxlen) return ret; + } + while (width) { + gfileWrite(f, &filler, 1); + ret++; if (--maxlen) return ret; + width--; + } + } + return ret; + } + + #if GFILE_NEED_STRINGS + int snprintg(char *buf, int maxlen, const char *fmt, ...) { + int res; + GFILE f; + va_list ap; + + if (maxlen <= 1) { + if (maxlen == 1) + *buf = 0; + return 0; + } + f.flags = GFILEFLG_OPEN|GFILEFLG_WRITE; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + va_start(ap, fmt); + res = vfnprintg(&f, maxlen-1, fmt, ap); + va_end(ap); + buf[res] = 0; + return res; + } + int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg) { + int res; + GFILE f; + + if (maxlen <= 1) { + if (maxlen == 1) + *buf = 0; + return 0; + } + f.flags = GFILEFLG_OPEN|GFILEFLG_WRITE; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + res = vfnprintg(&f, maxlen-1, fmt, arg); + buf[res] = 0; + return res; + } + #endif #endif /******************************************************** * scang routines ********************************************************/ #if GFILE_NEED_SCANG + #error "GFILE-SCANG: Not implemented yet" #endif /******************************************************** * stdio emulation routines ********************************************************/ -#ifndef GFILE_NEED_STDIO - #define GFILE_NEED_STDIO FALSE +#if GFILE_NEED_STDIO + size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f) { + return gfileRead(f, ptr, size*count)/size; + } + size_t gstdioWrite(const void * ptr, size_t size, size_t count, FILE *f) { + return gfileWrite(f, ptr, size*count)/size; + } + int gstdioSeek(FILE *f, size_t offset, int origin) { + switch(origin) { + case SEEK_SET: + break; + case SEEK_CUR: + offset += f->pos; + break; + case SEEK_END: + offset += gfileGetSize(f); + break; + default: + return -1; + } + return gfileSetPos(f, offset) ? 0 : -1; + } + int gstdioGetpos(FILE *f, long int *pos) { + if (!(f->flags & GFILEFLG_OPEN)) + return -1; + *pos = f->pos; + return 0; + } #endif #endif /* GFX_USE_GFILE */ diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index ccf1d40a..df5e7861 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -26,17 +26,19 @@ static bool_t NativeDel(const char *fname); static bool_t NativeExists(const char *fname); static long int NativeFilesize(const char *fname); static bool_t NativeRen(const char *oldname, const char *newname); -static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode); +static bool_t NativeOpen(GFILE *f, const char *fname); static void NativeClose(GFILE *f); static int NativeRead(GFILE *f, char *buf, int size); -static int NativeWrite(GFILE *f, char *buf, int size); +static int NativeWrite(GFILE *f, const char *buf, int size); static bool_t NativeSetpos(GFILE *f, long int pos); static long int NativeGetsize(GFILE *f); static bool_t NativeEof(GFILE *f); static const GFILEVMT FsNativeVMT = { GFILE_CHAINHEAD, // next - #if !defined(WIN32) && !GFX_USE_OS_WIN32 + #if defined(WIN32) || GFX_USE_OS_WIN32 + GFSFLG_TEXTMODES| + #else GFSFLG_CASESENSITIVE| #endif GFSFLG_WRITEABLE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags @@ -84,11 +86,9 @@ static bool_t NativeOpen(GFILE *f, const char *fname) { } static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } static int NativeRead(GFILE *f, char *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } -static int NativeWrite(GFILE *f, char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, const char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } static bool_t NativeSetpos(GFILE *f, long int pos) { - if (fseek((FILE *)f->obj, pos, SEEK_SET)) return FALSE; - f->pos = pos; - return TRUE; + return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; } static long int NativeGetsize(GFILE *f) { struct stat st; diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 170b9a6c..5a780554 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -30,7 +30,7 @@ static const ROMFS_DIRENTRY const *FsROMHead = ROMFS_DIRENTRY_HEAD; static bool_t ROMExists(const char *fname); static long int ROMFilesize(const char *fname); -static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode); +static bool_t ROMOpen(GFILE *f, const char *fname); static void ROMClose(GFILE *f); static int ROMRead(GFILE *f, char *buf, int size); static bool_t ROMSetpos(GFILE *f, long int pos); From a6c22fc364c25e8673488f0f5c36e3538546d898 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Sun, 2 Feb 2014 20:01:54 +0100 Subject: [PATCH 05/23] added _gfileDeinit() dummy --- src/gfile/gfile.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index e42dc2af..59dade1f 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -68,10 +68,8 @@ GFILE *gfileStdErr; */ static const GFILEVMT const * FsChain = GFILE_CHAINHEAD; -/** - * The init routine - */ -void _gfileInit(void) { +void _gfileInit(void) +{ #if GFILE_NEED_NATIVEFS NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ; NativeStdIn.vmt = &FsNativeVMT; @@ -91,6 +89,11 @@ void _gfileInit(void) { #endif } +void _gfileDeinit(void) +{ + /* ToDo */ +} + bool_t gfileExists(const char *fname) { const GFILEVMT *p; From 79d913f16dbaa17520521c645176cdbbffbb746a Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 3 Feb 2014 18:16:22 +1000 Subject: [PATCH 06/23] More gFile stuff --- include/gfile/gfile.h | 75 ++++++++------ src/gfile/gfile.c | 233 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 264 insertions(+), 44 deletions(-) diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h index bc476956..9d171050 100644 --- a/include/gfile/gfile.h +++ b/include/gfile/gfile.h @@ -82,32 +82,6 @@ extern GFILE *gfileStdOut; /* External declarations. */ /*===========================================================================*/ -//TODO -//FILE * tmpfile ( void ); // Auto-deleting -//char * tmpnam ( char * str ); -//L_tmpnam - Minimum length for temporary file name -//FILENAME_MAX - Maximum length of file names (constant ) -// FOPEN_MAX - Potential limit of simultaneous open streams (constant ) -// TMP_MAX - Number of temporary files (constant ) -//FILE * freopen ( const char * filename, const char * mode, FILE * stream ); -//setbuf -//setvbuf -//fflush -//fscanf -//scanf -//sscanf -//vscanf -//vsscanf -//fgetc -//fgets -//fputc -//fputs -//getc -//getchar -//puts -//ungetc -//void perror (const char * str); - #ifdef __cplusplus extern "C" { #endif @@ -136,13 +110,32 @@ extern "C" { #if GFILE_NEED_STRINGS int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg); int snprintg(char *buf, int maxlen, const char *fmt, ...); - #define vsprintg(s,m,a) vsnprintg(s,0,m,a) - #define sprintg(s,m,...) snprintg(s,0,m,...) + #define vsprintg(s,m,a) vsnprintg(s,0,m,a) + #define sprintg(s,m,...) snprintg(s,0,m,...) #endif #endif + #if GFILE_NEED_SCANG + int vfscang(GFILE *f, const char *fmt, va_list arg); + int fscang(GFILE *f, const char *fmt, ...); + #define vscang(f,a) vfscang(gfileStdIn,f,a) + #define scang(f,...) fscang(gfileStdIn,f,...) + + #if GFILE_NEED_STRINGS + int vsscang(const char *buf, const char *fmt, va_list arg); + int sscang(const char *buf, const char *fmt, ...); + #endif + #endif #if GFILE_NEED_STDIO && !defined(GFILE_IMPLEMENTATION) + #define stdin gfileStdIn + #define stdout gfileStdOut + #define stderr gfileStdErr + #define FILENAME_MAX 256 // Use a relatively small number for an embedded platform + #define L_tmpnam FILENAME_MAX + #define FOPEN_MAX GFILE_MAX_GFILES + #define TMP_MAX GFILE_MAX_GFILES + #define P_tmpdir "/tmp/" #define FILE GFILE #define fopen(n,m) gfileOpen(n,m) #define fclose(f) gfileClose(f) @@ -164,9 +157,7 @@ extern "C" { #define fgetpos(f,pos) gstdioGetpos(f,pos) #define fsetpos(f, pos) (!gfileSetPos(f, *pos)) #define rewind(f) gfileSetPos(f, 0); - #define clearerr(f) (0) #define feof(f) gfileEOF(f) - //#define ferror(f) (0) #define vfprintf(f,m,a) vfnprintg(f,0,m,a) #define fprintf(f,m,...) fnprintg(f,0,m,...) @@ -176,6 +167,30 @@ extern "C" { #define snprintf(s,n,m,...) snprintg(s,n,m,...) #define vsprintf(s,m,a) vsnprintg(s,0,m,a) #define sprintf(s,m,...) snprintg(s,0,m,...) + //TODO + //void clearerr ( FILE * stream ); + //int ferror ( FILE * stream ); + //FILE * tmpfile ( void ); // Auto-deleting + //char * tmpnam ( char * str ); + //char * mktemp (char *template); + //FILE * freopen ( const char * filename, const char * mode, FILE * stream ); + //setbuf + //setvbuf + //fflush + //fscanf + //scanf + //sscanf + //vscanf + //vsscanf + //fgetc + //fgets + //fputc + //fputs + //getc + //getchar + //puts + //ungetc + //void perror (const char * str); #endif #ifdef __cplusplus diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index 59dade1f..f9c306e4 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -68,8 +68,10 @@ GFILE *gfileStdErr; */ static const GFILEVMT const * FsChain = GFILE_CHAINHEAD; -void _gfileInit(void) -{ +/** + * The init routine + */ +void _gfileInit(void) { #if GFILE_NEED_NATIVEFS NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ; NativeStdIn.vmt = &FsNativeVMT; @@ -296,7 +298,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } void gfileClose(GFILE *f) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return; if (f->vmt->close) f->vmt->close(f); @@ -306,7 +308,7 @@ void gfileClose(GFILE *f) { size_t gfileRead(GFILE *f, char *buf, size_t len) { size_t res; - if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) + if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) return 0; if (!f->vmt->read) return 0; @@ -319,7 +321,7 @@ size_t gfileRead(GFILE *f, char *buf, size_t len) { size_t gfileWrite(GFILE *f, const char *buf, size_t len) { size_t res; - if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) + if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) return 0; if (!f->vmt->write) return 0; @@ -330,13 +332,13 @@ size_t gfileWrite(GFILE *f, const char *buf, size_t len) { } long int gfileGetPos(GFILE *f) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return 0; return f->pos; } bool_t gfileSetPos(GFILE *f, long int pos) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return FALSE; if (!f->vmt->setpos || !f->vmt->setpos(f, pos)) return FALSE; @@ -344,7 +346,7 @@ bool_t gfileSetPos(GFILE *f, long int pos) { } long int gfileGetSize(GFILE *f) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return 0; if (!f->vmt->getsize) return 0; @@ -352,7 +354,7 @@ long int gfileGetSize(GFILE *f) { } bool_t gfileEOF(GFILE *f) { - if (!(f->flags & GFILEFLG_OPEN)) + if (!f || !(f->flags & GFILEFLG_OPEN)) return TRUE; if (!f->vmt->eof) return TRUE; @@ -367,12 +369,16 @@ bool_t gfileEOF(GFILE *f) { // Special String VMT static int StringRead(GFILE *f, char *buf, int size) { - memcpy(buf, (char *)f->obj+f->pos, size); - return size; + // size must be 1 for a complete read + if (!((char *)f->obj)[f->pos]) + return 0; + buf[0] = ((char *)f->obj)[f->pos]; + return 1; } static int StringWrite(GFILE *f, const char *buf, int size) { - memcpy((char *)f->obj+f->pos, buf, size); - return size; + // size must be 1 for a complete write + ((char *)f->obj)[f->pos] = buf[0]; + return 1; } static const GFILEVMT StringVMT = { 0, // next @@ -640,7 +646,206 @@ bool_t gfileEOF(GFILE *f) { * scang routines ********************************************************/ #if GFILE_NEED_SCANG - #error "GFILE-SCANG: Not implemented yet" + int fscang(GFILE *f, const char *fmt, ...) { + int res; + va_list ap; + + va_start(ap, fmt); + res = vfscang(f, fmt, ap); + va_end(ap); + return res; + } + + int vfscang(GFILE *f, const char *fmt, va_list arg) { + int res, width, size, base; + char c; + bool_t assign; + void *p; + + for(res = 0; *fmt; fmt++) { + switch(*fmt) { + case ' ': case '\t': case '\r': case '\n': case '\v': case '\f': + break; + + case '%': + fmt++; + assign = TRUE; + width = 0; + size = 1; + + if (*fmt == '*') { + fmt++; + assign = FALSE; + } + while(*fmt >= '0' && *fmt <= '9') + width = width * 10 + (*fmt++ - '0'); + if (*fmt == 'h') { + fmt++; + size = 0; + } else if (*fmt == 'l') { + fmt++; + size = 2; + } else if (*fmt == 'L') { + fmt++; + size = 3; + } + switch(*fmt) { + case 0: + return res; + case '%': + goto matchchar; + case 'c': + if (!width) { + while(1) { + if (!gfileRead(f, &c, 1)) return res; + switch(c) { + case ' ': case '\t': case '\r': + case '\n': case '\v': case '\f': continue; + } + break; + } + width = 1; + } else { + if (!gfileRead(f, &c, 1)) return res; + } + if (assign) { + p = va_arg(ap, char *); + res++; + *((char *)p)++ = c; + } + while(--width) { + if (!gfileRead(f, &c, 1)) return res; + if (assign) *((char *)p)++ = c; + } + break; + case 's': + while(1) { + if (!gfileRead(f, &c, 1)) return res; + switch(c) { + case ' ': case '\t': case '\r': + case '\n': case '\v': case '\f': continue; + } + break; + } + if (assign) { + p = va_arg(ap, char *); + res++; + *((char *)p)++ = c; + } + if (width) { + while(--width) { + if (!gfileRead(f, &c, 1)) { + if (assign) *((char *)p) = 0; + return res; + } + if (assign) *((char *)p)++ = c; + } + } else { + while(1) { + if (!gfileRead(f, &c, 1)) { + if (assign) *((char *)p) = 0; + return res; + } + switch(c) { + case ' ': case '\t': case '\r': + case '\n': case '\v': case '\f': break; + default: + if (assign) *((char *)p)++ = c; + continue; + } + break; + } + //ungetch(c); + } + if (assign) *((char *)p) = 0; + break; + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'b': + /* + while (isspace (*buf)) + buf++; + if (*s == 'd' || *s == 'u') + base = 10; + else if (*s == 'x') + base = 16; + else if (*s == 'o') + base = 8; + else if (*s == 'b') + base = 2; + if (!width) { + if (isspace (*(s + 1)) || *(s + 1) == 0) + width = strcspn (buf, ISSPACE); + else + width = strchr (buf, *(s + 1)) - buf; + } + strncpy (tmp, buf, width); + tmp[width] = '\0'; + buf += width; + if (!noassign) + atob (va_arg (ap, u_int32_t *), tmp, base); + } + if (!noassign) + count++; + */ + + #if GFILE_ALLOW_FLOATS + case 'e': case 'f': case 'g': + #endif + default: + return res; + } + + break; + + default: + matchchar: + while(1) { + if (!gfileRead(f, &c, 1)) return res; + switch(c) { + case ' ': case '\t': case '\r': + case '\n': case '\v': case '\f': continue; + } + break; + } + if (c != *fmt) return res; + break; + } + } + return res; + } + + #if GFILE_NEED_STRINGS + int sscang(const char *buf, const char *fmt, ...) { + int res; + GFILE f; + va_list ap; + + f.flags = GFILEFLG_OPEN|GFILEFLG_READ; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + va_start(ap, fmt); + res = vfscang(&f, fmt, ap); + va_end(ap); + return res; + } + + int vsscang(const char *buf, const char *fmt, va_list arg) { + int res; + GFILE f; + + f.flags = GFILEFLG_OPEN|GFILEFLG_READ; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + res = vfscang(&f, fmt, arg); + return res; + } + #endif #endif /******************************************************** From 888a5d065640ff601e07bc35710daec2c4e6cc0b Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 5 Feb 2014 08:45:28 +1000 Subject: [PATCH 07/23] Update file2c tool to enable creation of directory entries for the ROM file system. --- include/gfile/gfile.h | 5 -- include/gfile/options.h | 6 +- tools/file2c/binaries/windows/file2c.exe | Bin 9728 -> 22030 bytes tools/file2c/src/Makefile.mingw32 | 10 +++ tools/file2c/src/file2c.c | 95 +++++++++++++++-------- 5 files changed, 77 insertions(+), 39 deletions(-) create mode 100644 tools/file2c/src/Makefile.mingw32 diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h index 9d171050..6cd2d9ad 100644 --- a/include/gfile/gfile.h +++ b/include/gfile/gfile.h @@ -177,11 +177,6 @@ extern "C" { //setbuf //setvbuf //fflush - //fscanf - //scanf - //sscanf - //vscanf - //vsscanf //fgetc //fgets //fputc diff --git a/include/gfile/options.h b/include/gfile/options.h index a64937f1..55c37f8e 100644 --- a/include/gfile/options.h +++ b/include/gfile/options.h @@ -65,9 +65,9 @@ * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are * opening a file on the ROM file system by prefixing * its name with "S|" (the letter 'S', followed by a vertical bar). - * @note This requires a file called romfs_files.h to be included in the - * users project. This file includes all the files converted to .h files - * using the file2c utility using the "-r" flag. + * @note This requires a file called romfs_files.h to be in the + * users project include path. This file should include all the files + * converted to .h files using the file2c utility (using flags "-dbcs"). */ #ifndef GFILE_NEED_ROMFS #define GFILE_NEED_ROMFS FALSE diff --git a/tools/file2c/binaries/windows/file2c.exe b/tools/file2c/binaries/windows/file2c.exe index 333b11383dd11ca03c20c72462fb8f7350a34b05..dc530bf904193e21b279af39407c0893d60dbd04 100644 GIT binary patch literal 22030 zcmeHveS8$vx&PVCBAXX7D+Y-gWyFoV7y{AQCK_}h*?^kZ2nnJjhLG$+bV>5b&H^gP z(%D6(rF6C<`S+K1 zn96>CdF6^muh`Psyu7t;rC49r)YL4A%UoisuSsld5=*|ZP+ZyE;L060F2!z;u5dC| zX0o#JOFvn_7U`Y+Oh`&KnJ2QV(O!UZ9?Aq18%hNVNk`9SU2YQ|Nq+tb;~S0nSDLt9 zjEOodArKBeMx{5}088}$Uq8VWyA%Tg38N&(7<58xa#^Yso7jklnrpg2%Q zd#(XLNtY+84y#GauzJ2;wJ(-CnVCLR%IH&t@KLmo0+6wYShczle_!ILjY8mlh$?*hdl>hhm?8wOMbm#`y1PvX)bYp3 zLf}t;4TeKSNm5ErQnlP=Dm>{MRGrUj27U6va(UQf2pqjR9*_G^R11M` zaB0^If#36oB|^}HA$2wxuk&wX} zUQg0`NWbX}x1X^19jN=CU{t$yY_ACN z(3q=Uy5lMda(R~%vcM}_TV?!*A{z6?g#DHNxo3k>(C@E{qjq*2B`=*_TrLl@U}ez}LR7QNpyXKx?mKp zpUzC1KxFpDqt}cc<1CI}u8&Q`Slb9hqN%-&!QeqIsu1`bR)xv4w5O1jVAZVX`{)U^ z1CWJwB1wVJKo%q<*6|5HKyYiZ6M%ptMva?KkNB{7h0`#{iKUi?IZ$WFQc3{J_30#KUNL-h{QzByx*EWH*`FkcWuqa_s9$Xr|W- zl`iP#zu$CS$YCa_tD&Ay(nr&Dv8V^^Omu}Rkk|z0Th#ABKN4|;32nJMQ|VjMHEch` zf2Q^m!|S;~gg%)06F7>L)B~Ax3_}d~5015yG3B8o$<{%xl)JNbr!hXC)JpqQN+kdi zF$1k+o=l{j5pbj8f!4wddG=CdJTnoNQX*q`gUAk1}*^Y<(7Qfr8oQlj`g$|BS48AAeSC|f3&{bANsljb6F<>D(h`! z>ILGgkOu+i(f17wgD3j!3Y@;2^RW^A5v1iIhww;={W7qmdXlyYto&>3lbEy_)n!b2 z5Ez`O5ka#^kp$84I?-q?CKFWV>kcUklLcTh?Qx_+ciZ;Ghzx}3*e-nevGv}gqvfwbI}w&5go3bKrGp?#rM^;*yBL*E zh(Z9TR6JOPKo}30(-vqn0FB^He!9^1VnOD7bi&?Tb)n@&3xGr4e2o%7qvB%nk7qFT@ycgb7 z-q`SatRitY>@fe0X}^8Z42~NU~MXkU!;zMY+3GGLf&w-21zyakb zkaaAOAk&XPzLAiB2fuCTB(l?9;aVjX5M_8IQ@e}+eyXo}WR?zc^ow6$olJbTTd@|X zT&K?HGT-XOv`1K8=x5jZ^qPS3>B(S<;=q(LGOAi=cEi;0KQ zCC#JxW{_2q_(UtVXurVlb`nzIqACdP0Wv;U;W-Q{N6;~n!7jKu9{X0pzFZ)Tix6cj zOqds5(v`rk1im^UVS)qFWvaQb&v$<8mV`a6g@2MJDZACVR$!AeINNK12Brovb-q=( znJ;}+IG-e7&evgLZvpoSE`M+Aps}9PDp%5q#V$#zNi3B-9=NRFw1PhX%-3(wi;N+= z(ntFZxPW_X5Aq9jBHE_t!(`91(UTt4%m~}q!wKO628q2I?e1gWNyP7M6|?CsBvfWk zYn`wmO3!jKn?W@nSRI?ziH^m0U>R}azbbyZwFtX1alDgH)+p}?0lHR@PtFhmKj9BG z%AwF2lXNY*BnRRsM?O_8Z0VFw%@nqTlRE?Zlp$Yc;hREW6TpRCla$W^PNWX`_P5bq z+p^@Y+8QH&3cD7Y{3mOKz|#N@9#jrV?-afhT4NSM$IwyuM#yQB#us)8n~@mk@Df@P zFZ{^&u?ped6)~TL_OV64o&ZA?t(R_-BPN{wK8pRI@HNRpwCTKa6QV~)!1=b_=05?1 z0Lb}Itd|4;1P=JLXgz>HFSyT_CA3!%UhMF2d!7k|V~?Xv{V(V3i(W|J*!H47y2hX% zHbEwxfi#7PkJpJ0M9(8=zKtG9|6QWjZ2=HBh`!!}{!T?J>{{n4+%2Vt?lBc=(mYu+ z74G(Zt}DS+mac@l<8^gEjy{E07^a^gwCnN`{m?v9^jjDu`FrG(a8ajx67GVdq6?^> z8tBq}7rk+q(C~gf2UA(Xve|>lpM|Vx$2vAuxh?LSo!XCIJl=d@vh$X3aStAxYm@qkNkv}r|KF$kcGG`&1h*(1GSVE@C z-8n{l=<%52zb;oPvqLj1V|T#U${u8sjL>~1xnIO0o=L52qMQBL@?1_CKpI9#hC!t%|Rb`U*m_e#Ui`vkk%d5OO z?NIbuYU=j`{^Pkq;4wtOF<6vj6oPGN3A;LFEjM}@0EvC5#tfl*PjaEpSKf)<&pDiT ztS@?!pxd41q8en~Tic+00GDJ!ds0!2G{0y)rY=^E;Ghq;F~uf~#@^|ufvnLk;8F99 zjvJ}D1I>;l^hC=u&d_w?57i`rbW&^w0Kt@I)$K}zmOvX;W3@Id)DrJ}-y94-aFKeu zRsI+&>cw)G1s>EMx&ZNZD(?GGoyQaVT55OOuyov2%McTXvbfKd2 zmHdv-9FuyB)wG+)Da96|$mf79V!;$?dyA0Eh}MOW#q&`a6A^RKcIye)gBv<2pzFPQzFpM@5A?(O4WYFxmPKFQo;UUGvIN)l*2Z17 z9-r2Yptq`3d$I3N0|;6c?dt#|@Z~sk8CQ_Fl*BEW_J$q`){yHn9{y@oN8Ucww_pB1 z#PPgT*kumgNjG&x@O-j7ge$#z2@%_Oa1gI zAxQG~IG?SKIO#OU)bf7Sq?Er-TivT6zgo3lE#Dt;hRx*9_beOUWqug1YMWBtE3XS9 zF?~U449cY7GLLpkLSQdo)pZ@gxDddlDM-AonhD|v7Hh@1Q!U?_xbW>XE9KAg^@6;e ziEK)IdFJxUp`{SI7e z3&C}ioy)r^ZSN*?A&P6BQ+?eyIXi&=T5PTgWbhUgdf^|}GP+4P*IN(miJAE-J6`VJ7 z*Ogk-s&1rHr?XpecH`QYToK~V6oNiP)F}V(dvhsOt+L`tyAs)(yI0{A(zQ?UE$rcNp{zJx$8|XX$~mHnemdjhAzikc_b{fhfST) z2%TYQ+LKM0|+}JWVuV5G<=!a_JJzf2UftRcJ3sOD(FF@{49lvyg9} z-DF8o_F|V3{Tqo@WmSf>HxNzyScV8ksIur6l%By)b?%JPc~W(5BSprOyVgBPA)SWF zrCm#0^bBc4w_5&W{MBHXr&yuH8HSgm?-DV6Ju==C{B<1gs`i?87gp^R zDu5*pFQ^miRS`6!b0%y=2Qspic7*3WtiLHVfxZP!N)N&0K-&b&eu6nDjqzX4d|nLF z0?pqFP>JZ@<8GoorJVIRKmv7f_wW>!?@#KjVk4bP5YGcep-GBgHq!} zB3;#w(<3s1J7SrOnB7PRCbjCY@IuCTw|t`7tyCS7Qt*VJR(O)^$EZ@?C%jO8$bEg; zc)V=95dypAb%&S`IKd|-2AzkL<8FDVnsA4Jdp!n(7tUAq5>a2895xFt*yvgMjEGAg zyOC7Wv2M)AfWz#@ni4Kt*C)ucIn%z-yi9=BXjjbo&=N_e5dtPEisnVyUX45U5mZ2A%5d{^@e- z7#ChBOSbUj-^VTDMjv^mT1uq~e%L_nb@qY2o0gtL5P_5tLtOUH5zjbXV}U*$xi6wm zkK8U=xUn-q*donav)x(dObyOP{qQ8;4hK1qWgyhPv?R|WFa_{Q1S3W)ggCb1!!KzX;xTtem0H+|2iX4 z3!XTs{xV$&pkB{_`vb*ym+cSPYBD`dGXrWmsd5eYRgGtj)hU7WG!ql2H zolkNX$YCqeBLq}p`E&ukuMQ^6;P@R8g?r8&deBO7Hv z3gxj`7>sPp$2WZ<*q)OzboAcPO}12y@N`7^_P=NtYzDF}pw;y)IEpsI2grG_Q#Fi# zc4E;-01{ec#V;BD_+lv}`SjVyMv@TW6W6YRaB{(g(p1c>yg}_VyjYFijsau7Xcu5S zZ!p3jHH+Rr7$)>Y7!IQ>_PaLiQy@ebZPub9jlPdI!Q=LUMbl3cGR`|22Fl2ATkS=t z)UEakYVEK)sM={Sq3SvNd{jXk{qIDr%4EinH;2E0Qy!+4uz4e>Yiqztof^V*135yK zNhewnet>=?5ZbuX9ft}4;48&eJY^|(>AxEfBDr@Vj(g*|Q=so(b<1 z$1?5jkRb1%JT%_-ZLJQ^%GB6KPEUvY2)llB>}AATPqCGS?oa;Zl-Q580suxBk|~QW zf}=P*y}wlHD)*pdKW))l0f~iWJZ(Y_V1G%shPWvQJ?&F8bs`<05s!Uf1kSL(Non|- zoC6bZNAIwc7vXQ3#^5ymG^fKLhpqlp?cav!0*fQ-SgMYNc?8_9wuJXXGSO1t{ci!0 zyx$|;14m~56K?0zyZE&CLHt?}SAIp}M0i}nb}YJtq8xss)MNOq)bLy0NWb|mg1>x1 zga;}aD|$J;;J(;E!lAKuMmlVF!dnw#KR3*Zmmbi{1{0;IezGFobaZJ=2$GRb_-Ocj zG~L%Be*+L2yDZi z3Bwb_6S243v@5_-&t4;d6MmQy`_V}MJlfV4&mQ=WgHgTHsJ9q(n^A8y>W7Tl`duA9 z$EY)mS~JGqHtN@ny3eSm8gTtayVt0*jQ+6Ewi)d&jCPvQ&Nu3AqkqV#_Z#(LqdsEP zvkZ7<)S^*m8uc~<&SJC+jQTU9|9PW++NkZu_;W`4Nu%}{b)`{P7|s*x+^NYfd~H*ueTooVisXyFGVHgu;1QFo3~Vev zS?1vRj(+H+PS^phumg2qlY|9J2>hLvD9q_7YJ%QR&{(RT1Tqd)$09ubN!Kx-HkiQ|s8MMz@Lz|DNv zxDB}cM+GD`4shDf^zkxwTB*Vj=$kQ&>$(h_C;92t7}HjvKVd8E*+*(Jn>3-z1h6H^ zdPri)UJ|qN{M5s0NybWI0`p%>4DfzBa8MdYR@K%X1ZDiZ0zf=q@&?h(mmCH{glf`# z;@AKRxck*k;O+q)#GbYnL!m_`+=^A&=L>;aG=W@1_dI?)3+>|wDQ~btfhA&-xI9Ap zX6iiFgIhJ$;m5#BG>ZKDy<(F1Z$sus8<2u=o~pJxuox(2 zVV5<4SiS*14BgwQob;c}U$s#Gp$kzW$sYz`1t%tlg7XgWw3(m@33<#sO@nloO^3e{ zB1&Ld8bCTo<;11hh7alY5^?*lw={5sGUc`C?_fnRC};qUXcOeZj>Qqe4=}d#=zz-i5Ut62gO*DcrFTGvLZB2arY1rTA(c7w0CH%)#lsQ{c$2n4*z0ItOQ3g829G|~h@x&=syD1-AydjE0YYkjyS zGUm%TNC?_FgN`&&2)+j3!FlxbLp+h*h4>AKL_38X1x9^^F6Ft6#X`*dKLD9r+=1@A zaP+%itLK;CHgXXEkt~F^x<||4SO$f;JIQTeqRj(==vAaD&p)In^Fx5SHcCar`7gLV zBF<1aC+gANPfoFBkEZQ`b14ESz&`;_^y|8{IV>F|h&IHg>{K-Zb`Qat0GqHI|Ao+L z*q@Nyw&_BYz%co+K2K%c7yvi=@!c%wl7_JY2%V{WGy~lw=(duhv^54k$&f}-Xr#cU z#C(Rbd(ArW=fQ|Fb`nSZ)-8Fijdo#W5w`~o-j(W8h42&!kjm#BdN z<@xYu`pDGON_!DrYydg>D7xUq{S@(QF^?i*G+RgEiaxiDD{57GjT!b+;y?+F`^89f zy?`>tzeVGVFs>*69DtQU57E!*STq{fCj5~nAy`RDg&D;lxoR7m+|7&w-aRAl8Xe~5RkaHYsA5l@*X!~EufcUTOy-s9 zq{e!Y)i*bJB@wYU!!2fe8UGSzt;wEs_2L|slAL&|YPzSXd3BTM_S7vGXJpr>kW;F> zb<17XrKDtg#Thr!_mUY6%j&%~sGGzlNJ&p_(cS2wr^cohpJY5Y`=mr8C3(h;$^35= zSGYVaXssC4YDk{b&>+@{4UMg?da1efUeVPg;oIHZDoQI{;(~9Ka|WXKURY-(@Rude zZFSY%!$<2{TkG!ia^U*rl`RmY)r)~TNnG9BG({3u)HOADT%xD0b-7E_fkB}@xx`hE zK6H6S-9S@)UYFbF5v6AE_xdmd<|Ipl=xd?Bqb!BNS4;!4cO@pK_tf#sq&fRe*tUpBlULkeqM242O@K2L*4e^c7r;u=X) zoRaOGlEPMh8Af-$?lm0o_+?7Oaz354 zz3%!clXHr0xN+v%*}2s$+nepJUs2ZzB1>w-+2Z{yW!?3N>fzqnmTcdM5tedAqr1W7 zrVuP$SX*+_0_Uxj3+||$@0?ST!XQ?*ck~Dd*TP#w`fNBkT)iAI+lS&6!5d<;b0Y~-TjXGyumA5+7C;s!N`WEMB}RQN8P7AuN6LR3y4WTkN1Md}(FT3ueRnB79Y z62(NCZ1K8$4b3pLr@0<^wz-M^09$IVZ}y0*kb{9UvIpvLJxEr|kK^&V zBgY@$!~9hob)U-yS-_iT;K^oZy0|XgS_}=zK18<+-T3gYZx#dZd&+ zksgROKeaKv0&VjGUICoW*lSTN_&dW73Ez|MSSXL#Xn8OxXf}Un;LS-rmoC&#y6kv5 z9?wC|ZcVpU!wVuF^HKJr|0dKVH_Zugr7pm5BZc}1^~Mh^=Lbk zrDxrgE>@&xfx+GUyEr`!6OTKY%Rzi>&&1;o5iX!^+GsA7lWt2PtISFDrf1!jE`kaI z`j(U~L0Jpl(!1oRh!ry)_`E?ZKbSNp-L}y(Cp|+RQ=Fb@zAGg?0~*^9)@gGh z(0ot2WnOAhk_r7KXY`k*a=%L;_rp{dv+D6h#w!l2A(`_(v8WgfZAxvzt zCtb7_07oGl0F}y?n>QvsXkL`U1AJbpd2v?{pvh+RigGJpOAXi(Icfez^D1&V_pOBS z{TTlPUI6HJJ)P6dcaF+NNp&N$6Mo@E@wfx{)jQ&G`j!4^e9SzVR)%{?qHz}T1MF}Q zq|zIDjyVF{e&F)80O;rPKgA&F@;YD-pJnYa|6+uk#i>cJnntt{#OI>xFz9+ZunwHd zuchg|mZUO@AUI-FWR*~UCVwnNS@Tjn{%_ES0p2`M9#d^(kAdOrfn0}SntKB;pI&!( zK3Hz#15l(~^gK%DPUH-oUKsQ&Rpj8cx`XF}aVB8;P#nLG$ETo19N2EdT%tL<0!@mm zN{rn_G|o0(NKW(qvqWZTs&tm#`Kfhh=_PLG_8a+(%GO9cjz8Zz9UoQtI!j$&eg1n{ zpn@lPU8WU};NL>RA8c$I(dS2>AAMU!^c8&%an1j*IKI0U8tK-9zb~r*in11E6Uui{9z}T)<$08sP`Xj}qr8dIkMa@9 zXDFvotgy*=lq{5~DD?T?s`o3b#N}~Gu40_$8|&*l3vqLXBPSbR&L-R-p4rVNnw)DI zrHa<(dYolhz%Li_&MP_T&VaG=&1jc5H~2iR`TPQH4$=zs z5eZz^(UF+3L*|>Bz`xFe6YQBRbCb$kb*sMA%_Pf0msHiHU&}Q(*VMaONb=G~59DT# zSSmeUuvt{+@wwQqEyf8QTqS78*l!X&{LGGX5Uce{tqr~wwtzo1;{5Gl*W*%jxl3AE z*Vu$>KQE2dw$#?TnpQQo!btdst$5o_|0)_|jc9pYQf*yJORaQo3wj=9we>F83vthC zaf{N_%-A1UEiPgj>OIX~K=kP?cVnv;P>1wZ6aCv_r|^s$m6keb1$Gd%jm^vOXUeA9 zW(1;)N_b{jk&H@oQqjy+*^ zx3o4kNpAKeo_tb0{skyEUHGtPsD^aEFuVCh59X7((d%ugt9P-t%_|Lxhs-ONd8Ovn z_3+?(=9R9M^)2@@_KCR_j%Mtr8KgMtAu~j!+YOJ4oiKYFmp9dU82h`~YjBU7y&T1y z1Q*n=K-5_H6M0|^eedJNzI<-)rbLm(yD}l ztSAX$O3e@$lbv$mf3e)-YHf0PuDP1uo&!At_*7PUSJk&ldhb-U|CP!}*`d-`pMOyc y(A{MCLdUW literal 9728 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 diff --git a/tools/file2c/src/Makefile.mingw32 b/tools/file2c/src/Makefile.mingw32 new file mode 100644 index 00000000..470330bd --- /dev/null +++ b/tools/file2c/src/Makefile.mingw32 @@ -0,0 +1,10 @@ + +CC = i686-pc-mingw32-gcc +CFLAGS = -Wall -O2 + +all: + $(CC) $(CFLAGS) -o file2c.exe file2c.c + +clean: + @rm file2c.exe + diff --git a/tools/file2c/src/file2c.c b/tools/file2c/src/file2c.c index f7bc1e9c..1c279ff2 100644 --- a/tools/file2c/src/file2c.c +++ b/tools/file2c/src/file2c.c @@ -8,11 +8,14 @@ #include #include #include +#include +#include #ifdef WIN32 #include #endif -static unsigned char buf[1024]; +static unsigned char buf[1024]; +static char tname[FILENAME_MAX]; static char *filenameof(char *fname) { char *p; @@ -25,6 +28,13 @@ static char *filenameof(char *fname) { #endif p = strrchr(fname, '/'); if (p) fname = p+1; + return fname; +} + +static char *basenameof(char *fname) { + char *p; + + fname = filenameof(fname); p = strchr(fname, '.'); if (p) *p = 0; return fname; @@ -43,34 +53,35 @@ char * opt_progname; char * opt_inputfile; char * opt_outputfile; char * opt_arrayname; +char * opt_dirname; int opt_breakblocks; +int opt_romdir; char * opt_static; char * opt_const; FILE * f_input; FILE * f_output; unsigned blocknum; -size_t len; +size_t len, totallen; size_t i; /* Default values for our parameters */ - opt_progname = filenameof(argv[0]); - opt_inputfile = 0; - opt_outputfile = 0; - opt_arrayname = 0; - opt_breakblocks = 0; - opt_static = ""; - opt_const = ""; + opt_progname = basenameof(argv[0]); + opt_inputfile = opt_outputfile = opt_arrayname = opt_dirname = 0; + opt_breakblocks = opt_romdir = 0; + opt_static = opt_const = ""; /* Read the arguments */ while(*++argv) { if (argv[0][0] == '-') { while (*++(argv[0])) { switch(argv[0][0]) { - case '?': case 'h': goto usage; - case 'b': opt_breakblocks = 1; break; - case 'c': opt_const = "const "; break; - case 's': opt_static = "static "; break; - case 'n': opt_arrayname = *++argv; goto nextarg; + case '?': case 'h': goto usage; + case 'd': opt_romdir = 1; break; + case 'b': opt_breakblocks = 1; break; + case 'c': opt_const = "const "; break; + case 's': opt_static = "static "; break; + case 'n': opt_arrayname = *++argv; goto nextarg; + case 'f': opt_romdir = 1; opt_dirname = *++argv; goto nextarg; default: fprintf(stderr, "Unknown flag -%c\n", argv[0][0]); goto usage; @@ -82,20 +93,28 @@ size_t i; opt_outputfile = argv[0]; else { usage: - fprintf(stderr, "Usage:\n\t%s -?\n" - "\t%s [-bs] [-n name] [inputfile] [outputfile]\n" - "\t\t-?\tThis help\n" - "\t\t-h\tThis help\n" - "\t\t-b\tBreak the arrays for compilers that won't handle large arrays\n" - "\t\t-c\tDeclare the arrays as const (useful to ensure they end up in Flash)\n" - "\t\t-s\tDeclare the arrays as static\n" - "\t\t-n name\tUse \"name\" as the name of the array\n" + fprintf(stderr, "Usage:\n\n%s -?\n" + "%s [-dbcs] [-n name] [-f file] [inputfile] [outputfile]\n" + "\t-?\tThis help\n" + "\t-h\tThis help\n" + "\t-d\tAdd a directory entry for the ROM file system\n" + "\t-b\tBreak the arrays for compilers that won't handle large arrays\n" + "\t-c\tDeclare as const (useful to ensure they end up in Flash)\n" + "\t-s\tDeclare as static\n" + "\t-n name\tUse \"name\" as the name of the array\n" + "\t-f file\tUse \"file\" as the filename in the ROM directory entry\n" , opt_progname, opt_progname); return 1; } nextarg: ; } + /* Make sure we can generate a default directory name if required */ + if (opt_romdir && !opt_dirname && !opt_inputfile) { + fprintf(stderr, "If using -d you must either specify an input filename or use -f to specify a directory entry filename\n"); + goto usage; + } + /* Open the input file */ if (opt_inputfile) { f_input = fopen(opt_inputfile, @@ -129,43 +148,57 @@ size_t i; fprintf(f_output, "/**\n * This file was generated "); if (opt_inputfile) fprintf(f_output, "from \"%s\" ", opt_inputfile); fprintf(f_output, "using...\n *\n *\t%s", opt_progname); - if (opt_arrayname || opt_static[0] || opt_const[0] || opt_breakblocks) { + if (opt_arrayname || opt_static[0] || opt_const[0] || opt_breakblocks || opt_romdir) { fprintf(f_output, " -"); + if (opt_romdir) fprintf(f_output, "b"); if (opt_breakblocks) fprintf(f_output, "b"); if (opt_const[0]) fprintf(f_output, "c"); if (opt_static[0]) fprintf(f_output, "s"); if (opt_arrayname) fprintf(f_output, "n %s", opt_arrayname); + if (opt_dirname) fprintf(f_output, (opt_arrayname ? " -f %s" : "f %s"), opt_dirname); } if (opt_inputfile) fprintf(f_output, " %s", opt_inputfile); if (opt_outputfile) fprintf(f_output, " %s", opt_outputfile); fprintf(f_output, "\n *\n */\n"); /* - * Set the array name. - * We do this after printing opt_inputfile for the last time as we - * modify opt_inputfile in place to generate opt_arrayname. + * Set the array name and dir name */ if (!opt_arrayname) { if (opt_inputfile) - opt_arrayname = filenameof(opt_inputfile); - if (!opt_arrayname || !opt_arrayname[0]) - opt_arrayname = "filearray"; + opt_arrayname = basenameof(strcpy(tname, opt_inputfile)); + if (!opt_arrayname || !opt_arrayname[0]) { + srand(time(NULL)); + sprintf(tname, "filearray%u", rand()); + opt_arrayname = tname; + } } opt_arrayname = clean4c(opt_arrayname); + if (opt_romdir && !opt_dirname) + opt_dirname = filenameof(opt_inputfile); /* Read the file processing 1K at a time */ blocknum = 0; + totallen = 0; while((len = fread(buf, 1, sizeof(buf), f_input))) { if (!blocknum++) - fprintf(f_output, "%s%sunsigned char %s[] = {", opt_static, opt_const, opt_arrayname); + fprintf(f_output, "%s%schar %s[] = {", opt_static, opt_const, opt_arrayname); else if (opt_breakblocks) - fprintf(f_output, "\n};\n%s%sunsigned char %s_p%u[] = {", opt_static, opt_const, opt_arrayname, blocknum); + fprintf(f_output, "\n};\n%s%schar %s_p%u[] = {", opt_static, opt_const, opt_arrayname, blocknum); for(i = 0; i < len; i++) { fprintf(f_output, (i & 0x0F) ? " 0x%02X," : "\n\t0x%02X,", buf[i]); } + totallen += len; } fprintf(f_output, "\n};\n"); + /* Add the directory entry if required */ + if (opt_romdir) { + fprintf(f_output, "\n#ifdef ROMFS_DIRENTRY_HEAD\n"); + fprintf(f_output, "\t%s%sROMFS_DIRENTRY %s_dir = { ROMFS_DIRENTRY_HEAD, \"%s\", %u, %s };\n", opt_static, opt_const, opt_arrayname, opt_dirname, totallen, opt_arrayname); + fprintf(f_output, "\t#undef ROMFS_DIRENTRY_HEAD\n\t#define ROMFS_DIRENTRY_HEAD &%s_dir\n#endif\n", opt_arrayname); + } + /* Clean up */ if (ferror(f_input)) fprintf(stderr, "Input file read error\n"); From 9ef10b9ec669bd6af0747b083b1b61b4a041e206 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 5 Feb 2014 09:32:22 +1000 Subject: [PATCH 08/23] Add linux binary for the updated file2c tool. --- tools/file2c/binaries/linux/file2c | Bin 10801 -> 9700 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tools/file2c/binaries/linux/file2c b/tools/file2c/binaries/linux/file2c index 403c7d8f76fd919313e32f859446f76a661a46a8..5a2a5de72deadc012ae248f603068468ec7da651 100755 GIT binary patch literal 9700 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 literal 10801 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 Date: Fri, 7 Feb 2014 01:34:38 +1000 Subject: [PATCH 09/23] Add support for GFILEs based on BaseFileStreams and Memory Pointers --- include/gfile/gfile.h | 13 +++++-- include/gfile/options.h | 35 +++++++++++------- src/gfile/gfile.c | 76 ++++++++++++++++++++++++++++++++++++++- src/gfile/inc_chibiosfs.c | 46 ++++++++++++++++++++++++ src/gfile/inc_memfs.c | 41 +++++++++++++++++++++ 5 files changed, 194 insertions(+), 17 deletions(-) create mode 100644 src/gfile/inc_chibiosfs.c create mode 100644 src/gfile/inc_memfs.c diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h index 6cd2d9ad..b615cb8a 100644 --- a/include/gfile/gfile.h +++ b/include/gfile/gfile.h @@ -21,7 +21,7 @@ #include "gfx.h" -#if GFX_USE_GMISC || defined(__DOXYGEN__) +#if GFX_USE_GFILE || defined(__DOXYGEN__) /*===========================================================================*/ /* Type definitions */ @@ -99,6 +99,13 @@ extern "C" { long int gfileGetSize(GFILE *f); bool_t gfileEOF(GFILE *f); + #if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS + GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode); + #endif + #if GFILE_NEED_MEMFS + GFILE * gfileOpenMemory(void *memptr, const char *mode); + #endif + #if GFILE_NEED_PRINTG int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg); int fnprintg(GFILE *f, int maxlen, const char *fmt, ...); @@ -192,8 +199,8 @@ extern "C" { } #endif -#endif /* GFX_USE_MISC */ +#endif /* GFX_USE_GFILE */ -#endif /* _GMISC_H */ +#endif /* _GFILE_H */ /** @} */ diff --git a/include/gfile/options.h b/include/gfile/options.h index 55c37f8e..d73af02c 100644 --- a/include/gfile/options.h +++ b/include/gfile/options.h @@ -43,13 +43,6 @@ #ifndef GFILE_NEED_STRINGS #define GFILE_NEED_STRINGS FALSE #endif - /** - * @brief Include scang, fscang, sscang etc functions - * @details Defaults to FALSE - */ - #ifndef GFILE_NEED_SCANG - #define GFILE_NEED_SCANG FALSE - #endif /** * @brief Map many stdio functions to their GFILE equivalent * @details Defaults to FALSE @@ -108,6 +101,28 @@ #ifndef GFILE_NEED_NATIVEFS #define GFILE_NEED_NATIVEFS FALSE #endif + /** + * @brief Include ChibiOS BaseFileStream support + * @details Defaults to FALSE + * @pre This is only relevant on the ChibiOS operating system. + * @note Use the @p gfileOpenBaseFileStream() call to open a GFILE based on a + * BaseFileStream. The BaseFileStream must already be open. + * @note A GFile of this type cannot be opened by filename. The BaseFileStream + * must be pre-opened using the operating system. + */ + #ifndef GFILE_NEED_CHIBIOSFS + #define GFILE_NEED_CHIBIOSFS FALSE + #endif + /** + * @brief Include raw memory pointer support + * @details Defaults to FALSE + * @note Use the @p gfileOpenMemory() call to open a GFILE based on a + * memory pointer. The GFILE opened appears to be of unlimited size. + * @note A GFile of this type cannot be opened by filename. + */ + #ifndef GFILE_NEED_MEMFS + #define GFILE_NEED_MEMFS FALSE + #endif /** * @} * @@ -137,12 +152,6 @@ #ifndef GFILE_MAX_GFILES #define GFILE_MAX_GFILES 3 #endif - /** - * @brief The size in bytes of the RAM file system - */ - #ifndef GFILE_RAMFS_SIZE - #define GFILE_RAMFS_SIZE 0 - #endif /** @} */ #endif /* _GFILE_OPTIONS_H */ diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index f9c306e4..23985367 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -31,6 +31,20 @@ GFILE *gfileStdErr; * The last defined is the first searched. */ +/******************************************************** + * The ChibiOS BaseFileStream VMT + ********************************************************/ +#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS + #include "../src/gfile/inc_chibiosfs.c" +#endif + +/******************************************************** + * The Memory Pointer VMT + ********************************************************/ +#if GFILE_NEED_MEMFS + #include "../src/gfile/inc_memfs.c" +#endif + /******************************************************** * The RAM file-system VMT ********************************************************/ @@ -297,6 +311,66 @@ GFILE *gfileOpen(const char *fname, const char *mode) { return FALSE; } +#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS + GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode) { + GFILE * f; + + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + // Get the flags + if (!(f->flags = mode2flags(mode))) + return FALSE; + + // If we want write but the fs doesn't allow it then return + if ((f->flags & GFILEFLG_WRITE) && !(FsCHIBIOSVMT.flags & GFSFLG_WRITEABLE)) + return FALSE; + + // File is open - fill in all the details + f->vmt = &FsCHIBIOSVMT; + f->fd = BaseFileStreamPtr; + f->err = 0; + f->pos = 0; + f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; + return TRUE; + } + } + + // No available slot + return FALSE; + } +#endif + +#if GFILE_NEED_MEMFS + GFILE * gfileOpenMemory(void *memptr, const char *mode) { + GFILE * f; + + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + // Get the flags + if (!(f->flags = mode2flags(mode))) + return FALSE; + + // If we want write but the fs doesn't allow it then return + if ((f->flags & GFILEFLG_WRITE) && !(FsMemVMT.flags & GFSFLG_WRITEABLE)) + return FALSE; + + // File is open - fill in all the details + f->vmt = &FsMemVMT; + f->fd = memptr; + f->err = 0; + f->pos = 0; + f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; + return TRUE; + } + } + + // No available slot + return FALSE; + } +#endif + void gfileClose(GFILE *f) { if (!f || !(f->flags & GFILEFLG_OPEN)) return; @@ -357,7 +431,7 @@ bool_t gfileEOF(GFILE *f) { if (!f || !(f->flags & GFILEFLG_OPEN)) return TRUE; if (!f->vmt->eof) - return TRUE; + return FALSE; return f->vmt->eof(f); } diff --git a/src/gfile/inc_chibiosfs.c b/src/gfile/inc_chibiosfs.c new file mode 100644 index 00000000..b30a675f --- /dev/null +++ b/src/gfile/inc_chibiosfs.c @@ -0,0 +1,46 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The ChibiOS BaseFileStream file-system VMT + ********************************************************/ + +static void ChibiOSBFSClose(GFILE *f); +static int ChibiOSBFSRead(GFILE *f, char *buf, int size); +static int ChibiOSBFSWrite(GFILE *f, char *buf, int size); +static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos); +static long int ChibiOSBFSGetsize(GFILE *f); +static bool_t ChibiOSBFSEof(GFILE *f); + +static const GFILEVMT FsCHIBIOSVMT = { + 0, // next + GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags + 0, // prefix + 0, 0, 0, 0, + 0, ChibiOSBFSClose, ChibiOSBFSRead, ChibiOSBFSWrite, + ChibiOSBFSSetpos, ChibiOSBFSGetsize, ChibiOSBFSEof, +}; + +static void ChibiOSBFSClose(GFILE *f) { + chFileStreamClose(((BaseFileStream *)f->fd)); +} +static int ChibiOSBFSRead(GFILE *f, char *buf, int size) { + return chSequentialStreamRead(((BaseFileStream *)f->fd), (uint8_t *)buf, size); +} +static int ChibiOSBFSWrite(GFILE *f, char *buf, int size) { + return chSequentialStreamWrite(((BaseFileStream *)f->fd), (uint8_t *)buf, size); +} +static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos) { + chFileStreamSeek(((BaseFileStream *)f->fd), pos); + return TRUE; +} +static long int ChibiOSBFSGetsize(GFILE *f) { return chFileStreamGetSize(((BaseFileStream *)f->fd)); } +static bool_t ChibiOSBFSEof(GFILE *f) { return f->pos >= chFileStreamGetSize(((BaseFileStream *)f->fd)); } diff --git a/src/gfile/inc_memfs.c b/src/gfile/inc_memfs.c new file mode 100644 index 00000000..fee089ce --- /dev/null +++ b/src/gfile/inc_memfs.c @@ -0,0 +1,41 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * This file is included by src/gfile/gfile.c + */ + +/******************************************************** + * The Memory pointer file-system VMT + ********************************************************/ + +#include + +static int MEMRead(GFILE *f, char *buf, int size); +static int MEMWrite(GFILE *f, char *buf, int size); +static bool_t MEMSetpos(GFILE *f, long int pos); + +static const GFILEVMT FsMemVMT = { + 0, // next + GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags + 0, // prefix + 0, 0, 0, 0, + 0, 0, MEMRead, MEMWrite, + MEMSetpos, 0, 0, +}; + +static int MEMRead(GFILE *f, char *buf, int size) { + memset(buf, ((char *)f->fd)+f->pos, size); + return size; +} +static int MEMWrite(GFILE *f, char *buf, int size) { + memset(((char *)f->fd)+f->pos, buf, size); + return size; +} +static bool_t MEMSetpos(GFILE *f, long int pos) { + return TRUE; +} From d667fab32579fb9208fff2bc78bec8e01ffa753e Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 01:35:31 +1000 Subject: [PATCH 10/23] Integrate gfile build files --- gfx.mk | 2 +- gfxconf.example.h | 25 ++++++++++++++++++++++++- include/gfx.h | 12 ++++++++++-- include/gfx_rules.h | 12 ++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/gfx.mk b/gfx.mk index aaea245a..0ee3e3f1 100644 --- a/gfx.mk +++ b/gfx.mk @@ -12,4 +12,4 @@ include $(GFXLIB)/src/gadc/gadc.mk include $(GFXLIB)/src/gaudin/gaudin.mk include $(GFXLIB)/src/gaudout/gaudout.mk include $(GFXLIB)/src/gmisc/gmisc.mk - +include $(GFXLIB)/src/gfile/gfile.mk diff --git a/gfxconf.example.h b/gfxconf.example.h index e6a3381e..d9dcf88b 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -9,6 +9,8 @@ /** * Copy this file into your project directory and rename it as gfxconf.h * Edit your copy to turn on the uGFX features you want to use. + * The values below are the defaults. You should delete anything + * you are leaving as default. * * Please use spaces instead of tabs in this file. */ @@ -26,7 +28,7 @@ /////////////////////////////////////////////////////////////////////////// // GDISP // /////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GDISP TRUE +#define GFX_USE_GDISP FALSE #define GDISP_NEED_AUTOFLUSH FALSE #define GDISP_NEED_TIMERFLUSH FALSE @@ -185,6 +187,27 @@ #define GINPUT_NEED_DIAL FALSE +/////////////////////////////////////////////////////////////////////////// +// GFILE // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GFILE FALSE + +#define GFILE_NEED_PRINTG FALSE +#define GFILE_NEED_SCANG FALSE +#define GFILE_NEED_STRINGS FALSE +#define GFILE_NEED_STDIO FALSE + #define GFILE_ALLOW_FLOATS FALSE + #define GFILE_ALLOW_DEVICESPECIFIC FALSE + #define GFILE_MAX_GFILES 3 + +#define GFILE_NEED_MEMFS FALSE +#define GFILE_NEED_ROMFS FALSE +#define GFILE_NEED_RAMFS FALSE +#define GFILE_NEED_FATFS FALSE +#define GFILE_NEED_NATIVEFS FALSE +#define GFILE_NEED_CHBIOSFS FALSE + + /////////////////////////////////////////////////////////////////////////// // GADC // /////////////////////////////////////////////////////////////////////////// diff --git a/include/gfx.h b/include/gfx.h index d261a6ce..f8a5ebc3 100644 --- a/include/gfx.h +++ b/include/gfx.h @@ -150,6 +150,13 @@ #ifndef GFX_USE_GMISC #define GFX_USE_GMISC FALSE #endif + /** + * @brief GFX File API + * @details Defaults to FALSE + */ + #ifndef GFX_USE_GFILE + #define GFX_USE_GFILE FALSE + #endif /** @} */ /** @@ -157,6 +164,7 @@ * */ #include "gos/options.h" +#include "gfile/options.h" #include "gmisc/options.h" #include "gqueue/options.h" #include "gevent/options.h" @@ -169,7 +177,7 @@ #include "gaudout/options.h" /** - * Inter-dependancy safety checks on the sub-systems. + * Interdependency safety checks on the sub-systems. * */ #include "gfx_rules.h" @@ -178,6 +186,7 @@ * Include the sub-system header files */ #include "gos/gos.h" +#include "gfile/options.h" #include "gmisc/gmisc.h" #include "gqueue/gqueue.h" #include "gevent/gevent.h" @@ -208,7 +217,6 @@ extern "C" { * @brief The one call to end it all * * @note This will deinitialise each sub-system that has been turned on. - * @note Do not call this without a previous @p gfxInit(); * * @api */ diff --git a/include/gfx_rules.h b/include/gfx_rules.h index a129ef76..817ff749 100644 --- a/include/gfx_rules.h +++ b/include/gfx_rules.h @@ -187,6 +187,15 @@ #undef GDISP_INCLUDE_FONT_UI2 #define GDISP_INCLUDE_FONT_UI2 TRUE #endif + #if GDISP_NEED_IMAGE + #if !GFX_USE_GFILE + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GDISP: GFX_USE_GFILE is required when GDISP_NEED_IMAGE is TRUE. It has been turned on for you." + #endif + #undef GFX_USE_GFILE + #define GFX_USE_GFILE TRUE + #endif + #endif #endif #if GFX_USE_GAUDIN @@ -230,5 +239,8 @@ #if GFX_USE_GMISC #endif +#if GFX_USE_GFILE +#endif + #endif /* _GFX_H */ /** @} */ From 71aeb15d58dc306b3cf5027ca151be40cf5a5890 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 01:36:31 +1000 Subject: [PATCH 11/23] Start changing GDISP images to use a simpler API based on GFILE's. --- include/gdisp/image.h | 208 +++++++++++++------------------------ src/gdisp/image.c | 235 ++++++++++++++++++++++++------------------ 2 files changed, 202 insertions(+), 241 deletions(-) diff --git a/include/gdisp/image.h b/include/gdisp/image.h index ff2e9d85..f8c5f6a1 100644 --- a/include/gdisp/image.h +++ b/include/gdisp/image.h @@ -40,6 +40,7 @@ typedef uint16_t gdispImageError; #define GDISP_IMAGE_ERR_UNSUPPORTED (GDISP_IMAGE_ERR_UNRECOVERABLE+3) #define GDISP_IMAGE_ERR_UNSUPPORTED_OK 3 #define GDISP_IMAGE_ERR_NOMEMORY (GDISP_IMAGE_ERR_UNRECOVERABLE+4) + #define GDISP_IMAGE_ERR_NOSUCHFILE (GDISP_IMAGE_ERR_UNRECOVERABLE+5) /** * @brief Image flags @@ -116,59 +117,78 @@ typedef struct gdispImage { extern "C" { #endif - /** - * @brief Sets the io fields in the image structure to routines - * that support reading from an image stored in RAM or Flash. - * - * @return TRUE if the IO open function succeeds - * - * @param[in] img The image structure - * @param[in] memimage A pointer to the image in RAM or Flash - * - * @note Always returns TRUE for a Memory Reader - */ - bool_t gdispImageSetMemoryReader(gdispImage *img, const void *memimage); - - #if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) - /** - * @brief Sets the io fields in the image structure to routines - * that support reading from an image stored on a BaseFileStream (eg SDCard). - * - * @return TRUE if the IO open function succeeds - * - * @param[in] img The image structure - * @param[in] BaseFileStreamPtr A pointer to the (open) BaseFileStream object. - * - */ - bool_t gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr); + gdispImageError DEPRECATED("If possible please use gdispImageOpenFile(), gdispImageOpenMemory() or gdispImageOpenBaseFileStream() instead") + gdispImageOpen(gdispImage *img); + bool_t DEPRECATED("Use gdispImageOpenMemory() instead. GFX_USE_GFILE, GFILE_NEED_MEMFS must also be TRUE") gdispImageSetMemoryReader(gdispImage *img, const void *memimage); + #if GFX_USE_OS_CHIBIOS + bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead. GFX_USE_GFILE, GFILE_NEED_CHIBIOSFS must also be TRUE") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr); #endif - - #if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX || defined(__DOXYGEN__) - /** - * @brief Sets the io fields in the image structure to routines - * that support reading from an image stored in Win32 simulators native - * file system. - * @pre Only available on the Win32 simulator - * - * @return TRUE if the IO open function succeeds - * - * @param[in] img The image structure - * @param[in] filename The filename to open - * - */ - bool_t gdispImageSetFileReader(gdispImage *img, const char *filename); - /* Old definition */ + #if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX + bool_t DEPRECATED("Please use gdispImageOpenFile() instead. GFX_USE_GFILE must also be TRUE") + gdispImageSetFileReader(gdispImage *img, const char *filename); #define gdispImageSetSimulFileReader(img, fname) gdispImageSetFileReader(img, fname) #endif + + #if GFX_USE_GFILE || defined(__DOXYGEN__) + /** + * @brief Open an image in a file and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @pre GFX_USE_GFILE must be TRUE and you must have included the file-system support + * you want to use. + * + * @param[in] img The image structure + * @param[in] filename The filename to open + * + * @note This determines which decoder to use and then initialises all other fields + * in the gdispImage structure. + * @note The image background color is set to White. + * @note There are three types of return - everything OK, partial success and unrecoverable + * failures. For everything OK it returns GDISP_IMAGE_ERR_OK. A partial success can + * be distinguished from a unrecoverable failure by testing the GDISP_IMAGE_ERR_UNRECOVERABLE + * bit in the error code. + * A partial success return code means an image can still be drawn but perhaps with + * reduced functionality eg only the first page of a multi-page image. + * @note @p gdispImageClose() should be called even after a partial failure in order to + * properly close the file. + */ + gdispImageError gdispImageOpenFile(gdispImage *img, const char *filename); + #endif + #if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) + /** + * @brief Open an image in a ChibiOS basefilestream and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @pre This only makes sense on the ChibiOS operating system. + * + * @param[in] img The image structure + * @param[in] BaseFileStreamPtr A pointer to an open BaseFileStream + * + * @note This determines which decoder to use and then initialises all other fields + * in the gdispImage structure. + * @note The image background color is set to White. + * @note There are three types of return - everything OK, partial success and unrecoverable + * failures. For everything OK it returns GDISP_IMAGE_ERR_OK. A partial success can + * be distinguished from a unrecoverable failure by testing the GDISP_IMAGE_ERR_UNRECOVERABLE + * bit in the error code. + * A partial success return code means an image can still be drawn but perhaps with + * reduced functionality eg only the first page of a multi-page image. + * @note @p gdispImageClose() should be called even after a partial failure in order to + * properly close the file. + */ + gdispImageError gdispImageOpenBaseFileStream(gdispImage *img, void *BaseFileStreamPtr); + #endif + /** - * @brief Open an image ready for drawing + * @brief Open an image in memory and get it ready for drawing * @details Determine the image format and get ready to decode the first image frame * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. * - * @param[in] img The image structure - * - * @pre The io fields should be filled in before calling gdispImageOpen() + * @param[in] img The image structure + * @param[in] memimage A pointer to the image bytes in memory * * @note This determines which decoder to use and then initialises all other fields * in the gdispImage structure. @@ -179,17 +199,17 @@ extern "C" { * bit in the error code. * A partial success return code means an image can still be drawn but perhaps with * reduced functionality eg only the first page of a multi-page image. - * @note @p gdispImageClose() can be called even after a failure to open the image to ensure - * that the IO close routine gets called. + * @note @p gdispImageClose() should be called even after a partial failure in order to + * properly close the file. */ - gdispImageError gdispImageOpen(gdispImage *img); - + gdispImageError gdispImageOpenMemory(gdispImage *img, const void *memimage); + /** * @brief Close an image and release any dynamically allocated working storage. * * @param[in] img The image structure * - * @pre gdispImageOpen() must have returned successfully. + * @pre gdispImageOpenFile() must have returned successfully. * * @note Also calls the IO close function (if it hasn't already been called). */ @@ -282,94 +302,6 @@ extern "C" { */ delaytime_t gdispImageNext(gdispImage *img); - #if GDISP_NEED_IMAGE_NATIVE - /** - * @brief The image drawing routines for a NATIVE format image. - * - * @note Only use these functions if you absolutely know the format - * of the image you are decoding. Generally you should use the - * generic functions and it will auto-detect the format. - * @note A NATIVE format image is defined as an 8 byte header described below, immediately - * followed by the bitmap data. The bitmap data is stored in the native format for - * the display controller. If the pixel format specified in the header does not - * match the controller native format then the image is rejected. - * @note The 8 byte header: - * { 'N', 'I', width.hi, width.lo, height.hi, height.lo, format.hi, format.lo } - * The format word = GDISP_PIXELFORMAT - * @{ - */ - gdispImageError gdispImageOpen_NATIVE(gdispImage *img); - void gdispImageClose_NATIVE(gdispImage *img); - gdispImageError gdispImageCache_NATIVE(gdispImage *img); - gdispImageError gdispGImageDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); - delaytime_t gdispImageNext_NATIVE(gdispImage *img); - /* @} */ - #endif - - #if GDISP_NEED_IMAGE_GIF - /** - * @brief The image drawing routines for a GIF image. - * @note Only use these functions if you absolutely know the format - * of the image you are decoding. Generally you should use the - * generic functions and it will auto-detect the format. - * @{ - */ - gdispImageError gdispImageOpen_GIF(gdispImage *img); - void gdispImageClose_GIF(gdispImage *img); - gdispImageError gdispImageCache_GIF(gdispImage *img); - gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); - delaytime_t gdispImageNext_GIF(gdispImage *img); - /* @} */ - #endif - - #if GDISP_NEED_IMAGE_BMP - /** - * @brief The image drawing routines for a BMP image. - * @note Only use these functions if you absolutely know the format - * of the image you are decoding. Generally you should use the - * generic functions and it will auto-detect the format. - * @{ - */ - gdispImageError gdispImageOpen_BMP(gdispImage *img); - void gdispImageClose_BMP(gdispImage *img); - gdispImageError gdispImageCache_BMP(gdispImage *img); - gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); - delaytime_t gdispImageNext_BMP(gdispImage *img); - /* @} */ - #endif - - #if GDISP_NEED_IMAGE_JPG - /** - * @brief The image drawing routines for a JPG image. - * @note Only use these functions if you absolutely know the format - * of the image you are decoding. Generally you should use the - * generic functions and it will auto-detect the format. - * @{ - */ - gdispImageError gdispImageOpen_JPG(gdispImage *img); - void gdispImageClose_JPG(gdispImage *img); - gdispImageError gdispImageCache_JPG(gdispImage *img); - gdispImageError gdispGImageDraw_JPG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); - delaytime_t gdispImageNext_JPG(gdispImage *img); - /* @} */ - #endif - - #if GDISP_NEED_IMAGE_PNG - /** - * @brief The image drawing routines for a PNG image. - * @note Only use these functions if you absolutely know the format - * of the image you are decoding. Generally you should use the - * generic functions and it will auto-detect the format. - * @{ - */ - gdispImageError gdispImageOpen_PNG(gdispImage *img); - void gdispImageClose_PNG(gdispImage *img); - gdispImageError gdispImageCache_PNG(gdispImage *img); - gdispImageError gdispGImageDraw_PNG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); - delaytime_t gdispImageNext_PNG(gdispImage *img); - /* @} */ - #endif - #ifdef __cplusplus } #endif diff --git a/src/gdisp/image.c b/src/gdisp/image.c index 62af0aeb..dd219289 100644 --- a/src/gdisp/image.c +++ b/src/gdisp/image.c @@ -18,6 +18,77 @@ #include +static gdispImageError imageOpen(gdispImage *img) { + gdispImageError err; + + img->bgcolor = White; + for(img->fns = ImageHandlers; img->fns < ImageHandlers+sizeof(ImageHandlers)/sizeof(ImageHandlers[0]); img->fns++) { + err = img->fns->open(img); + if (err != GDISP_IMAGE_ERR_BADFORMAT) { + if (!(err & GDISP_IMAGE_ERR_UNRECOVERABLE)) + return err; + goto unrecoverable; + } + img->io.fns->seek(&img->io, 0); + } + + err = GDISP_IMAGE_ERR_BADFORMAT; + img->type = GDISP_IMAGE_TYPE_UNKNOWN; + +unrecoverable: + img->fns->close(img); + img->flags = 0; + img->fns = 0; + img->priv = 0; + return err; +} + +gdispImageError + DEPRECATED("If possible please use gdispImageOpenFile(), gdispImageOpenMemory() or gdispImageOpenBaseFileStream() instead") + gdispImageOpen(gdispImage *img) { + return imageOpen(img); +} + +#if GDISP_NEED_IMAGE_NATIVE + extern gdispImageError gdispImageOpen_NATIVE(gdispImage *img); + extern void gdispImageClose_NATIVE(gdispImage *img); + extern gdispImageError gdispImageCache_NATIVE(gdispImage *img); + extern gdispImageError gdispGImageDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_NATIVE(gdispImage *img); +#endif + +#if GDISP_NEED_IMAGE_GIF + extern gdispImageError gdispImageOpen_GIF(gdispImage *img); + extern void gdispImageClose_GIF(gdispImage *img); + extern gdispImageError gdispImageCache_GIF(gdispImage *img); + extern gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_GIF(gdispImage *img); +#endif + +#if GDISP_NEED_IMAGE_BMP + extern gdispImageError gdispImageOpen_BMP(gdispImage *img); + extern void gdispImageClose_BMP(gdispImage *img); + extern gdispImageError gdispImageCache_BMP(gdispImage *img); + extern gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_BMP(gdispImage *img); +#endif + +#if GDISP_NEED_IMAGE_JPG + extern gdispImageError gdispImageOpen_JPG(gdispImage *img); + extern void gdispImageClose_JPG(gdispImage *img); + extern gdispImageError gdispImageCache_JPG(gdispImage *img); + extern gdispImageError gdispGImageDraw_JPG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_JPG(gdispImage *img); +#endif + +#if GDISP_NEED_IMAGE_PNG + extern gdispImageError gdispImageOpen_PNG(gdispImage *img); + extern void gdispImageClose_PNG(gdispImage *img); + extern gdispImageError gdispImageCache_PNG(gdispImage *img); + extern gdispImageError gdispGImageDraw_PNG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); + extern delaytime_t gdispImageNext_PNG(gdispImage *img); +#endif + /* The structure defining the routines for image drawing */ typedef struct gdispImageHandlers { gdispImageError (*open)(gdispImage *img); /* The open function */ @@ -59,129 +130,87 @@ static gdispImageHandlers ImageHandlers[] = { #endif }; -static size_t ImageMemoryRead(struct gdispImageIO *pio, void *buf, size_t len) { - if (pio->fd == (void *)-1) return 0; - memcpy(buf, ((const char *)pio->fd)+pio->pos, len); +static size_t ImageGFileRead(struct gdispImageIO *pio, void *buf, size_t len) { + if (!pio->fd) return 0; + len = gfileRead((GFILE *)pio->fd, buf, len); + if ((int)len < 0) len = 0; pio->pos += len; return len; } -static void ImageMemorySeek(struct gdispImageIO *pio, size_t pos) { - if (pio->fd == (void *)-1) return; - pio->pos = pos; +static void ImageGFileSeek(struct gdispImageIO *pio, size_t pos) { + if (!pio->fd) return; + if (pio->pos != pos) { + gfileSetPos((GFILE *)pio->fd, pos); + pio->pos = pos; + } } -static void ImageMemoryClose(struct gdispImageIO *pio) { - pio->fd = (void *)-1; +static void ImageGFileClose(struct gdispImageIO *pio) { + if (!pio->fd) return; + gfileClose((GFILE *)pio->fd); + pio->fd = 0; pio->pos = 0; } -static const gdispImageIOFunctions ImageMemoryFunctions = - { ImageMemoryRead, ImageMemorySeek, ImageMemoryClose }; +static const gdispImageIOFunctions ImageGFileFunctions = + { ImageGFileRead, ImageGFileSeek, ImageGFileClose }; -bool_t gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { - img->io.fns = &ImageMemoryFunctions; - img->io.pos = 0; - img->io.fd = memimage; - return TRUE; -} - -#if GFX_USE_OS_CHIBIOS - static size_t ImageBaseFileStreamRead(struct gdispImageIO *pio, void *buf, size_t len) { - if (pio->fd == (void *)-1) return 0; - len = chSequentialStreamRead(((BaseFileStream *)pio->fd), (uint8_t *)buf, len); - pio->pos += len; - return len; - } - - static void ImageBaseFileStreamSeek(struct gdispImageIO *pio, size_t pos) { - if (pio->fd == (void *)-1) return; - if (pio->pos != pos) { - chFileStreamSeek(((BaseFileStream *)pio->fd), pos); - pio->pos = pos; - } - } - - static void ImageBaseFileStreamClose(struct gdispImageIO *pio) { - if (pio->fd == (void *)-1) return; - chFileStreamClose(((BaseFileStream *)pio->fd)); - pio->fd = (void *)-1; - pio->pos = 0; - } - - static const gdispImageIOFunctions ImageBaseFileStreamFunctions = - { ImageBaseFileStreamRead, ImageBaseFileStreamSeek, ImageBaseFileStreamClose }; - - bool_t gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { - img->io.fns = &ImageBaseFileStreamFunctions; +#if GFILE_NEED_MEMFS + gdispImageError gdispImageOpenMemory(gdispImage *img, const void *memimage) { + img->io.fns = &ImageGFileFunctions; img->io.pos = 0; - img->io.fd = BaseFileStreamPtr; - return TRUE; - } -#endif - -#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX - #include - - static size_t ImageFileRead(struct gdispImageIO *pio, void *buf, size_t len) { - if (!pio->fd) return 0; - len = fread(buf, 1, len, (FILE *)pio->fd); - if ((int)len < 0) len = 0; - pio->pos += len; - return len; + img->io.fd = gfileOpenMemory(memimage, "rb"); + if (!img->io.fd) + return GDISP_IMAGE_ERR_NOSUCHFILE; + return imageOpen(img); } - static void ImageFileSeek(struct gdispImageIO *pio, size_t pos) { - if (!pio->fd) return; - if (pio->pos != pos) { - fseek((FILE *)pio->fd, pos, SEEK_SET); - pio->pos = pos; - } - } - - static void ImageFileClose(struct gdispImageIO *pio) { - if (!pio->fd) return; - fclose((FILE *)pio->fd); - pio->fd = 0; - pio->pos = 0; - } - - static const gdispImageIOFunctions ImageFileFunctions = - { ImageFileRead, ImageFileSeek, ImageFileClose }; - - bool_t gdispImageSetFileReader(gdispImage *img, const char *filename) { - img->io.fns = &ImageFileFunctions; + bool_t DEPRECATED("Use gdispImageOpenMemory() instead. GFX_USE_GFILE, GFILE_NEED_MEMFS must also be TRUE") gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { + img->io.fns = &ImageGFileFunctions; img->io.pos = 0; - #if defined(WIN32) || GFX_USE_OS_WIN32 - img->io.fd = (void *)fopen(filename, "rb"); - #else - img->io.fd = (void *)fopen(filename, "r"); - #endif - + img->io.fd = gfileOpenMemory(memimage, "rb"); return img->io.fd != 0; } #endif -gdispImageError gdispImageOpen(gdispImage *img) { - gdispImageError err; - - img->bgcolor = White; - for(img->fns = ImageHandlers; img->fns < ImageHandlers+sizeof(ImageHandlers)/sizeof(ImageHandlers[0]); img->fns++) { - err = img->fns->open(img); - if (err != GDISP_IMAGE_ERR_BADFORMAT) { - if ((err & GDISP_IMAGE_ERR_UNRECOVERABLE)) - img->fns = 0; - return err; - } - img->io.fns->seek(&img->io, 0); - } - img->type = GDISP_IMAGE_TYPE_UNKNOWN; - img->flags = 0; - img->fns = 0; - img->priv = 0; - return GDISP_IMAGE_ERR_BADFORMAT; +gdispImageError gdispImageOpenFile(gdispImage *img, const char *filename) { + img->io.fns = &ImageGFileFunctions; + img->io.pos = 0; + img->io.fd = gfileOpen(filename, "rb"); + if (!img->io.fd) + return GDISP_IMAGE_ERR_NOSUCHFILE; + return imageOpen(img); } +#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX + bool_t DEPRECATED("Please use gdispImageOpenFile() instead. GFX_USE_GFILE must also be TRUE") gdispImageSetFileReader(gdispImage *img, const char *filename) { + img->io.fns = &ImageGFileFunctions; + img->io.pos = 0; + img->io.fd = gfileOpen(filename, "rb"); + return img->io.fd != 0; + } +#endif + +#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS + bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead. GFX_USE_GFILE, GFILE_NEED_CHIBIOSFS must also be TRUE") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { + img->io.fns = &ImageGFileFunctions; + img->io.pos = 0; + img->io.fd = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); + return img->io.fd != 0; + } + + gdispImageError gdispImageOpenBaseFileStream(gdispImage *img, void *BaseFileStreamPtr) { + img->io.fns = &ImageGFileFunctions; + img->io.pos = 0; + img->io.fd = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); + if (!img->io.fd) + return GDISP_IMAGE_ERR_NOSUCHFILE; + return imageOpen(img); + } + +#endif + void gdispImageClose(gdispImage *img) { if (img->fns) img->fns->close(img); From b74686bdf075c51e3779d3118b50a91950647f07 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 13:59:02 +1000 Subject: [PATCH 12/23] Removing compiler warnings from new list code --- src/gwin/list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gwin/list.c b/src/gwin/list.c index 972ea1ab..08e6a96d 100644 --- a/src/gwin/list.c +++ b/src/gwin/list.c @@ -172,6 +172,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) { const gfxQueueASyncItem* qi; int item, i; coord_t iheight; + (void) x; iheight = gdispGetFontMetric(gw->g.font, fontHeight) + VERTICAL_PADDING; @@ -202,8 +203,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) { // a mouse down has occurred over the list area static void MouseDown(GWidgetObject* gw, coord_t x, coord_t y) { - const gfxQueueASyncItem* qi; - int item, i, pgsz; + int pgsz; coord_t iheight; (void) x; From 1d904dccaf4e82b5a7225f004f191ebc97176b91 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 13:59:52 +1000 Subject: [PATCH 13/23] Typo in Win32 GOS --- include/gos/win32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/gos/win32.h b/include/gos/win32.h index 2840ffcf..c704a288 100644 --- a/include/gos/win32.h +++ b/include/gos/win32.h @@ -69,11 +69,11 @@ typedef HANDLE gfxThreadHandle; #define gfxSystemTicks() GetTickCount() #define gfxMillisecondsToTicks(ms) (ms) #define gfxMutexInit(pmutex) *(pmutex) = CreateMutex(0, FALSE, 0) -#define gfxMutexDestory(pmutex) CloseHandle(*(pmutex)) +#define gfxMutexDestroy(pmutex) CloseHandle(*(pmutex)) #define gfxMutexEnter(pmutex) WaitForSingleObject(*(pmutex), INFINITE) #define gfxMutexExit(pmutex) ReleaseMutex(*(pmutex)) #define gfxSemInit(psem, val, limit) *(psem) = CreateSemaphore(0, val, limit, 0) -#define gfxSemDestory(psem) CloseHandle(*(psem)) +#define gfxSemDestroy(psem) CloseHandle(*(psem)) #define gfxSemSignal(psem) ReleaseSemaphore(*(psem), 1, 0) #define gfxSemSignalI(psem) ReleaseSemaphore(*(psem), 1, 0) #define gfxSemCounterI(psem) gfxSemCounter(psem) From a86bab4a77ea6a4cd34e011c15535fc8da8a1ba6 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 14:04:43 +1000 Subject: [PATCH 14/23] Updates to GFILE code --- include/gfile/gfile.h | 51 ++++------------------- include/gfx.h | 2 +- src/gfile/gfile.c | 88 ++++++++++++++++++++++++++++----------- src/gfile/inc_chibiosfs.c | 8 ++-- src/gfile/inc_memfs.c | 14 ++++--- src/gfile/inc_nativefs.c | 8 ++-- src/gfile/inc_romfs.c | 4 +- 7 files changed, 90 insertions(+), 85 deletions(-) diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h index b615cb8a..62972c47 100644 --- a/include/gfile/gfile.h +++ b/include/gfile/gfile.h @@ -31,48 +31,11 @@ * @brief A file pointer */ -typedef struct GFILE { - const struct GFILEVMT * vmt; - uint16_t flags; - #define GFILEFLG_OPEN 0x0001 // File is open - #define GFILEFLG_READ 0x0002 // Read the file - #define GFILEFLG_WRITE 0x0004 // Write the file - #define GFILEFLG_APPEND 0x0008 // Append on each write - #define GFILEFLG_BINARY 0x0010 // Treat as a binary file - #define GFILEFLG_DELONCLOSE 0x0020 // Delete on close - #define GFILEFLG_CANSEEK 0x0040 // Seek operations are valid - #define GFILEFLG_FAILONBLOCK 0x0080 // Fail on a blocking call - #define GFILEFLG_MUSTEXIST 0x0100 // On open file must exist - #define GFILEFLG_MUSTNOTEXIST 0x0200 // On open file must not exist - #define GFILEFLG_TRUNC 0x0400 // On open truncate the file - void * obj; - long int pos; -} GFILE; - -typedef struct GFILEVMT { - const struct GFILEVMT * next; - uint8_t flags; - #define GFSFLG_WRITEABLE 0x0001 - #define GFSFLG_CASESENSITIVE 0x0002 - #define GFSFLG_SEEKABLE 0x0004 - #define GFSFLG_FAST 0x0010 - #define GFSFLG_SMALL 0x0020 - #define GFSFLG_TEXTMODES 0x0040 - char prefix; - bool_t del(const char *fname); - bool_t exists(const char *fname); - long int filesize(const char *fname); - bool_t ren(const char *oldname, const char *newname); - bool_t open(GFILE *f, const char *fname); - void close(GFILE *f); - int read(GFILE *f, char *buf, int size); - int write(GFILE *f, const char *buf, int size); - bool_t setpos(GFILE *f, long int pos); - long int getsize(GFILE *f); - bool_t eof(GFILE *f); -} GFILEVMT; - -typedef void GFILE; +#ifndef GFILE_IMPLEMENTATION + typedef void GFILE; +#else + typedef struct GFILE GFILE; +#endif extern GFILE *gfileStdIn; extern GFILE *gfileStdErr; @@ -92,8 +55,8 @@ extern "C" { bool_t gfileRename(const char *oldname, const char *newname); GFILE * gfileOpen(const char *fname, const char *mode); void gfileClose(GFILE *f); - size_t gfileRead(GFILE *f, char *buf, size_t len); - size_t gfileWrite(GFILE *f, const char *buf, size_t len); + size_t gfileRead(GFILE *f, void *buf, size_t len); + size_t gfileWrite(GFILE *f, const void *buf, size_t len); long int gfileGetPos(GFILE *f); bool_t gfileSetPos(GFILE *f, long int pos); long int gfileGetSize(GFILE *f); diff --git a/include/gfx.h b/include/gfx.h index f8a5ebc3..0c922669 100644 --- a/include/gfx.h +++ b/include/gfx.h @@ -186,7 +186,7 @@ * Include the sub-system header files */ #include "gos/gos.h" -#include "gfile/options.h" +#include "gfile/gfile.h" #include "gmisc/gmisc.h" #include "gqueue/gqueue.h" #include "gevent/gevent.h" diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index 23985367..9edafea4 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -12,10 +12,52 @@ */ #define GFILE_IMPLEMENTATION + #include "gfx.h" #if GFX_USE_GFILE +struct GFILE { + const struct GFILEVMT * vmt; + uint16_t flags; + #define GFILEFLG_OPEN 0x0001 // File is open + #define GFILEFLG_READ 0x0002 // Read the file + #define GFILEFLG_WRITE 0x0004 // Write the file + #define GFILEFLG_APPEND 0x0008 // Append on each write + #define GFILEFLG_BINARY 0x0010 // Treat as a binary file + #define GFILEFLG_DELONCLOSE 0x0020 // Delete on close + #define GFILEFLG_CANSEEK 0x0040 // Seek operations are valid + #define GFILEFLG_FAILONBLOCK 0x0080 // Fail on a blocking call + #define GFILEFLG_MUSTEXIST 0x0100 // On open file must exist + #define GFILEFLG_MUSTNOTEXIST 0x0200 // On open file must not exist + #define GFILEFLG_TRUNC 0x0400 // On open truncate the file + void * obj; + long int pos; +}; + +typedef struct GFILEVMT { + const struct GFILEVMT * next; + uint8_t flags; + #define GFSFLG_WRITEABLE 0x0001 + #define GFSFLG_CASESENSITIVE 0x0002 + #define GFSFLG_SEEKABLE 0x0004 + #define GFSFLG_FAST 0x0010 + #define GFSFLG_SMALL 0x0020 + #define GFSFLG_TEXTMODES 0x0040 + char prefix; + bool_t (*del) (const char *fname); + bool_t (*exists) (const char *fname); + long int (*filesize) (const char *fname); + bool_t (*ren) (const char *oldname, const char *newname); + bool_t (*open) (GFILE *f, const char *fname); + void (*close) (GFILE *f); + int (*read) (GFILE *f, void *buf, int size); + int (*write) (GFILE *f, const void *buf, int size); + bool_t (*setpos) (GFILE *f, long int pos); + long int (*getsize) (GFILE *f); + bool_t (*eof) (GFILE *f); +} GFILEVMT; + // The chain of FileSystems #define GFILE_CHAINHEAD 0 @@ -254,7 +296,6 @@ static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { // File is open - fill in all the details f->vmt = p; - f->err = 0; f->pos = 0; f->flags |= GFILEFLG_OPEN; if (p->flags & GFSFLG_SEEKABLE) @@ -269,7 +310,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { // Get the requested mode if (!(flags = mode2flags(mode))) - return FALSE; + return 0; #if GFILE_ALLOW_DEVICESPECIFIC if (fname[0] && fname[1] == '|') { @@ -280,7 +321,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { f->flags = flags; for(p = FsChain; p; p = p->next) { if (p->prefix == fname[0]) - return testopen(p, f, fname+2); + return testopen(p, f, fname+2) ? f : 0; } // File not found break; @@ -288,7 +329,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } // No available slot - return FALSE; + return 0; } #endif @@ -300,7 +341,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { f->flags = flags; for(p = FsChain; p; p = p->next) { if (testopen(p, f, fname)) - return TRUE; + return f; } // File not found break; @@ -308,7 +349,7 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } // No available slot - return FALSE; + return 0; } #if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS @@ -320,24 +361,23 @@ GFILE *gfileOpen(const char *fname, const char *mode) { if (!(f->flags & GFILEFLG_OPEN)) { // Get the flags if (!(f->flags = mode2flags(mode))) - return FALSE; + return 0; // If we want write but the fs doesn't allow it then return if ((f->flags & GFILEFLG_WRITE) && !(FsCHIBIOSVMT.flags & GFSFLG_WRITEABLE)) - return FALSE; + return 0; // File is open - fill in all the details f->vmt = &FsCHIBIOSVMT; - f->fd = BaseFileStreamPtr; - f->err = 0; + f->obj = BaseFileStreamPtr; f->pos = 0; f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; - return TRUE; + return f; } } // No available slot - return FALSE; + return 0; } #endif @@ -350,24 +390,23 @@ GFILE *gfileOpen(const char *fname, const char *mode) { if (!(f->flags & GFILEFLG_OPEN)) { // Get the flags if (!(f->flags = mode2flags(mode))) - return FALSE; + return 0; // If we want write but the fs doesn't allow it then return if ((f->flags & GFILEFLG_WRITE) && !(FsMemVMT.flags & GFSFLG_WRITEABLE)) - return FALSE; + return 0; // File is open - fill in all the details f->vmt = &FsMemVMT; - f->fd = memptr; - f->err = 0; + f->obj = memptr; f->pos = 0; f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK; - return TRUE; + return f; } } // No available slot - return FALSE; + return 0; } #endif @@ -379,7 +418,7 @@ void gfileClose(GFILE *f) { f->flags = 0; } -size_t gfileRead(GFILE *f, char *buf, size_t len) { +size_t gfileRead(GFILE *f, void *buf, size_t len) { size_t res; if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) @@ -392,7 +431,7 @@ size_t gfileRead(GFILE *f, char *buf, size_t len) { return res; } -size_t gfileWrite(GFILE *f, const char *buf, size_t len) { +size_t gfileWrite(GFILE *f, const void *buf, size_t len) { size_t res; if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) @@ -417,6 +456,7 @@ bool_t gfileSetPos(GFILE *f, long int pos) { if (!f->vmt->setpos || !f->vmt->setpos(f, pos)) return FALSE; f->pos = pos; + return TRUE; } long int gfileGetSize(GFILE *f) { @@ -442,16 +482,16 @@ bool_t gfileEOF(GFILE *f) { #include // Special String VMT - static int StringRead(GFILE *f, char *buf, int size) { + static int StringRead(GFILE *f, void *buf, int size) { // size must be 1 for a complete read if (!((char *)f->obj)[f->pos]) return 0; - buf[0] = ((char *)f->obj)[f->pos]; + ((char *)buf)[0] = ((char *)f->obj)[f->pos]; return 1; } - static int StringWrite(GFILE *f, const char *buf, int size) { + static int StringWrite(GFILE *f, const void *buf, int size) { // size must be 1 for a complete write - ((char *)f->obj)[f->pos] = buf[0]; + ((char *)f->obj)[f->pos] = ((char *)buf)[0]; return 1; } static const GFILEVMT StringVMT = { diff --git a/src/gfile/inc_chibiosfs.c b/src/gfile/inc_chibiosfs.c index b30a675f..87b8c110 100644 --- a/src/gfile/inc_chibiosfs.c +++ b/src/gfile/inc_chibiosfs.c @@ -14,8 +14,8 @@ ********************************************************/ static void ChibiOSBFSClose(GFILE *f); -static int ChibiOSBFSRead(GFILE *f, char *buf, int size); -static int ChibiOSBFSWrite(GFILE *f, char *buf, int size); +static int ChibiOSBFSRead(GFILE *f, void *buf, int size); +static int ChibiOSBFSWrite(GFILE *f, const void *buf, int size); static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos); static long int ChibiOSBFSGetsize(GFILE *f); static bool_t ChibiOSBFSEof(GFILE *f); @@ -32,10 +32,10 @@ static const GFILEVMT FsCHIBIOSVMT = { static void ChibiOSBFSClose(GFILE *f) { chFileStreamClose(((BaseFileStream *)f->fd)); } -static int ChibiOSBFSRead(GFILE *f, char *buf, int size) { +static int ChibiOSBFSRead(GFILE *f, void *buf, int size) { return chSequentialStreamRead(((BaseFileStream *)f->fd), (uint8_t *)buf, size); } -static int ChibiOSBFSWrite(GFILE *f, char *buf, int size) { +static int ChibiOSBFSWrite(GFILE *f, const void *buf, int size) { return chSequentialStreamWrite(((BaseFileStream *)f->fd), (uint8_t *)buf, size); } static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos) { diff --git a/src/gfile/inc_memfs.c b/src/gfile/inc_memfs.c index fee089ce..434150d8 100644 --- a/src/gfile/inc_memfs.c +++ b/src/gfile/inc_memfs.c @@ -15,8 +15,8 @@ #include -static int MEMRead(GFILE *f, char *buf, int size); -static int MEMWrite(GFILE *f, char *buf, int size); +static int MEMRead(GFILE *f, void *buf, int size); +static int MEMWrite(GFILE *f, const void *buf, int size); static bool_t MEMSetpos(GFILE *f, long int pos); static const GFILEVMT FsMemVMT = { @@ -28,14 +28,16 @@ static const GFILEVMT FsMemVMT = { MEMSetpos, 0, 0, }; -static int MEMRead(GFILE *f, char *buf, int size) { - memset(buf, ((char *)f->fd)+f->pos, size); +static int MEMRead(GFILE *f, void *buf, int size) { + memcpy(buf, ((char *)f->obj)+f->pos, size); return size; } -static int MEMWrite(GFILE *f, char *buf, int size) { - memset(((char *)f->fd)+f->pos, buf, size); +static int MEMWrite(GFILE *f, const void *buf, int size) { + memcpy(((char *)f->obj)+f->pos, buf, size); return size; } static bool_t MEMSetpos(GFILE *f, long int pos) { + (void) f; + (void) pos; return TRUE; } diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index df5e7861..390a885d 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -28,8 +28,8 @@ static long int NativeFilesize(const char *fname); static bool_t NativeRen(const char *oldname, const char *newname); static bool_t NativeOpen(GFILE *f, const char *fname); static void NativeClose(GFILE *f); -static int NativeRead(GFILE *f, char *buf, int size); -static int NativeWrite(GFILE *f, const char *buf, int size); +static int NativeRead(GFILE *f, void *buf, int size); +static int NativeWrite(GFILE *f, const void *buf, int size); static bool_t NativeSetpos(GFILE *f, long int pos); static long int NativeGetsize(GFILE *f); static bool_t NativeEof(GFILE *f); @@ -85,8 +85,8 @@ static bool_t NativeOpen(GFILE *f, const char *fname) { return TRUE; } static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } -static int NativeRead(GFILE *f, char *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } -static int NativeWrite(GFILE *f, const char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static int NativeRead(GFILE *f, void *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, const void *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } static bool_t NativeSetpos(GFILE *f, long int pos) { return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; } diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 5a780554..8d0e32c1 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -32,7 +32,7 @@ static bool_t ROMExists(const char *fname); static long int ROMFilesize(const char *fname); static bool_t ROMOpen(GFILE *f, const char *fname); static void ROMClose(GFILE *f); -static int ROMRead(GFILE *f, char *buf, int size); +static int ROMRead(GFILE *f, void *buf, int size); static bool_t ROMSetpos(GFILE *f, long int pos); static long int ROMGetsize(GFILE *f); static bool_t ROMEof(GFILE *f); @@ -72,7 +72,7 @@ static bool_t ROMOpen(GFILE *f, const char *fname) { return TRUE; } static void ROMClose(GFILE *f) { (void)f; } -static int ROMRead(GFILE *f, char *buf, int size) { +static int ROMRead(GFILE *f, void *buf, int size) { const ROMFS_DIRENTRY *p; p = (const ROMFS_DIRENTRY *)f->obj; From 695bcbee5b84cd2e152baca91c58bdc2e971b0d1 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 14:06:08 +1000 Subject: [PATCH 15/23] Update GDISP image code to fully use new GFILE's --- include/gdisp/image.h | 131 ++++++++++++++++---------------- src/gdisp/image.c | 157 ++++++++++++++------------------------- src/gdisp/image_bmp.c | 93 ++++++++++++----------- src/gdisp/image_gif.c | 105 +++++++++++++------------- src/gdisp/image_native.c | 29 ++++---- 5 files changed, 229 insertions(+), 286 deletions(-) diff --git a/include/gdisp/image.h b/include/gdisp/image.h index f8c5f6a1..bcf9c497 100644 --- a/include/gdisp/image.h +++ b/include/gdisp/image.h @@ -104,10 +104,10 @@ typedef struct gdispImage { gdispImageFlags flags; /* @< The image flags */ color_t bgcolor; /* @< The default background color */ coord_t width, height; /* @< The image dimensions */ - gdispImageIO io; /* @< The image IO functions */ + GFILE * f; /* @< The underlying GFILE */ #if GDISP_NEED_IMAGE_ACCOUNTING - uint32_t memused; /* @< How much RAM is currently allocated */ - uint32_t maxmemused; /* @< How much RAM has been allocated (maximum) */ + uint32_t memused; /* @< How much RAM is currently allocated */ + uint32_t maxmemused; /* @< How much RAM has been allocated (maximum) */ #endif const struct gdispImageHandlers * fns; /* @< Don't mess with this! */ struct gdispImagePrivate * priv; /* @< Don't mess with this! */ @@ -117,78 +117,28 @@ typedef struct gdispImage { extern "C" { #endif - gdispImageError DEPRECATED("If possible please use gdispImageOpenFile(), gdispImageOpenMemory() or gdispImageOpenBaseFileStream() instead") - gdispImageOpen(gdispImage *img); - bool_t DEPRECATED("Use gdispImageOpenMemory() instead. GFX_USE_GFILE, GFILE_NEED_MEMFS must also be TRUE") gdispImageSetMemoryReader(gdispImage *img, const void *memimage); + /** + * Deprecated Functions. + */ + gdispImageError DEPRECATED("Use gdispImageOpenGFile() instead") gdispImageOpen(gdispImage *img); + bool_t DEPRECATED("Use gdispImageOpenMemory() instead") gdispImageSetMemoryReader(gdispImage *img, const void *memimage); #if GFX_USE_OS_CHIBIOS - bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead. GFX_USE_GFILE, GFILE_NEED_CHIBIOSFS must also be TRUE") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr); + bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr); #endif #if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX - bool_t DEPRECATED("Please use gdispImageOpenFile() instead. GFX_USE_GFILE must also be TRUE") - gdispImageSetFileReader(gdispImage *img, const char *filename); + bool_t DEPRECATED("Please use gdispImageOpenFile() instead") gdispImageSetFileReader(gdispImage *img, const char *filename); #define gdispImageSetSimulFileReader(img, fname) gdispImageSetFileReader(img, fname) #endif - #if GFX_USE_GFILE || defined(__DOXYGEN__) - /** - * @brief Open an image in a file and get it ready for drawing - * @details Determine the image format and get ready to decode the first image frame - * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. - * - * @pre GFX_USE_GFILE must be TRUE and you must have included the file-system support - * you want to use. - * - * @param[in] img The image structure - * @param[in] filename The filename to open - * - * @note This determines which decoder to use and then initialises all other fields - * in the gdispImage structure. - * @note The image background color is set to White. - * @note There are three types of return - everything OK, partial success and unrecoverable - * failures. For everything OK it returns GDISP_IMAGE_ERR_OK. A partial success can - * be distinguished from a unrecoverable failure by testing the GDISP_IMAGE_ERR_UNRECOVERABLE - * bit in the error code. - * A partial success return code means an image can still be drawn but perhaps with - * reduced functionality eg only the first page of a multi-page image. - * @note @p gdispImageClose() should be called even after a partial failure in order to - * properly close the file. - */ - gdispImageError gdispImageOpenFile(gdispImage *img, const char *filename); - #endif - - #if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) - /** - * @brief Open an image in a ChibiOS basefilestream and get it ready for drawing - * @details Determine the image format and get ready to decode the first image frame - * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. - * - * @pre This only makes sense on the ChibiOS operating system. - * - * @param[in] img The image structure - * @param[in] BaseFileStreamPtr A pointer to an open BaseFileStream - * - * @note This determines which decoder to use and then initialises all other fields - * in the gdispImage structure. - * @note The image background color is set to White. - * @note There are three types of return - everything OK, partial success and unrecoverable - * failures. For everything OK it returns GDISP_IMAGE_ERR_OK. A partial success can - * be distinguished from a unrecoverable failure by testing the GDISP_IMAGE_ERR_UNRECOVERABLE - * bit in the error code. - * A partial success return code means an image can still be drawn but perhaps with - * reduced functionality eg only the first page of a multi-page image. - * @note @p gdispImageClose() should be called even after a partial failure in order to - * properly close the file. - */ - gdispImageError gdispImageOpenBaseFileStream(gdispImage *img, void *BaseFileStreamPtr); - #endif - /** - * @brief Open an image in memory and get it ready for drawing + * @brief Open an image using an open GFILE and get it ready for drawing * @details Determine the image format and get ready to decode the first image frame * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. - * + * * @param[in] img The image structure - * @param[in] memimage A pointer to the image bytes in memory + * @param[in] f The open GFILE stream. + * + * @pre The GFILE must be open for reading. * * @note This determines which decoder to use and then initialises all other fields * in the gdispImage structure. @@ -199,10 +149,55 @@ extern "C" { * bit in the error code. * A partial success return code means an image can still be drawn but perhaps with * reduced functionality eg only the first page of a multi-page image. - * @note @p gdispImageClose() should be called even after a partial failure in order to - * properly close the file. + * @note @p gdispImageClose() should be called when finished with the image. This will close + * the image and its underlying GFILE file. Note that images opened with partial success + * (eg GDISP_IMAGE_ERR_UNSUPPORTED_OK) + * still need to be closed when you are finished with them. */ - gdispImageError gdispImageOpenMemory(gdispImage *img, const void *memimage); + gdispImageError gdispImageOpenGFile(gdispImage *img, GFILE *filename); + + /** + * @brief Open an image in a file and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @pre You must have included the file-system support into GFILE that you want to use. + * + * @param[in] img The image structure + * @param[in] filename The filename to open + * + * @note This function just opens the GFILE using the filename and passes it to @p gdispImageOpenGFile(). + */ + #define gdispImageOpenFile(img, filename) gdispImageOpenGFile((img), gfileOpen((filename), "rb")) + + /** + * @brief Open an image in a ChibiOS basefilestream and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @pre GFILE_NEED_CHIBIOSFS and GFX_USE_OS_CHIBIOS must be TRUE. This only makes sense on the ChibiOS + * operating system. + * + * @param[in] img The image structure + * @param[in] BaseFileStreamPtr A pointer to an open BaseFileStream + * + * @note This function just opens the GFILE using the basefilestream and passes it to @p gdispImageOpenGFile(). + */ + #define gdispImageOpenBaseFileStream(img, BaseFileStreamPtr) gdispImageOpenGFile((img), gfileOpenBaseFileStream((BaseFileStreamPtr), "rb")) + + /** + * @brief Open an image in memory and get it ready for drawing + * @details Determine the image format and get ready to decode the first image frame + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @pre GFILE_NEED_MEMFS must be TRUE + * + * @param[in] img The image structure + * @param[in] ptr A pointer to the image bytes in memory + * + * @note This function just opens the GFILE using the basefilestream and passes it to @p gdispImageOpenGFile(). + */ + #define gdispImageOpenMemory(img, ptr) gdispImageOpenGFile((img), gfileOpenMemory((void *)(ptr), "rb")) /** * @brief Close an image and release any dynamically allocated working storage. diff --git a/src/gdisp/image.c b/src/gdisp/image.c index dd219289..2b8395b0 100644 --- a/src/gdisp/image.c +++ b/src/gdisp/image.c @@ -16,39 +16,6 @@ #if GFX_USE_GDISP && GDISP_NEED_IMAGE -#include - -static gdispImageError imageOpen(gdispImage *img) { - gdispImageError err; - - img->bgcolor = White; - for(img->fns = ImageHandlers; img->fns < ImageHandlers+sizeof(ImageHandlers)/sizeof(ImageHandlers[0]); img->fns++) { - err = img->fns->open(img); - if (err != GDISP_IMAGE_ERR_BADFORMAT) { - if (!(err & GDISP_IMAGE_ERR_UNRECOVERABLE)) - return err; - goto unrecoverable; - } - img->io.fns->seek(&img->io, 0); - } - - err = GDISP_IMAGE_ERR_BADFORMAT; - img->type = GDISP_IMAGE_TYPE_UNKNOWN; - -unrecoverable: - img->fns->close(img); - img->flags = 0; - img->fns = 0; - img->priv = 0; - return err; -} - -gdispImageError - DEPRECATED("If possible please use gdispImageOpenFile(), gdispImageOpenMemory() or gdispImageOpenBaseFileStream() instead") - gdispImageOpen(gdispImage *img) { - return imageOpen(img); -} - #if GDISP_NEED_IMAGE_NATIVE extern gdispImageError gdispImageOpen_NATIVE(gdispImage *img); extern void gdispImageClose_NATIVE(gdispImage *img); @@ -130,92 +97,76 @@ static gdispImageHandlers ImageHandlers[] = { #endif }; -static size_t ImageGFileRead(struct gdispImageIO *pio, void *buf, size_t len) { - if (!pio->fd) return 0; - len = gfileRead((GFILE *)pio->fd, buf, len); - if ((int)len < 0) len = 0; - pio->pos += len; - return len; +gdispImageError + DEPRECATED("Use gdispImageOpenGFile() instead") + gdispImageOpen(gdispImage *img) { + return gdispImageOpenGFile(img, img->f); } -static void ImageGFileSeek(struct gdispImageIO *pio, size_t pos) { - if (!pio->fd) return; - if (pio->pos != pos) { - gfileSetPos((GFILE *)pio->fd, pos); - pio->pos = pos; - } -} - -static void ImageGFileClose(struct gdispImageIO *pio) { - if (!pio->fd) return; - gfileClose((GFILE *)pio->fd); - pio->fd = 0; - pio->pos = 0; -} - -static const gdispImageIOFunctions ImageGFileFunctions = - { ImageGFileRead, ImageGFileSeek, ImageGFileClose }; - #if GFILE_NEED_MEMFS - gdispImageError gdispImageOpenMemory(gdispImage *img, const void *memimage) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpenMemory(memimage, "rb"); - if (!img->io.fd) - return GDISP_IMAGE_ERR_NOSUCHFILE; - return imageOpen(img); - } - - bool_t DEPRECATED("Use gdispImageOpenMemory() instead. GFX_USE_GFILE, GFILE_NEED_MEMFS must also be TRUE") gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpenMemory(memimage, "rb"); - return img->io.fd != 0; + bool_t + DEPRECATED("Use gdispImageOpenMemory() instead") + gdispImageSetMemoryReader(gdispImage *img, const void *memimage) { + img->f = gfileOpenMemory((void *)memimage, "rb"); + return img->f != 0; } #endif -gdispImageError gdispImageOpenFile(gdispImage *img, const char *filename) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpen(filename, "rb"); - if (!img->io.fd) - return GDISP_IMAGE_ERR_NOSUCHFILE; - return imageOpen(img); -} - #if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX - bool_t DEPRECATED("Please use gdispImageOpenFile() instead. GFX_USE_GFILE must also be TRUE") gdispImageSetFileReader(gdispImage *img, const char *filename) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpen(filename, "rb"); - return img->io.fd != 0; + bool_t + DEPRECATED("Use gdispImageOpenFile() instead") + gdispImageSetFileReader(gdispImage *img, const char *filename) { + img->f = gfileOpen(filename, "rb"); + return img->f != 0; } #endif #if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS - bool_t DEPRECATED("Use gdispImageOpenBaseFileStream() instead. GFX_USE_GFILE, GFILE_NEED_CHIBIOSFS must also be TRUE") gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); - return img->io.fd != 0; + bool_t + DEPRECATED("Use gdispImageOpenBaseFileStream() instead") + gdispImageSetBaseFileStreamReader(gdispImage *img, void *BaseFileStreamPtr) { + img->f = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); + return img->f != 0; } - - gdispImageError gdispImageOpenBaseFileStream(gdispImage *img, void *BaseFileStreamPtr) { - img->io.fns = &ImageGFileFunctions; - img->io.pos = 0; - img->io.fd = gfileOpenBaseFileStream(BaseFileStreamPtr, "rb"); - if (!img->io.fd) - return GDISP_IMAGE_ERR_NOSUCHFILE; - return imageOpen(img); - } - #endif +gdispImageError gdispImageOpenGFile(gdispImage *img, GFILE *f) { + gdispImageError err; + + if (!f) + return GDISP_IMAGE_ERR_NOSUCHFILE; + img->f = f; + img->bgcolor = White; + for(img->fns = ImageHandlers; img->fns < ImageHandlers+sizeof(ImageHandlers)/sizeof(ImageHandlers[0]); img->fns++) { + err = img->fns->open(img); + if (err != GDISP_IMAGE_ERR_BADFORMAT) { + if ((err & GDISP_IMAGE_ERR_UNRECOVERABLE)) + goto unrecoverable; + + // Everything is possible + return err; + } + + // Try the next decoder + gfileSetPos(img->f, 0); + } + + err = GDISP_IMAGE_ERR_BADFORMAT; + img->type = GDISP_IMAGE_TYPE_UNKNOWN; + +unrecoverable: + gfileClose(img->f); + img->f = 0; + img->flags = 0; + img->fns = 0; + img->priv = 0; + return err; +} + void gdispImageClose(gdispImage *img) { if (img->fns) img->fns->close(img); - else - img->io.fns->close(&img->io); + gfileClose(img->f); img->type = GDISP_IMAGE_TYPE_UNKNOWN; img->flags = 0; img->fns = 0; @@ -223,7 +174,7 @@ void gdispImageClose(gdispImage *img) { } bool_t gdispImageIsOpen(gdispImage *img) { - return img->type != GDISP_IMAGE_TYPE_UNKNOWN && img->fns != 0; + return img->fns != 0; } void gdispImageSetBgColor(gdispImage *img, color_t bgcolor) { diff --git a/src/gdisp/image_bmp.c b/src/gdisp/image_bmp.c index 158d6edc..8ff40ca0 100644 --- a/src/gdisp/image_bmp.c +++ b/src/gdisp/image_bmp.c @@ -118,6 +118,19 @@ typedef struct gdispImagePrivate { pixel_t buf[BLIT_BUFFER_SIZE]; } gdispImagePrivate; +void gdispImageClose_BMP(gdispImage *img) { + if (img->priv) { +#if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE + if (img->priv->palette) + gdispImageFree(img, (void *)img->priv->palette, img->priv->palsize*sizeof(color_t)); +#endif + if (img->priv->frame0cache) + gdispImageFree(img, (void *)img->priv->frame0cache, img->width*img->height*sizeof(pixel_t)); + gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); + img->priv = 0; + } +} + gdispImageError gdispImageOpen_BMP(gdispImage *img) { gdispImagePrivate *priv; uint8_t hdr[2]; @@ -126,7 +139,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { uint32_t offsetColorTable; /* Read the file identifier */ - if (img->io.fns->read(&img->io, hdr, 2) != 2) + if (gfileRead(img->f, hdr, 2) != 2) return GDISP_IMAGE_ERR_BADFORMAT; // It can't be us /* Process the BITMAPFILEHEADER structure */ @@ -154,18 +167,18 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { #endif /* Skip the size field and the 2 reserved fields */ - if (img->io.fns->read(&img->io, priv->buf, 8) != 8) + if (gfileRead(img->f, priv->buf, 8) != 8) goto baddatacleanup; /* Get the offset to the bitmap data */ - if (img->io.fns->read(&img->io, &priv->frame0pos, 4) != 4) + if (gfileRead(img->f, &priv->frame0pos, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->frame0pos); /* Process the BITMAPCOREHEADER structure */ /* Get the offset to the colour data */ - if (img->io.fns->read(&img->io, &offsetColorTable, 4) != 4) + if (gfileRead(img->f, &offsetColorTable, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(offsetColorTable); offsetColorTable += 14; // Add the size of the BITMAPFILEHEADER @@ -175,7 +188,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { img->priv->bmpflags |= BMP_V2; // Read the header - if (img->io.fns->read(&img->io, priv->buf, 12-4) != 12-4) + if (gfileRead(img->f, priv->buf, 12-4) != 12-4) goto baddatacleanup; // Get the width img->width = *(uint16_t *)(((uint8_t *)priv->buf)+0); @@ -224,7 +237,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { priv->bmpflags |= BMP_V4; // Read the header - if (img->io.fns->read(&img->io, priv->buf, 40-4) != 40-4) + if (gfileRead(img->f, priv->buf, 40-4) != 40-4) goto baddatacleanup; // Get the width adword = *(uint32_t *)(((uint8_t *)priv->buf)+0); @@ -327,18 +340,18 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { #if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE /* Load the palette tables */ if (priv->bmpflags & BMP_PALETTE) { - img->io.fns->seek(&img->io, offsetColorTable); + gfileSetPos(img->f, offsetColorTable); if (!(priv->palette = (color_t *)gdispImageAlloc(img, priv->palsize*sizeof(color_t)))) return GDISP_IMAGE_ERR_NOMEMORY; if (priv->bmpflags & BMP_V2) { for(aword = 0; aword < priv->palsize; aword++) { - if (img->io.fns->read(&img->io, &priv->buf, 3) != 3) goto baddatacleanup; + if (gfileRead(img->f, &priv->buf, 3) != 3) goto baddatacleanup; priv->palette[aword] = RGB2COLOR(((uint8_t *)priv->buf)[2], ((uint8_t *)priv->buf)[1], ((uint8_t *)priv->buf)[0]); } } else { for(aword = 0; aword < priv->palsize; aword++) { - if (img->io.fns->read(&img->io, &priv->buf, 4) != 4) goto baddatacleanup; + if (gfileRead(img->f, &priv->buf, 4) != 4) goto baddatacleanup; priv->palette[aword] = RGB2COLOR(((uint8_t *)priv->buf)[2], ((uint8_t *)priv->buf)[1], ((uint8_t *)priv->buf)[0]); } } @@ -349,15 +362,15 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) { #if GDISP_NEED_IMAGE_BMP_16 || GDISP_NEED_IMAGE_BMP_32 /* Load the bit masks */ if (priv->bmpflags & BMP_COMP_MASK) { - img->io.fns->seek(&img->io, offsetColorTable); - if (img->io.fns->read(&img->io, &priv->maskred, 4) != 4) goto baddatacleanup; + gfileSetPos(img->f, offsetColorTable); + if (gfileRead(img->f, &priv->maskred, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->maskred); - if (img->io.fns->read(&img->io, &priv->maskgreen, 4) != 4) goto baddatacleanup; + if (gfileRead(img->f, &priv->maskgreen, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->maskgreen); - if (img->io.fns->read(&img->io, &priv->maskblue, 4) != 4) goto baddatacleanup; + if (gfileRead(img->f, &priv->maskblue, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->maskblue); if (priv->bmpflags & BMP_V4) { - if (img->io.fns->read(&img->io, &priv->maskalpha, 4) != 4) goto baddatacleanup; + if (gfileRead(img->f, &priv->maskalpha, 4) != 4) goto baddatacleanup; CONVERT_FROM_DWORD_LE(priv->maskalpha); } else priv->maskalpha = 0; @@ -419,20 +432,6 @@ unsupportedcleanup: return GDISP_IMAGE_ERR_UNSUPPORTED; // Not supported } -void gdispImageClose_BMP(gdispImage *img) { - if (img->priv) { -#if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE - if (img->priv->palette) - gdispImageFree(img, (void *)img->priv->palette, img->priv->palsize*sizeof(color_t)); -#endif - if (img->priv->frame0cache) - gdispImageFree(img, (void *)img->priv->frame0cache, img->width*img->height*sizeof(pixel_t)); - gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); - img->priv = 0; - } - img->io.fns->close(&img->io); -} - static coord_t getPixels(gdispImage *img, coord_t x) { gdispImagePrivate * priv; color_t * pc; @@ -454,7 +453,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { len = 0; while(x < img->width && len <= BLIT_BUFFER_SIZE-32) { - if (img->io.fns->read(&img->io, &b, 4) != 4) + if (gfileRead(img->f, &b, 4) != 4) return 0; for(m=0x80; m; m >>= 1, pc++) @@ -499,7 +498,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { return len; } else if (priv->bmpflags & BMP_RLE_ABS) { while (priv->rlerun && len <= BLIT_BUFFER_SIZE-2 && x < img->width) { - if (img->io.fns->read(&img->io, &b, 1) != 1) + if (gfileRead(img->f, &b, 1) != 1) return 0; *pc++ = priv->palette[b[0] >> 4]; priv->rlerun--; @@ -514,8 +513,8 @@ static coord_t getPixels(gdispImage *img, coord_t x) { } if (priv->rlerun) // Return if we have more run to do return len; - if ((img->io.pos - priv->frame0pos)&1) { // Make sure we are on a word boundary - if (img->io.fns->read(&img->io, &b, 1) != 1) + if ((gfileGetPos(img->f) - priv->frame0pos)&1) { // Make sure we are on a word boundary + if (gfileRead(img->f, &b, 1) != 1) return 0; } } @@ -524,7 +523,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { priv->bmpflags &= ~(BMP_RLE_ENC|BMP_RLE_ABS); // There are always at least 2 bytes in an RLE code - if (img->io.fns->read(&img->io, &b, 2) != 2) + if (gfileRead(img->f, &b, 2) != 2) return 0; if (b[0]) { // Encoded mode @@ -541,7 +540,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { return len; } else if (b[1] == 2) { // Delta x, y // There are always at least 2 bytes in an RLE code - if (img->io.fns->read(&img->io, &b, 2) != 2) + if (gfileRead(img->f, &b, 2) != 2) return 0; priv->rlerun = b[0] + (uint16_t)b[1] * img->width; priv->rlecode = 0; // Who knows what color this should really be @@ -559,7 +558,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { uint8_t b[4]; while(x < img->width && len <= BLIT_BUFFER_SIZE-8) { - if (img->io.fns->read(&img->io, &b, 4) != 4) + if (gfileRead(img->f, &b, 4) != 4) return 0; *pc++ = priv->palette[b[0] >> 4]; @@ -599,7 +598,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { return len; } else if (priv->bmpflags & BMP_RLE_ABS) { while (priv->rlerun && len < BLIT_BUFFER_SIZE && x < img->width) { - if (img->io.fns->read(&img->io, &b, 1) != 1) + if (gfileRead(img->f, &b, 1) != 1) return 0; *pc++ = priv->palette[b[0]]; priv->rlerun--; @@ -608,8 +607,8 @@ static coord_t getPixels(gdispImage *img, coord_t x) { } if (priv->rlerun) // Return if we have more run to do return len; - if ((img->io.pos - priv->frame0pos)&1) { // Make sure we are on a word boundary - if (img->io.fns->read(&img->io, &b, 1) != 1) + if ((gfileGetPos(img->f) - priv->frame0pos)&1) { // Make sure we are on a word boundary + if (gfileRead(img->f, &b, 1) != 1) return 0; } } @@ -618,7 +617,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { priv->bmpflags &= ~(BMP_RLE_ENC|BMP_RLE_ABS); // There are always at least 2 bytes in an RLE code - if (img->io.fns->read(&img->io, &b, 2) != 2) + if (gfileRead(img->f, &b, 2) != 2) return 0; if (b[0]) { // Encoded mode @@ -635,7 +634,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { return len; } else if (b[1] == 2) { // Delta x, y // There are always at least 2 bytes in an RLE code - if (img->io.fns->read(&img->io, &b, 2) != 2) + if (gfileRead(img->f, &b, 2) != 2) return GDISP_IMAGE_ERR_BADDATA; priv->rlerun = b[0] + (uint16_t)b[1] * img->width; priv->rlecode = 0; // Who knows what color this should really be @@ -653,7 +652,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { uint8_t b[4]; while(x < img->width && len <= BLIT_BUFFER_SIZE-4) { - if (img->io.fns->read(&img->io, &b, 4) != 4) + if (gfileRead(img->f, &b, 4) != 4) return 0; *pc++ = priv->palette[b[0]]; @@ -675,7 +674,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { color_t r, g, b; while(x < img->width && len <= BLIT_BUFFER_SIZE-2) { - if (img->io.fns->read(&img->io, &w, 4) != 4) + if (gfileRead(img->f, &w, 4) != 4) return 0; CONVERT_FROM_WORD_LE(w[0]); CONVERT_FROM_WORD_LE(w[1]); @@ -720,7 +719,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { uint8_t b[3]; while(x < img->width && len < BLIT_BUFFER_SIZE) { - if (img->io.fns->read(&img->io, &b, 3) != 3) + if (gfileRead(img->f, &b, 3) != 3) return 0; *pc++ = RGB2COLOR(b[2], b[1], b[0]); x++; @@ -729,7 +728,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { if (x >= img->width) { // Make sure we have read a multiple of 4 bytes for the line - if ((x & 3) && img->io.fns->read(&img->io, &b, x & 3) != (x & 3)) + if ((x & 3) && gfileRead(img->f, &b, x & 3) != (x & 3)) return 0; } } @@ -743,7 +742,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) { color_t r, g, b; while(x < img->width && len < BLIT_BUFFER_SIZE) { - if (img->io.fns->read(&img->io, &dw, 4) != 4) + if (gfileRead(img->f, &dw, 4) != 4) return 0; CONVERT_FROM_DWORD_LE(dw); if (priv->shiftred < 0) @@ -791,7 +790,7 @@ gdispImageError gdispImageCache_BMP(gdispImage *img) { return GDISP_IMAGE_ERR_NOMEMORY; /* Read the entire bitmap into cache */ - img->io.fns->seek(&img->io, priv->frame0pos); + gfileSetPos(img->f, priv->frame0pos); #if GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8_RLE priv->rlerun = 0; priv->rlecode = 0; @@ -847,7 +846,7 @@ gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coo } /* Start decoding from the beginning */ - img->io.fns->seek(&img->io, priv->frame0pos); + gfileSetPos(img->f, priv->frame0pos); #if GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8_RLE priv->rlerun = 0; priv->rlecode = 0; diff --git a/src/gdisp/image_gif.c b/src/gdisp/image_gif.c index 1ff72ff0..06f4ef6a 100644 --- a/src/gdisp/image_gif.c +++ b/src/gdisp/image_gif.c @@ -172,9 +172,9 @@ static gdispImageError startDecode(gdispImage *img) { // Local palette decode->maxpixel = priv->frame.palsize-1; decode->palette = (color_t *)(decode+1); - img->io.fns->seek(&img->io, priv->frame.pospal); + gfileSetPos(img->f, priv->frame.pospal); for(cnt = 0; cnt < priv->frame.palsize; cnt++) { - if (img->io.fns->read(&img->io, &decode->buf, 3) != 3) + if (gfileRead(img->f, &decode->buf, 3) != 3) goto baddatacleanup; decode->palette[cnt] = RGB2COLOR(decode->buf[0], decode->buf[1], decode->buf[2]); } @@ -188,8 +188,8 @@ static gdispImageError startDecode(gdispImage *img) { } // Get the initial lzw code size and values - img->io.fns->seek(&img->io, priv->frame.posimg); - if (img->io.fns->read(&img->io, &decode->bitsperpixel, 1) != 1 || decode->bitsperpixel >= MAX_CODE_BITS) + gfileSetPos(img->f, priv->frame.posimg); + if (gfileRead(img->f, &decode->bitsperpixel, 1) != 1 || decode->bitsperpixel >= MAX_CODE_BITS) goto baddatacleanup; decode->code_clear = 1 << decode->bitsperpixel; decode->code_eof = decode->code_clear + 1; @@ -273,8 +273,8 @@ static uint16_t getbytes(gdispImage *img) { // Get another code - a code is made up of decode->bitspercode bits. while (decode->shiftbits < decode->bitspercode) { // Get a byte - we may have to start a new data block - if ((!decode->blocksz && (img->io.fns->read(&img->io, &decode->blocksz, 1) != 1 || !decode->blocksz)) - || img->io.fns->read(&img->io, &bdata, 1) != 1) { + if ((!decode->blocksz && (gfileRead(img->f, &decode->blocksz, 1) != 1 || !decode->blocksz)) + || gfileRead(img->f, &bdata, 1) != 1) { // Pretend we got the EOF code - some encoders seem to just end the file decode->code_last = decode->code_eof; return cnt; @@ -302,8 +302,8 @@ static uint16_t getbytes(gdispImage *img) { if (code == decode->code_eof) { // Skip to the end of the data blocks do { - img->io.fns->seek(&img->io, img->io.pos+decode->blocksz); - } while (img->io.fns->read(&img->io, &decode->blocksz, 1) == 1 && decode->blocksz); + gfileSetPos(img->f, gfileGetPos(img->f)+decode->blocksz); + } while (gfileRead(img->f, &decode->blocksz, 1) == 1 && decode->blocksz); // Mark the end decode->code_last = decode->code_eof; @@ -398,8 +398,8 @@ static gdispImageError initFrame(gdispImage *img) { priv->dispose.height = priv->frame.height; // Check for a cached version of this image - for(cache=priv->cache; cache && cache->frame.posstart <= img->io.pos; cache=cache->next) { - if (cache->frame.posstart == img->io.pos) { + for(cache=priv->cache; cache && cache->frame.posstart <= (size_t)gfileGetPos(img->f); cache=cache->next) { + if (cache->frame.posstart == (size_t)gfileGetPos(img->f)) { priv->frame = cache->frame; priv->curcache = cache; return GDISP_IMAGE_ERR_OK; @@ -408,20 +408,20 @@ static gdispImageError initFrame(gdispImage *img) { // Get ready for a new image priv->curcache = 0; - priv->frame.posstart = img->io.pos; + priv->frame.posstart = gfileGetPos(img->f); priv->frame.flags = 0; priv->frame.delay = 0; priv->frame.palsize = 0; // Process blocks until we reach the image descriptor while(1) { - if (img->io.fns->read(&img->io, &blocktype, 1) != 1) + if (gfileRead(img->f, &blocktype, 1) != 1) return GDISP_IMAGE_ERR_BADDATA; switch(blocktype) { case 0x2C: //',' - IMAGE_DESC_RECORD_TYPE; // Read the Image Descriptor - if (img->io.fns->read(&img->io, priv->buf, 9) != 9) + if (gfileRead(img->f, priv->buf, 9) != 9) return GDISP_IMAGE_ERR_BADDATA; priv->frame.x = *(uint16_t *)(((uint8_t *)priv->buf)+0); CONVERT_FROM_WORD_LE(priv->frame.x); @@ -437,7 +437,7 @@ static gdispImageError initFrame(gdispImage *img) { priv->frame.flags |= GIFL_INTERLACE; // We are ready to go for the actual palette read and image decode - priv->frame.pospal = img->io.pos; + priv->frame.pospal = gfileGetPos(img->f); priv->frame.posimg = priv->frame.pospal+priv->frame.palsize*3; priv->frame.posend = 0; @@ -448,13 +448,13 @@ static gdispImageError initFrame(gdispImage *img) { case 0x21: //'!' - EXTENSION_RECORD_TYPE; // Read the extension type - if (img->io.fns->read(&img->io, &blocktype, 1) != 1) + if (gfileRead(img->f, &blocktype, 1) != 1) return GDISP_IMAGE_ERR_BADDATA; switch(blocktype) { case 0xF9: // EXTENSION - Graphics Control Block // Read the GCB - if (img->io.fns->read(&img->io, priv->buf, 6) != 6) + if (gfileRead(img->f, priv->buf, 6) != 6) return GDISP_IMAGE_ERR_BADDATA; // Check we have read a 4 byte data block and a data block terminator (0) if (((uint8_t *)priv->buf)[0] != 4 || ((uint8_t *)priv->buf)[5] != 0) @@ -485,7 +485,7 @@ static gdispImageError initFrame(gdispImage *img) { if (priv->flags & GIF_LOOP) goto skipdatablocks; // Read the Application header - if (img->io.fns->read(&img->io, priv->buf, 16) != 16) + if (gfileRead(img->f, priv->buf, 16) != 16) return GDISP_IMAGE_ERR_BADDATA; // Check we have read a 11 byte data block if (((uint8_t *)priv->buf)[0] != 11 && ((uint8_t *)priv->buf)[12] != 3) @@ -516,11 +516,11 @@ static gdispImageError initFrame(gdispImage *img) { // We don't understand this extension - just skip it by skipping data blocks skipdatablocks: while(1) { - if (img->io.fns->read(&img->io, &blocksz, 1) != 1) + if (gfileRead(img->f, &blocksz, 1) != 1) return GDISP_IMAGE_ERR_BADDATA; if (!blocksz) break; - img->io.fns->seek(&img->io, img->io.pos + blocksz); + gfileSetPos(img->f, gfileGetPos(img->f) + blocksz); } break; } @@ -537,7 +537,7 @@ static gdispImageError initFrame(gdispImage *img) { } // Seek back to frame0 - img->io.fns->seek(&img->io, priv->frame0pos); + gfileSetPos(img->f, priv->frame0pos); return GDISP_IMAGE_LOOP; default: // UNDEFINED_RECORD_TYPE; @@ -546,13 +546,34 @@ static gdispImageError initFrame(gdispImage *img) { } } +void gdispImageClose_GIF(gdispImage *img) { + gdispImagePrivate * priv; + imgcache * cache; + imgcache * ncache; + + priv = img->priv; + if (priv) { + // Free any stored frames + cache = priv->cache; + while(cache) { + ncache = cache->next; + gdispImageFree(img, (void *)cache, sizeof(imgcache)+cache->frame.width*cache->frame.height+cache->frame.palsize*sizeof(color_t)); + cache = ncache; + } + if (priv->palette) + gdispImageFree(img, (void *)priv->palette, priv->palsize*sizeof(color_t)); + gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); + img->priv = 0; + } +} + gdispImageError gdispImageOpen_GIF(gdispImage *img) { gdispImagePrivate *priv; uint8_t hdr[6]; uint16_t aword; /* Read the file identifier */ - if (img->io.fns->read(&img->io, hdr, 6) != 6) + if (gfileRead(img->f, hdr, 6) != 6) return GDISP_IMAGE_ERR_BADFORMAT; // It can't be us /* Process the GIFFILEHEADER structure */ @@ -580,7 +601,7 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { /* Process the Screen Descriptor structure */ // Read the screen descriptor - if (img->io.fns->read(&img->io, priv->buf, 7) != 7) + if (gfileRead(img->f, priv->buf, 7) != 7) goto baddatacleanup; // Get the width img->width = *(uint16_t *)(((uint8_t *)priv->buf)+0); @@ -596,7 +617,7 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { goto nomemcleanup; // Read the global palette for(aword = 0; aword < priv->palsize; aword++) { - if (img->io.fns->read(&img->io, &priv->buf, 3) != 3) + if (gfileRead(img->f, &priv->buf, 3) != 3) goto baddatacleanup; priv->palette[aword] = RGB2COLOR(((uint8_t *)priv->buf)[0], ((uint8_t *)priv->buf)[1], ((uint8_t *)priv->buf)[2]); } @@ -604,7 +625,7 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { priv->bgcolor = ((uint8_t *)priv->buf)[5]; // Save the fram0pos - priv->frame0pos = img->io.pos; + priv->frame0pos = gfileGetPos(img->f); // Read the first frame descriptor switch(initFrame(img)) { @@ -628,28 +649,6 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) { } } -void gdispImageClose_GIF(gdispImage *img) { - gdispImagePrivate * priv; - imgcache * cache; - imgcache * ncache; - - priv = img->priv; - if (priv) { - // Free any stored frames - cache = priv->cache; - while(cache) { - ncache = cache->next; - gdispImageFree(img, (void *)cache, sizeof(imgcache)+cache->frame.width*cache->frame.height+cache->frame.palsize*sizeof(color_t)); - cache = ncache; - } - if (priv->palette) - gdispImageFree(img, (void *)priv->palette, priv->palsize*sizeof(color_t)); - gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); - img->priv = 0; - } - img->io.fns->close(&img->io); -} - gdispImageError gdispImageCache_GIF(gdispImage *img) { gdispImagePrivate * priv; imgcache * cache; @@ -786,7 +785,7 @@ gdispImageError gdispImageCache_GIF(gdispImage *img) { } // We could be pedantic here but extra bytes won't hurt us while(getbytes(img)); - priv->frame.posend = cache->frame.posend = img->io.pos; + priv->frame.posend = cache->frame.posend = gfileGetPos(img->f); // Save everything priv->curcache = cache; @@ -1150,7 +1149,7 @@ gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coo } // We could be pedantic here but extra bytes won't hurt us while (getbytes(img)); - priv->frame.posend = img->io.pos; + priv->frame.posend = gfileGetPos(img->f); stopDecode(img); return GDISP_IMAGE_ERR_OK; @@ -1173,19 +1172,19 @@ delaytime_t gdispImageNext_GIF(gdispImage *img) { // We need to get to the end of this frame if (!priv->frame.posend) { // We don't know where the end of the frame is yet - find it! - img->io.fns->seek(&img->io, priv->frame.posimg+1); // Skip the code size byte too + gfileSetPos(img->f, priv->frame.posimg+1); // Skip the code size byte too while(1) { - if (img->io.fns->read(&img->io, &blocksz, 1) != 1) + if (gfileRead(img->f, &blocksz, 1) != 1) return TIME_INFINITE; if (!blocksz) break; - img->io.fns->seek(&img->io, img->io.pos + blocksz); + gfileSetPos(img->f, gfileGetPos(img->f) + blocksz); } - priv->frame.posend = img->io.pos; + priv->frame.posend = gfileGetPos(img->f); } // Seek to the end of this frame - img->io.fns->seek(&img->io, priv->frame.posend); + gfileSetPos(img->f, priv->frame.posend); // Read the next frame descriptor for(blocksz=0; blocksz < 2; blocksz++) { // 2 loops max to prevent cycling forever with a bad file diff --git a/src/gdisp/image_native.c b/src/gdisp/image_native.c index 7f249ae8..c458531e 100644 --- a/src/gdisp/image_native.c +++ b/src/gdisp/image_native.c @@ -33,11 +33,20 @@ typedef struct gdispImagePrivate { pixel_t buf[BLIT_BUFFER_SIZE]; } gdispImagePrivate; +void gdispImageClose_NATIVE(gdispImage *img) { + if (img->priv) { + if (img->priv->frame0cache) + gdispImageFree(img, (void *)img->priv->frame0cache, img->width * img->height * sizeof(pixel_t)); + gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); + img->priv = 0; + } +} + gdispImageError gdispImageOpen_NATIVE(gdispImage *img) { uint8_t hdr[HEADER_SIZE]; /* Read the 8 byte header */ - if (img->io.fns->read(&img->io, hdr, 8) != 8) + if (gfileRead(img->f, hdr, 8) != 8) return GDISP_IMAGE_ERR_BADFORMAT; // It can't be us if (hdr[0] != 'N' || hdr[1] != 'I') @@ -60,16 +69,6 @@ gdispImageError gdispImageOpen_NATIVE(gdispImage *img) { return GDISP_IMAGE_ERR_OK; } -void gdispImageClose_NATIVE(gdispImage *img) { - if (img->priv) { - if (img->priv->frame0cache) - gdispImageFree(img, (void *)img->priv->frame0cache, img->width * img->height * sizeof(pixel_t)); - gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); - img->priv = 0; - } - img->io.fns->close(&img->io); -} - gdispImageError gdispImageCache_NATIVE(gdispImage *img) { size_t len; @@ -84,8 +83,8 @@ gdispImageError gdispImageCache_NATIVE(gdispImage *img) { return GDISP_IMAGE_ERR_NOMEMORY; /* Read the entire bitmap into cache */ - img->io.fns->seek(&img->io, FRAME0POS); - if (img->io.fns->read(&img->io, img->priv->frame0cache, len) != len) + gfileSetPos(img->f, FRAME0POS); + if (gfileRead(img->f, img->priv->frame0cache, len) != len) return GDISP_IMAGE_ERR_BADDATA; return GDISP_IMAGE_ERR_OK; @@ -112,12 +111,12 @@ gdispImageError gdispImageGDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, /* Cycle through the lines */ for(;cy;cy--, y++) { /* Move to the start of the line */ - img->io.fns->seek(&img->io, pos); + gfileSetPos(img->f, pos); /* Draw the line in chunks using BitBlt */ for(mx = x, mcx = cx; mcx > 0; mcx -= len, mx += len) { // Read the data - len = img->io.fns->read(&img->io, + len = gfileRead(img->f, img->priv->buf, mcx > BLIT_BUFFER_SIZE ? (BLIT_BUFFER_SIZE*sizeof(pixel_t)) : (mcx * sizeof(pixel_t))) / sizeof(pixel_t); From bd4827922708efc85c878ebd17ca6a8c88bc75b5 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 14:07:29 +1000 Subject: [PATCH 16/23] Update gwin Images to properly use new GFILE based images --- include/gwin/image.h | 53 ++++++++++++++++++++++++------------------ src/gwin/gimage.c | 55 ++------------------------------------------ 2 files changed, 33 insertions(+), 75 deletions(-) diff --git a/include/gwin/image.h b/include/gwin/image.h index 66dd0b94..66aba3d1 100644 --- a/include/gwin/image.h +++ b/include/gwin/image.h @@ -60,42 +60,51 @@ GHandle gwinGImageCreate(GDisplay *g, GImageObject *widget, GWindowInit *pInit); #define gwinImageCreate(w, pInit) gwinGImageCreate(GDISP, w, pInit) /** - * @brief Sets the input routines that support reading the image from memory - * in RAM or flash. - * @return TRUE if the IO open function succeeds + * @brief Opens the image using a GFILE + * @return TRUE if the image can be opened * * @param[in] gh The widget (must be an image widget) - * @param[in] memory A pointer to the image in RAM or Flash + * @param[in] f The open (for reading) GFILE to use * * @api */ -bool_t gwinImageOpenMemory(GHandle gh, const void* memory); +bool_t gwinImageOpenGFile(GHandle gh, GFILE *f); + +/** + * @brief Opens the image using the specified filename + * @return TRUE if the open succeeds + * + * @param[in] gh The widget (must be an image widget) + * @param[in] filename The filename to open + * + * @api + */ +#define gwinImageOpenFile(gh, filename) gwinImageOpenGFile((gh), gfileOpen((filename), "rb")) -#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX || defined(__DOXYGEN__) /** - * @brief Sets the input routines that support reading the image from a file + * @brief Sets the input routines that support reading the image from memory + * in RAM or flash. + * @pre GFILE_NEED_MEMFS must be TRUE * @return TRUE if the IO open function succeeds * * @param[in] gh The widget (must be an image widget) - * @param[in] filename The filename to open + * @param[in] ptr A pointer to the image in RAM or Flash * * @api */ - bool_t gwinImageOpenFile(GHandle gh, const char* filename); -#endif +#define gwinImageOpenMemory(gh, ptr) gwinImageOpenGFile((gh), gfileOpenMemory((void *)(ptr), "rb")) -#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) - /** - * @brief Sets the input routines that support reading the image from a BaseFileStream (eg. an SD-Card). - * @return TRUE if the IO open function succeeds - * - * @param[in] gh The widget (must be an image widget) - * @param[in] streamPtr A pointer to the (open) BaseFileStream object. - * - * @api - */ - bool_t gwinImageOpenStream(GHandle gh, void *streamPtr); -#endif +/** + * @brief Sets the input routines that support reading the image from a BaseFileStream (eg. an SD-Card). + * @return TRUE if the IO open function succeeds + * @pre GFILE_NEED_CHIBIOSFS and GFX_USE_OS_CHIBIOS must be TRUE + * + * @param[in] gh The widget (must be an image widget) + * @param[in] streamPtr A pointer to the (open) BaseFileStream object. + * + * @api + */ +#define gwinImageOpenStream(gh, streamPtr) gwinImageOpenGFile((gh), gfileOpenBaseFIleStream((streamPtr), "rb")) /** * @brief Cache the image. diff --git a/src/gwin/gimage.c b/src/gwin/gimage.c index b1f8e078..e4032b96 100644 --- a/src/gwin/gimage.c +++ b/src/gwin/gimage.c @@ -139,14 +139,11 @@ GHandle gwinGImageCreate(GDisplay *g, GImageObject *gobj, GWindowInit *pInit) { return (GHandle)gobj; } -bool_t gwinImageOpenMemory(GHandle gh, const void* memory) { +bool_t gwinImageOpenGFile(GHandle gh, GFILE *f) { if (gdispImageIsOpen(&widget(gh)->image)) gdispImageClose(&widget(gh)->image); - if (!gdispImageSetMemoryReader(&widget(gh)->image, memory)) - return FALSE; - - if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) + if ((gdispImageOpenGFile(&widget(gh)->image, f) & GDISP_IMAGE_ERR_UNRECOVERABLE)) return FALSE; if ((gh->flags & GWIN_FLG_VISIBLE)) { @@ -161,54 +158,6 @@ bool_t gwinImageOpenMemory(GHandle gh, const void* memory) { return TRUE; } -#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX || defined(__DOXYGEN__) -bool_t gwinImageOpenFile(GHandle gh, const char* filename) { - if (gdispImageIsOpen(&widget(gh)->image)) - gdispImageClose(&widget(gh)->image); - - if (!gdispImageSetFileReader(&widget(gh)->image, filename)) - return FALSE; - - if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) - return FALSE; - - if ((gh->flags & GWIN_FLG_VISIBLE)) { - // Setting the clip here shouldn't be necessary if the redraw doesn't overdraw - // but we put it in for safety anyway - #if GDISP_NEED_CLIP - gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height); - #endif - _redraw(gh); - } - - return TRUE; -} -#endif - -#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) -bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) { - if (gdispImageIsOpen(&widget(gh)->image)) - gdispImageClose(&widget(gh)->image); - - if (!gdispImageSetBaseFileStreamReader(&widget(gh)->image, streamPtr)) - return FALSE; - - if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK) - return FALSE; - - if ((gh->flags & GWIN_FLG_VISIBLE)) { - // Setting the clip here shouldn't be necessary if the redraw doesn't overdraw - // but we put it in for safety anyway - #if GDISP_NEED_CLIP - gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height); - #endif - _redraw(gh); - } - - return TRUE; -} -#endif - gdispImageError gwinImageCache(GHandle gh) { return gdispImageCache(&widget(gh)->image); } From 010e0f0d626b0f03cec9e8dd876762acb38fafc3 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 14:08:39 +1000 Subject: [PATCH 17/23] Update demo's with images in them --- demos/modules/gdisp/images/gfxconf.h | 3 +++ demos/modules/gdisp/images/main.c | 5 ++--- demos/modules/gdisp/images_animated/gfxconf.h | 3 +++ demos/modules/gdisp/images_animated/main.c | 5 ++--- demos/modules/gwin/widgets/gfxconf.h | 4 ++++ demos/modules/gwin/widgets/main.c | 3 +-- 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/demos/modules/gdisp/images/gfxconf.h b/demos/modules/gdisp/images/gfxconf.h index 6cd78b37..09dbe30c 100644 --- a/demos/modules/gdisp/images/gfxconf.h +++ b/demos/modules/gdisp/images/gfxconf.h @@ -51,5 +51,8 @@ #define GDISP_NEED_IMAGE_JPG FALSE #define GDISP_NEED_IMAGE_PNG FALSE +#define GFX_USE_GFILE TRUE +#define GFILE_NEED_MEMFS TRUE + #endif /* _GFXCONF_H */ diff --git a/demos/modules/gdisp/images/main.c b/demos/modules/gdisp/images/main.c index b87f663c..021bf9f5 100644 --- a/demos/modules/gdisp/images/main.c +++ b/demos/modules/gdisp/images/main.c @@ -53,12 +53,11 @@ int main(void) { // Set up IO for our image #if USE_MEMORY_FILE - gdispImageSetMemoryReader(&myImage, test_pal8); + gdispImageOpenMemory(&myImage, test_pal8); #else - gdispImageSetSimulFileReader(&myImage, "test-pal8.bmp"); + gdispImageOpenFile(&myImage, "test-pal8.bmp"); #endif - gdispImageOpen(&myImage); gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0); gdispImageClose(&myImage); diff --git a/demos/modules/gdisp/images_animated/gfxconf.h b/demos/modules/gdisp/images_animated/gfxconf.h index cc38ed36..b2dcaf92 100644 --- a/demos/modules/gdisp/images_animated/gfxconf.h +++ b/demos/modules/gdisp/images_animated/gfxconf.h @@ -51,5 +51,8 @@ #define GDISP_NEED_IMAGE_JPG FALSE #define GDISP_NEED_IMAGE_PNG FALSE +#define GFX_USE_GFILE TRUE +#define GFILE_NEED_MEMFS TRUE + #endif /* _GFXCONF_H */ diff --git a/demos/modules/gdisp/images_animated/main.c b/demos/modules/gdisp/images_animated/main.c index 9b2b5d2c..bf49f692 100644 --- a/demos/modules/gdisp/images_animated/main.c +++ b/demos/modules/gdisp/images_animated/main.c @@ -76,12 +76,11 @@ int main(void) { // Set up IO for our image #if USE_MEMORY_FILE - gdispImageSetMemoryReader(&myImage, testanim); + if (!(gdispImageOpenMemory(&myImage, testanim) & GDISP_IMAGE_ERR_UNRECOVERABLE)) { #else - gdispImageSetFileReader(&myImage, "testanim.gif"); + if (!(gdispImageOpenFile(&myImage, "testanim.gif") & GDISP_IMAGE_ERR_UNRECOVERABLE)) { #endif - if (gdispImageOpen(&myImage) == GDISP_IMAGE_ERR_OK) { gdispImageSetBgColor(&myImage, MY_BG_COLOR); // Adjust the error indicator area if necessary if (myImage.width > errx && myImage.height < sheight) { diff --git a/demos/modules/gwin/widgets/gfxconf.h b/demos/modules/gwin/widgets/gfxconf.h index b22af659..b536de4c 100644 --- a/demos/modules/gwin/widgets/gfxconf.h +++ b/demos/modules/gwin/widgets/gfxconf.h @@ -79,6 +79,10 @@ #define GWIN_NEED_RADIO TRUE #define GWIN_NEED_LIST TRUE +/* Features for the GFILE subsystem. */ +#define GFX_USE_GFILE TRUE +#define GFILE_NEED_MEMFS TRUE + /* Features for the GINPUT subsystem. */ #define GINPUT_NEED_MOUSE TRUE diff --git a/demos/modules/gwin/widgets/main.c b/demos/modules/gwin/widgets/main.c index af2926d7..80c39dd9 100644 --- a/demos/modules/gwin/widgets/main.c +++ b/demos/modules/gwin/widgets/main.c @@ -184,8 +184,7 @@ static void createWidgets(void) { wi.g.x = 0+2*(LIST_WIDTH+1); wi.text = "L3"; ghList3 = gwinListCreate(0, &wi, TRUE); gwinListAddItem(ghList3, "Item 0", FALSE); gwinListAddItem(ghList3, "Item 1", FALSE); gwinListAddItem(ghList3, "Item 2", FALSE); gwinListAddItem(ghList3, "Item 3", FALSE); - gdispImageSetMemoryReader(&imgYesNo, image_yesno); - gdispImageOpen(&imgYesNo); + gdispImageOpenMemory(&imgYesNo, image_yesno); gwinListItemSetImage(ghList3, 1, &imgYesNo); gwinListItemSetImage(ghList3, 3, &imgYesNo); From f7d6b9b58e4e8d979004026b41c1bfd275218fb9 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 18:43:39 +1000 Subject: [PATCH 18/23] Bug fixes to GFILE. --- src/gfile/inc_nativefs.c | 28 +++++++++++++---------- src/gfile/inc_romfs.c | 20 +++++++++++----- tools/file2c/binaries/windows/file2c.exe | Bin 22030 -> 22030 bytes tools/file2c/src/file2c.c | 2 +- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index 390a885d..4ecb2004 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -16,7 +16,7 @@ #include #include #include -#include +//#include static GFILE NativeStdIn; static GFILE NativeStdOut; @@ -50,7 +50,7 @@ static const GFILEVMT FsNativeVMT = { #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsNativeVMT -static char *flags2mode(char *buf, uint16_t flags) { +static void flags2mode(char *buf, uint16_t flags) { if (flags & GFILEFLG_MUSTEXIST) *buf = 'r'; else if (flags & GFILEFLG_APPEND) @@ -67,32 +67,36 @@ static char *flags2mode(char *buf, uint16_t flags) { *buf++ = 0; } -static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; } -static bool_t NativeExists(const char *fname) { return access(fname, 0) ? FALSE : TRUE; } +static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; } +static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } +static int NativeRead(GFILE *f, void *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, const void *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static bool_t NativeSetpos(GFILE *f, long int pos) { return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; } +static bool_t NativeEof(GFILE *f) { return feof((FILE *)f->obj) ? TRUE : FALSE; } +static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE; } +static bool_t NativeExists(const char *fname) { + // We define access this way so we don't have to include which may + // (and does under windows) contain conflicting definitions for types such as uint16_t. + extern int access(const char *pathname, int mode); + return access(fname, 0) ? FALSE : TRUE; +} static long int NativeFilesize(const char *fname) { struct stat st; if (stat(fname, &st)) return -1; return st.st_size; } -static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE }; static bool_t NativeOpen(GFILE *f, const char *fname) { FILE *fd; char mode[5]; + flags2mode(mode, f->flags); if (!(fd = fopen(fname, mode))) return FALSE; f->obj = (void *)fd; return TRUE; } -static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } -static int NativeRead(GFILE *f, void *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } -static int NativeWrite(GFILE *f, const void *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } -static bool_t NativeSetpos(GFILE *f, long int pos) { - return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; -} static long int NativeGetsize(GFILE *f) { struct stat st; if (fstat(fileno((FILE *)f->obj), &st)) return -1; return st.st_size; } -static bool_t NativeEof(GFILE *f) { return feof((FILE *)f->obj) ? TRUE : FALSE; } diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 8d0e32c1..49c1b173 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -15,11 +15,19 @@ #include +// What directory file formats do we understand +#define ROMFS_DIR_VER_MAX 0x0000 + +// Compression Formats +#define ROMFS_CMP_UNCOMPRESSED 0 + typedef struct ROMFS_DIRENTRY { - const struct ROMFS_DIRENTRY * next; - const char * name; - long int size; - const char * file; + uint16_t ver; // Directory Entry Version + uint16_t cmp; // Compression format + const struct ROMFS_DIRENTRY * next; // The next entry + const char * name; // The file name + long int size; // The file size + const char * file; // The file data } ROMFS_DIRENTRY; #define ROMFS_DIRENTRY_HEAD 0 @@ -48,11 +56,11 @@ static const GFILEVMT FsROMVMT = { #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsROMVMT -static ROMFS_DIRENTRY *ROMFindFile(const char *fname) { +static const ROMFS_DIRENTRY *ROMFindFile(const char *fname) { const ROMFS_DIRENTRY *p; for(p = FsROMHead; p; p = p->next) { - if (!strcmp(p->name, fname)) + if (p->ver <= ROMFS_DIR_VER_MAX && p->cmp == ROMFS_CMP_UNCOMPRESSED && !strcmp(p->name, fname)) break; } return p; diff --git a/tools/file2c/binaries/windows/file2c.exe b/tools/file2c/binaries/windows/file2c.exe index dc530bf904193e21b279af39407c0893d60dbd04..28e9a32915aa45034c1a5ead9878287fd0fc30db 100644 GIT binary patch delta 301 zcmeBM!`QcmaY6@k%d9UGyM39;L?_<*#%QtmBBLb}W6ox7mhBvj1)C4^7%?h!q&hIX zSoH7z|Fj7UBU&98S`U=4AMV}800cWM(i|9cEhdZe890ELt>5@tTY=);vNj;z?b7OQ zUI!p+w+o1SlD}mSP;xg&Ww$d&^AAS;)-Xl}hUUXOjlV4>xAQqjegN8a+(ktKWcZ5{ zfB*jnD+b9v;L~Nan9Rp71tc~3w=(Y8e4k&Ii&19tU&&Q00&+kjOL#j!ys-K9|Nn6| zxyjq*<}=Do4wv_3G?=_pUWL(U@+o-(Mx)KY<=^u&&e;4~{|+N#!Q>N$+KiEtzZljq i3T!SkD&k}{&`~hZnQUMqGWnae$Yvg!56qh!_{0E4fNZw_ delta 294 zcmeBM!`QcmaY6^PP{PNF-M&m7Y7=jLV>H=(kjktp`fj5BF|k0D>JRX$}m!CX>ba3>-kr)^Gf+tw8Z^Sql*Fc4>7t zuMLp3+X2Kq$=|XED7hP?vfG)X`3EC^YZxN~L-S#t#@{BB+xZ+M-vI48?xG?AGW^Af zzyJS(6@z3S@aZy|Oy=X40+O2iTN!t3zRxeq#VE1)ujDEg0V$x7CA^&P%iLufnJ|`INi?qu%D<^6&W>r)++$e}|DVXYvU{ZN|{aUkqy) bc{Uds6>&~}X|2AQ&*l^JL<5#h4t!z&OXO-+ diff --git a/tools/file2c/src/file2c.c b/tools/file2c/src/file2c.c index 1c279ff2..f1415fe7 100644 --- a/tools/file2c/src/file2c.c +++ b/tools/file2c/src/file2c.c @@ -195,7 +195,7 @@ size_t i; /* Add the directory entry if required */ if (opt_romdir) { fprintf(f_output, "\n#ifdef ROMFS_DIRENTRY_HEAD\n"); - fprintf(f_output, "\t%s%sROMFS_DIRENTRY %s_dir = { ROMFS_DIRENTRY_HEAD, \"%s\", %u, %s };\n", opt_static, opt_const, opt_arrayname, opt_dirname, totallen, opt_arrayname); + fprintf(f_output, "\t%s%sROMFS_DIRENTRY %s_dir = { 0, 0, ROMFS_DIRENTRY_HEAD, \"%s\", %u, %s };\n", opt_static, opt_const, opt_arrayname, opt_dirname, totallen, opt_arrayname); fprintf(f_output, "\t#undef ROMFS_DIRENTRY_HEAD\n\t#define ROMFS_DIRENTRY_HEAD &%s_dir\n#endif\n", opt_arrayname); } From 4d3a08f5cfd244f82d1283cab702450e1dad14cd Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 18:44:32 +1000 Subject: [PATCH 19/23] Update image demo's to use GFILE ROMFS. --- demos/modules/gdisp/images/gfxconf.h | 3 +- demos/modules/gdisp/images/main.c | 20 ++++--------- demos/modules/gdisp/images/romfs_files.h | 7 +++++ .../images/{test-pal8.h => romfs_testpal8.h} | 28 +++++++++++++++++-- demos/modules/gdisp/images_animated/gfxconf.h | 2 +- demos/modules/gdisp/images_animated/main.c | 23 ++++++--------- .../gdisp/images_animated/romfs_files.h | 7 +++++ .../{testanim.h => romfs_testanim.h} | 26 +++++++++++++++-- demos/modules/gwin/widgets/gfxconf.h | 3 +- demos/modules/gwin/widgets/main.c | 15 ++++++---- demos/modules/gwin/widgets/romfs_files.h | 8 ++++++ .../{image_chibios.h => romfs_img_chibios.h} | 8 +++++- .../{image_yesno.h => romfs_img_yesno.h} | 12 ++++++-- 13 files changed, 116 insertions(+), 46 deletions(-) create mode 100644 demos/modules/gdisp/images/romfs_files.h rename demos/modules/gdisp/images/{test-pal8.h => romfs_testpal8.h} (98%) create mode 100644 demos/modules/gdisp/images_animated/romfs_files.h rename demos/modules/gdisp/images_animated/{testanim.h => romfs_testanim.h} (98%) create mode 100644 demos/modules/gwin/widgets/romfs_files.h rename demos/modules/gwin/widgets/{image_chibios.h => romfs_img_chibios.h} (99%) rename demos/modules/gwin/widgets/{image_yesno.h => romfs_img_yesno.h} (77%) diff --git a/demos/modules/gdisp/images/gfxconf.h b/demos/modules/gdisp/images/gfxconf.h index 09dbe30c..4ef9ab9e 100644 --- a/demos/modules/gdisp/images/gfxconf.h +++ b/demos/modules/gdisp/images/gfxconf.h @@ -52,7 +52,8 @@ #define GDISP_NEED_IMAGE_PNG FALSE #define GFX_USE_GFILE TRUE -#define GFILE_NEED_MEMFS TRUE +#define GFILE_NEED_ROMFS TRUE +//#define GFILE_NEED_NATIVEFS TRUE #endif /* _GFXCONF_H */ diff --git a/demos/modules/gdisp/images/main.c b/demos/modules/gdisp/images/main.c index 021bf9f5..6a2e4418 100644 --- a/demos/modules/gdisp/images/main.c +++ b/demos/modules/gdisp/images/main.c @@ -29,15 +29,12 @@ #include "gfx.h" -#ifdef WIN32 - #define USE_MEMORY_FILE TRUE // Can be true or false for Win32 -#else - #define USE_MEMORY_FILE TRUE // Non-Win32 - use the compiled in image -#endif - -#if USE_MEMORY_FILE - #include "test-pal8.h" -#endif +/** + * The image file must be stored on a GFILE file-system. + * Use either GFILE_NEED_NATIVEFS or GFILE_NEED_ROMFS (or both). + * + * The ROMFS uses the file "romfs_files.h" to describe the set of files in the ROMFS. + */ static gdispImage myImage; @@ -52,12 +49,7 @@ int main(void) { sheight = gdispGetHeight(); // Set up IO for our image -#if USE_MEMORY_FILE - gdispImageOpenMemory(&myImage, test_pal8); -#else gdispImageOpenFile(&myImage, "test-pal8.bmp"); -#endif - gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0); gdispImageClose(&myImage); diff --git a/demos/modules/gdisp/images/romfs_files.h b/demos/modules/gdisp/images/romfs_files.h new file mode 100644 index 00000000..a31dc7bf --- /dev/null +++ b/demos/modules/gdisp/images/romfs_files.h @@ -0,0 +1,7 @@ +/** + * This file contains the list of files for the ROMFS. + * + * The files have been converted using... + * file2c -dbcs infile outfile + */ +#include "romfs_testpal8.h" diff --git a/demos/modules/gdisp/images/test-pal8.h b/demos/modules/gdisp/images/romfs_testpal8.h similarity index 98% rename from demos/modules/gdisp/images/test-pal8.h rename to demos/modules/gdisp/images/romfs_testpal8.h index 9d1d7e0f..a7844b0d 100644 --- a/demos/modules/gdisp/images/test-pal8.h +++ b/demos/modules/gdisp/images/romfs_testpal8.h @@ -1,10 +1,10 @@ /** * This file was generated from "test-pal8.bmp" using... * - * file2c -cs test-pal8.bmp test-pal8.h + * file2c -bbcs test-pal8.bmp romfs_testpal8.h * */ -static const unsigned char test_pal8[] = { +static const char test_pal8[] = { 0x42, 0x4D, 0x26, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x04, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0xFC, 0x00, @@ -69,6 +69,8 @@ static const unsigned char test_pal8[] = { 0x66, 0x00, 0xFF, 0x80, 0x99, 0x00, 0xFF, 0x80, 0xCC, 0x00, 0xFF, 0x80, 0xFF, 0x00, 0xFF, 0xAA, 0x00, 0x00, 0xFF, 0xAA, 0x33, 0x00, 0xFF, 0xAA, 0x66, 0x00, 0xFF, 0xAA, 0x99, 0x00, 0xFF, 0xAA, 0xCC, 0x00, 0xFF, 0xAA, 0xFF, 0x00, 0xFF, 0xD5, 0x00, 0x00, 0xFF, 0xD5, 0x33, 0x00, 0xFF, 0xD5, +}; +static const char test_pal8_p2[] = { 0x66, 0x00, 0xFF, 0xD5, 0x99, 0x00, 0xFF, 0xD5, 0xCC, 0x00, 0xFF, 0xD5, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x66, 0x00, 0xFF, 0xFF, 0x99, 0x00, 0xFF, 0xFF, 0xCC, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x30, 0x30, 0x30, 0x30, 0x36, @@ -133,6 +135,8 @@ static const unsigned char test_pal8[] = { 0x5C, 0x2B, 0x5C, 0x56, 0x5C, 0x56, 0x87, 0x56, 0x87, 0x81, 0xB2, 0x81, 0xB2, 0x81, 0xB2, 0xAC, 0xB2, 0xAC, 0xDD, 0xAC, 0xDD, 0xD7, 0x2A, 0x00, 0x30, 0x00, 0x31, 0x06, 0x31, 0x07, 0x38, 0x07, 0x38, 0x0D, 0x3E, 0x0E, 0x3E, 0x0E, 0x45, 0x14, 0x45, 0x15, 0x46, 0x1B, 0x46, 0x1B, 0x4C, 0x22, +}; +static const char test_pal8_p3[] = { 0x4C, 0x22, 0x53, 0x22, 0x53, 0x29, 0x93, 0x62, 0x68, 0x62, 0x92, 0x62, 0x68, 0x62, 0x93, 0x62, 0x68, 0x62, 0x92, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x92, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x92, 0x62, 0x92, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x31, 0x30, 0x31, 0x30, 0x37, @@ -197,6 +201,8 @@ static const unsigned char test_pal8[] = { 0x62, 0x31, 0x62, 0x5C, 0x62, 0x5C, 0x8D, 0x5C, 0x8D, 0x87, 0xB8, 0x87, 0xB8, 0x87, 0xB8, 0xB2, 0xB8, 0xB2, 0xE3, 0xB2, 0xE3, 0xDD, 0x54, 0x2A, 0x30, 0x2A, 0x5B, 0x30, 0x31, 0x31, 0x62, 0x31, 0x38, 0x37, 0x68, 0x38, 0x3E, 0x38, 0x6F, 0x3E, 0x45, 0x3F, 0x70, 0x45, 0x46, 0x45, 0x76, 0x4C, +}; +static const char test_pal8_p4[] = { 0x4C, 0x4C, 0x7D, 0x4C, 0x53, 0x53, 0x93, 0x62, 0x68, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x00, 0x01, 0x01, 0x01, 0x07, 0x01, 0x31, 0x31, 0x31, 0x31, 0x37, @@ -261,6 +267,8 @@ static const unsigned char test_pal8[] = { 0x00, 0x00, 0xFB, 0xFB, 0xFB, 0x00, 0x00, 0x62, 0x8D, 0x8D, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0xB8, 0xB8, 0xE9, 0xB8, 0xE3, 0xE3, 0x54, 0x54, 0x5A, 0x2A, 0x5B, 0x30, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x68, 0x38, 0x68, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x45, 0x70, 0x45, 0x76, 0x76, +}; +static const char test_pal8_p5[] = { 0x76, 0x4C, 0x7D, 0x4C, 0x7D, 0x53, 0x93, 0x68, 0x93, 0x62, 0x93, 0x62, 0x93, 0x62, 0x93, 0x68, 0x93, 0x62, 0x93, 0x62, 0x93, 0x62, 0x93, 0x68, 0x93, 0x62, 0x93, 0x62, 0x93, 0x62, 0x93, 0x92, 0x93, 0x62, 0x93, 0x8C, 0x93, 0x00, 0x02, 0x02, 0x02, 0x08, 0x02, 0x32, 0x32, 0x32, 0x32, 0x38, @@ -325,6 +333,8 @@ static const unsigned char test_pal8[] = { 0xFB, 0xFB, 0x00, 0x00, 0x68, 0x62, 0x93, 0x68, 0x93, 0x8D, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0xBE, 0xB8, 0xE9, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x54, 0x85, 0x5A, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x92, 0x62, 0x92, 0x00, 0x00, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, +}; +static const char test_pal8_p6[] = { 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x00, 0x00, 0x00, 0x93, 0x62, 0x93, 0x68, 0x93, 0x68, 0x93, 0x68, 0x93, 0x62, 0x93, 0x92, 0x93, 0x68, 0x93, 0x92, 0x93, 0x62, 0x93, 0x92, 0x93, 0x92, 0x93, 0x92, 0x93, 0x00, 0x02, 0x03, 0x02, 0x09, 0x02, 0x33, 0x32, 0x33, 0x32, 0x39, @@ -389,6 +399,8 @@ static const unsigned char test_pal8[] = { 0x00, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x68, 0x99, 0x93, 0x00, 0x00, 0xFB, 0xFB, 0xFB, 0x00, 0x00, 0xBE, 0xEF, 0xBE, 0xEF, 0xE9, 0xA8, 0x7E, 0x84, 0x7E, 0xAF, 0x00, 0x00, 0xFB, 0xFB, 0xFB, 0x00, 0x00, 0xBC, 0x8C, 0x92, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static const char test_pal8_p7[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x68, 0x99, 0x92, 0x93, 0x68, 0x99, 0x92, 0x93, 0x68, 0x99, 0x92, 0x93, 0x92, 0x99, 0x92, 0x93, 0x92, 0xC3, 0x92, 0x93, 0x92, 0xC3, 0x92, 0x93, 0x00, 0x03, 0x03, 0x03, 0x09, 0x03, 0x33, 0x33, 0x33, 0x33, 0x39, @@ -453,6 +465,8 @@ static const unsigned char test_pal8[] = { 0x74, 0x43, 0x74, 0x6E, 0x74, 0x6E, 0x9F, 0x6E, 0x9F, 0x99, 0xCA, 0x99, 0xCA, 0x99, 0xCA, 0xC4, 0xCA, 0xC4, 0xF5, 0xC4, 0xF5, 0xEF, 0xA8, 0x7E, 0xAE, 0x7E, 0xAF, 0x84, 0xAF, 0x85, 0xB6, 0x85, 0xB6, 0x8B, 0xBC, 0x8C, 0xBC, 0x8C, 0xC3, 0x92, 0xC3, 0x93, 0xC4, 0x99, 0xC4, 0x99, 0xCA, 0xA0, +}; +static const char test_pal8_p8[] = { 0xCA, 0xA0, 0xD1, 0xA0, 0xD1, 0xA7, 0x99, 0x93, 0x99, 0x68, 0x99, 0x92, 0x99, 0x68, 0x99, 0x93, 0x99, 0x92, 0x99, 0x92, 0x99, 0x92, 0xC3, 0x93, 0x99, 0x92, 0xC3, 0x92, 0x99, 0x92, 0xC3, 0x93, 0xC3, 0x92, 0xC3, 0x92, 0xC3, 0x00, 0x04, 0x04, 0x04, 0x0A, 0x04, 0x34, 0x34, 0x34, 0x34, 0x3A, @@ -517,6 +531,8 @@ static const unsigned char test_pal8[] = { 0x7A, 0x49, 0x7A, 0x74, 0x74, 0x74, 0xA5, 0x74, 0xA5, 0x9F, 0xD0, 0x9F, 0xCA, 0x9F, 0xD0, 0xCA, 0xD0, 0xCA, 0xFB, 0xCA, 0xF5, 0xF5, 0xD2, 0xA8, 0xD8, 0xA8, 0xD9, 0xAE, 0xD9, 0xAF, 0xE0, 0xAF, 0xE0, 0xB5, 0xE6, 0xB6, 0xE6, 0xB6, 0xED, 0xBC, 0xED, 0xBD, 0xEE, 0xC3, 0xEE, 0xC3, 0xF4, 0xCA, +}; +static const char test_pal8_p9[] = { 0xF4, 0xCA, 0xFB, 0xCA, 0xFB, 0xD1, 0x99, 0x93, 0x99, 0x93, 0x99, 0x93, 0x99, 0x92, 0xC3, 0x93, 0x99, 0x93, 0xC3, 0x93, 0x99, 0x92, 0xC3, 0x93, 0xC3, 0x93, 0xC3, 0x93, 0xC3, 0x92, 0xC3, 0x93, 0xC3, 0x93, 0xC3, 0x93, 0xC3, 0x00, 0x04, 0x04, 0x04, 0x0B, 0x04, 0x35, 0x34, 0x35, 0x34, 0x3A, @@ -581,7 +597,15 @@ static const unsigned char test_pal8[] = { 0x7A, 0x4F, 0x7A, 0x7A, 0x7A, 0x7A, 0xA5, 0x7A, 0xA5, 0xA5, 0xD0, 0xA5, 0xD0, 0xA5, 0xD0, 0xD0, 0xD0, 0xD0, 0xFB, 0xD0, 0xFB, 0xFB, 0xD2, 0xD2, 0xD8, 0xD2, 0xD9, 0xD8, 0xD9, 0xD9, 0xE0, 0xD9, 0xE0, 0xDF, 0xE6, 0xE0, 0xE6, 0xE0, 0xED, 0xE6, 0xED, 0xE7, 0xEE, 0xED, 0xEE, 0xED, 0xF4, 0xF4, +}; +static const char test_pal8_p10[] = { 0xF4, 0xF4, 0xFB, 0xF4, 0xFB, 0xFB, 0xC4, 0x93, 0x99, 0x93, 0xC4, 0x93, 0x99, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x00, }; + +#ifdef ROMFS_DIRENTRY_HEAD + static const ROMFS_DIRENTRY test_pal8_dir = { 0, 0, ROMFS_DIRENTRY_HEAD, "test-pal8.bmp", 9254, test_pal8 }; + #undef ROMFS_DIRENTRY_HEAD + #define ROMFS_DIRENTRY_HEAD &test_pal8_dir +#endif diff --git a/demos/modules/gdisp/images_animated/gfxconf.h b/demos/modules/gdisp/images_animated/gfxconf.h index b2dcaf92..fddda437 100644 --- a/demos/modules/gdisp/images_animated/gfxconf.h +++ b/demos/modules/gdisp/images_animated/gfxconf.h @@ -52,7 +52,7 @@ #define GDISP_NEED_IMAGE_PNG FALSE #define GFX_USE_GFILE TRUE -#define GFILE_NEED_MEMFS TRUE +#define GFILE_NEED_ROMFS TRUE #endif /* _GFXCONF_H */ diff --git a/demos/modules/gdisp/images_animated/main.c b/demos/modules/gdisp/images_animated/main.c index bf49f692..039cf584 100644 --- a/demos/modules/gdisp/images_animated/main.c +++ b/demos/modules/gdisp/images_animated/main.c @@ -29,23 +29,20 @@ #include "gfx.h" +/** + * The image file must be stored on a GFILE file-system. + * Use either GFILE_NEED_NATIVEFS or GFILE_NEED_ROMFS (or both). + * + * The ROMFS uses the file "romfs_files.h" to describe the set of files in the ROMFS. + */ + #define USE_IMAGE_CACHE FALSE // Only if you want to get performance at the expense of RAM #define MY_BG_COLOR RGB2COLOR(220, 220, 255) // Pale blue so we can see the transparent parts -#ifdef WIN32 - #define USE_MEMORY_FILE TRUE // Can be true or false for Win32 -#else - #define USE_MEMORY_FILE TRUE // Non-Win32 - use the compiled in image -#endif +static gdispImage myImage; #define SHOW_ERROR(color) gdispFillArea(errx, erry, errcx, errcy, color) -#if USE_MEMORY_FILE - #include "testanim.h" -#endif - -static gdispImage myImage; - /** * This demo display the animated gif (either directly from a file or from a * file encoded in flash. @@ -75,11 +72,7 @@ int main(void) { errcy = sheight; // Set up IO for our image -#if USE_MEMORY_FILE - if (!(gdispImageOpenMemory(&myImage, testanim) & GDISP_IMAGE_ERR_UNRECOVERABLE)) { -#else if (!(gdispImageOpenFile(&myImage, "testanim.gif") & GDISP_IMAGE_ERR_UNRECOVERABLE)) { -#endif gdispImageSetBgColor(&myImage, MY_BG_COLOR); // Adjust the error indicator area if necessary diff --git a/demos/modules/gdisp/images_animated/romfs_files.h b/demos/modules/gdisp/images_animated/romfs_files.h new file mode 100644 index 00000000..9cd40491 --- /dev/null +++ b/demos/modules/gdisp/images_animated/romfs_files.h @@ -0,0 +1,7 @@ +/** + * This file contains the list of files for the ROMFS. + * + * The files have been converted using... + * file2c -dbcs infile outfile + */ +#include "romfs_testanim.h" diff --git a/demos/modules/gdisp/images_animated/testanim.h b/demos/modules/gdisp/images_animated/romfs_testanim.h similarity index 98% rename from demos/modules/gdisp/images_animated/testanim.h rename to demos/modules/gdisp/images_animated/romfs_testanim.h index ce2ba8c7..3b35b120 100644 --- a/demos/modules/gdisp/images_animated/testanim.h +++ b/demos/modules/gdisp/images_animated/romfs_testanim.h @@ -1,10 +1,10 @@ /** * This file was generated from "testanim.gif" using... * - * file2c -cs testanim.gif testanim.h + * file2c -bbcs testanim.gif romfs_testanim.h * */ -static const unsigned char testanim[] = { +static const char testanim[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x99, 0x00, 0x73, 0x00, 0xE6, 0x46, 0x00, 0x04, 0x07, 0x00, 0x10, 0x0F, 0x04, 0x1D, 0x1E, 0x29, 0x20, 0x23, 0x08, 0x2E, 0x2C, 0x18, 0x31, 0x32, 0x01, 0x2E, 0x32, 0x2A, 0x35, 0x37, 0x3B, 0x20, 0x28, 0x42, 0x2B, 0x37, 0x53, 0x3E, 0x41, 0x03, 0x3C, 0x44, @@ -69,6 +69,8 @@ static const unsigned char testanim[] = { 0x84, 0x61, 0x8E, 0x71, 0x05, 0x63, 0xE6, 0x5C, 0x85, 0x80, 0x80, 0xD7, 0x60, 0xB3, 0x10, 0x70, 0x40, 0x00, 0xB5, 0x61, 0xA0, 0x40, 0x04, 0x18, 0x30, 0x70, 0x80, 0x01, 0x09, 0x88, 0x35, 0xDA, 0x82, 0xD1, 0x58, 0xA0, 0xC8, 0x31, 0x79, 0xED, 0x48, 0x61, 0x95, 0x71, 0x5D, 0x68, 0xC0, 0x47, +}; +static const char testanim_p2[] = { 0x14, 0x52, 0x18, 0xD7, 0x8C, 0x0B, 0x78, 0x80, 0xC1, 0x00, 0x95, 0x65, 0xB8, 0xA5, 0x3E, 0xDF, 0x08, 0xF3, 0x4F, 0x02, 0xC9, 0x4D, 0x76, 0x90, 0x9D, 0x91, 0xCD, 0xE5, 0x81, 0x07, 0x2D, 0xE4, 0xE4, 0xD6, 0x9B, 0x23, 0x79, 0x08, 0x82, 0x7A, 0x4A, 0xC5, 0x45, 0x80, 0x04, 0x03, 0x10, 0x40, @@ -133,6 +135,8 @@ static const unsigned char testanim[] = { 0x8D, 0x34, 0xE6, 0x9E, 0x0E, 0x08, 0x87, 0xEB, 0x62, 0xC5, 0x1D, 0x67, 0x16, 0x00, 0x9A, 0xF3, 0xA8, 0x00, 0xE9, 0x6E, 0x68, 0xC0, 0xF1, 0x21, 0x85, 0xA1, 0xCF, 0xA3, 0x9E, 0xE9, 0x70, 0xC3, 0xD0, 0x56, 0xF9, 0xB0, 0x9C, 0xD5, 0x1A, 0x08, 0x86, 0x16, 0xC0, 0x81, 0x0D, 0x38, 0xD1, 0x08, +}; +static const char testanim_p3[] = { 0x21, 0xC5, 0x2A, 0x86, 0x5C, 0xF7, 0x35, 0x48, 0x74, 0x55, 0x07, 0xBE, 0xD4, 0x4A, 0x14, 0x27, 0x47, 0x49, 0x84, 0x0D, 0xB3, 0x61, 0xC0, 0x88, 0xD6, 0x5C, 0x4E, 0x51, 0x9F, 0x48, 0xCE, 0x48, 0x79, 0x85, 0xC0, 0x88, 0x01, 0x62, 0x95, 0xC3, 0x34, 0x0E, 0xC0, 0xA7, 0x35, 0x2C, 0xDD, 0x51, @@ -197,6 +201,8 @@ static const unsigned char testanim[] = { 0x83, 0xB2, 0x64, 0xAA, 0xF2, 0x4D, 0x4C, 0x67, 0x38, 0x33, 0x61, 0x1F, 0x1D, 0x71, 0x67, 0xAE, 0x63, 0x4A, 0x86, 0x13, 0x68, 0x7F, 0x01, 0x65, 0xAC, 0x17, 0x5F, 0x40, 0x62, 0x68, 0xBB, 0x66, 0x77, 0x53, 0xA6, 0x77, 0xA8, 0x20, 0x2B, 0xA5, 0xC3, 0x34, 0xF2, 0x86, 0x0A, 0xEC, 0xD2, 0x24, +}; +static const char testanim_p4[] = { 0xE0, 0x67, 0x2E, 0x2B, 0x24, 0x0E, 0x6B, 0x93, 0x27, 0x4B, 0x43, 0x0F, 0x5D, 0x26, 0x7C, 0x59, 0xB7, 0x21, 0x71, 0x41, 0x2F, 0x01, 0x24, 0x7B, 0xBD, 0x55, 0x3E, 0x7E, 0x38, 0x1B, 0x40, 0xE1, 0x3A, 0x08, 0x70, 0x85, 0x82, 0xE0, 0x73, 0x7A, 0x32, 0x3A, 0x06, 0xC8, 0x6E, 0xD3, 0x73, 0x6B, @@ -261,6 +267,8 @@ static const unsigned char testanim[] = { 0x32, 0xA0, 0x03, 0x1D, 0x40, 0x03, 0x0B, 0x00, 0x03, 0x71, 0xFA, 0x02, 0x7A, 0x9A, 0x97, 0x40, 0x40, 0x02, 0x78, 0x69, 0x9B, 0x31, 0x26, 0x03, 0xE2, 0x33, 0x51, 0xF4, 0x30, 0xA5, 0xB3, 0x81, 0x35, 0x77, 0x42, 0x5D, 0x58, 0x5A, 0x19, 0xE5, 0xEA, 0x66, 0x27, 0x2A, 0x0B, 0x33, 0xE6, 0x6B, +}; +static const char testanim_p5[] = { 0x0A, 0x89, 0x65, 0xB3, 0x35, 0xA0, 0xA5, 0xE9, 0x93, 0xBC, 0x78, 0x9D, 0xEA, 0xFA, 0x1D, 0xAE, 0xD3, 0x88, 0x05, 0x1A, 0x00, 0x9E, 0xDA, 0x02, 0x33, 0xE2, 0x01, 0x16, 0xFA, 0x02, 0x42, 0xF0, 0x02, 0x3E, 0x90, 0x97, 0x3A, 0x80, 0x97, 0xA4, 0xEA, 0x03, 0x24, 0x45, 0x3E, 0xAC, 0x64, 0xAB, @@ -325,6 +333,8 @@ static const unsigned char testanim[] = { 0xBD, 0xFC, 0x56, 0x2E, 0xE0, 0x28, 0x7B, 0xE9, 0xB4, 0xF5, 0x1A, 0x63, 0xD1, 0x1A, 0x63, 0x5D, 0x3C, 0xC3, 0x1C, 0xBD, 0xA4, 0x61, 0x79, 0x67, 0xBB, 0xA2, 0x24, 0x71, 0xE5, 0x3B, 0x3B, 0x02, 0x29, 0x2B, 0x0A, 0xD2, 0xFA, 0x8C, 0x65, 0x6F, 0x8D, 0xCD, 0xEA, 0x06, 0x6F, 0x71, 0x69, 0x4D, +}; +static const char testanim_p6[] = { 0xDD, 0x5C, 0xB4, 0x61, 0x8A, 0x55, 0x78, 0xF8, 0xD2, 0xDB, 0xD6, 0xC4, 0x2F, 0x90, 0x9E, 0xCC, 0x5A, 0xAF, 0x35, 0xD0, 0xA6, 0x82, 0xBD, 0x8A, 0xB9, 0x82, 0xA5, 0xF3, 0x59, 0x21, 0xE9, 0x04, 0x26, 0xA8, 0xA5, 0x23, 0x4A, 0xD1, 0xDA, 0x56, 0x13, 0x01, 0x74, 0x86, 0x0A, 0xD0, 0x10, 0xD9, @@ -389,6 +399,8 @@ static const unsigned char testanim[] = { 0x11, 0x88, 0x8B, 0x2A, 0x2A, 0xE0, 0xE7, 0x8D, 0x05, 0xE7, 0x90, 0xA3, 0x98, 0xDF, 0x96, 0x90, 0xDD, 0xA6, 0x82, 0x9D, 0xD4, 0xD0, 0xD1, 0x98, 0x02, 0x06, 0x0C, 0xB0, 0x72, 0xB5, 0x20, 0x96, 0x87, 0x16, 0x32, 0x6C, 0xE9, 0xD2, 0x25, 0xE3, 0x85, 0x8E, 0x5E, 0x1D, 0x30, 0x6C, 0x08, 0xC6, +}; +static const char testanim_p7[] = { 0xEA, 0x40, 0x83, 0x03, 0x19, 0x1A, 0x28, 0x1B, 0xD0, 0x60, 0x9A, 0xB2, 0x4D, 0x04, 0x04, 0x39, 0xF3, 0x64, 0xA9, 0x94, 0xB7, 0x7D, 0xFB, 0xB6, 0xA9, 0x9C, 0x00, 0xCF, 0x54, 0x3E, 0x70, 0x88, 0x06, 0x88, 0x73, 0x34, 0x80, 0x82, 0x0A, 0x46, 0x88, 0x2A, 0x35, 0x6A, 0xC4, 0xA8, 0x52, 0x24, @@ -453,6 +465,8 @@ static const unsigned char testanim[] = { 0x01, 0x1F, 0x50, 0x50, 0x18, 0x09, 0x67, 0x9D, 0x03, 0x6B, 0xCF, 0x18, 0x8A, 0x4F, 0x4C, 0x51, 0x8C, 0x59, 0x80, 0xC0, 0x00, 0x64, 0xAA, 0x8F, 0x04, 0x2C, 0x00, 0x9F, 0x5C, 0x60, 0x60, 0x65, 0x35, 0x78, 0x48, 0x69, 0x3A, 0xD0, 0x82, 0x91, 0x6D, 0x20, 0x22, 0x4F, 0xEC, 0x00, 0xA8, 0xD4, +}; +static const char testanim_p8[] = { 0xA2, 0x23, 0x5A, 0xE1, 0x26, 0x47, 0xC9, 0x23, 0x89, 0x63, 0x46, 0x32, 0x80, 0xB2, 0x64, 0x69, 0x50, 0xF9, 0xE8, 0x4E, 0x27, 0xCA, 0xE1, 0x38, 0x14, 0xDE, 0x30, 0x02, 0xD2, 0xB2, 0x10, 0x00, 0x70, 0xF7, 0xB3, 0xEA, 0xF0, 0xA5, 0x12, 0x56, 0xB2, 0xC4, 0x8E, 0xB2, 0x36, 0x94, 0x4C, 0xD1, @@ -517,6 +531,8 @@ static const unsigned char testanim[] = { 0x12, 0x42, 0x3C, 0x6C, 0xF3, 0x51, 0x92, 0x20, 0x33, 0x82, 0x42, 0x68, 0xB4, 0xB0, 0xD5, 0x68, 0x40, 0xA2, 0x1A, 0x21, 0x87, 0x78, 0x80, 0x11, 0xD4, 0x18, 0xCC, 0x5C, 0x46, 0x80, 0xB4, 0xD0, 0x90, 0x40, 0xD2, 0x82, 0x1A, 0xDB, 0x2E, 0xCC, 0x33, 0xC2, 0x52, 0xC6, 0x0F, 0x5C, 0x32, 0x6A, +}; +static const char testanim_p9[] = { 0x0C, 0x01, 0xE2, 0xA3, 0x05, 0x86, 0x0E, 0x92, 0x0E, 0x90, 0x78, 0x61, 0x61, 0xC1, 0x0B, 0x1B, 0xFE, 0x2F, 0x3C, 0xD1, 0x20, 0x08, 0xE4, 0xE3, 0x8F, 0x17, 0x35, 0x6A, 0xB4, 0x70, 0x61, 0xD5, 0xC8, 0x82, 0xBF, 0x5C, 0x49, 0xB8, 0xF0, 0xF1, 0x71, 0x88, 0x8C, 0x8F, 0x3E, 0x78, 0x1A, 0x21, @@ -565,3 +581,9 @@ static const unsigned char testanim[] = { 0xD7, 0x82, 0xFC, 0x87, 0xAE, 0x20, 0x04, 0x10, 0xA0, 0x48, 0xA0, 0x86, 0xCC, 0x05, 0x0C, 0x30, 0x87, 0x2C, 0x38, 0x88, 0xED, 0x86, 0x04, 0x02, 0x00, 0x3B, }; + +#ifdef ROMFS_DIRENTRY_HEAD + static const ROMFS_DIRENTRY testanim_dir = { 0, 0, ROMFS_DIRENTRY_HEAD, "testanim.gif", 8938, testanim }; + #undef ROMFS_DIRENTRY_HEAD + #define ROMFS_DIRENTRY_HEAD &testanim_dir +#endif diff --git a/demos/modules/gwin/widgets/gfxconf.h b/demos/modules/gwin/widgets/gfxconf.h index b536de4c..60de8d8b 100644 --- a/demos/modules/gwin/widgets/gfxconf.h +++ b/demos/modules/gwin/widgets/gfxconf.h @@ -81,7 +81,8 @@ /* Features for the GFILE subsystem. */ #define GFX_USE_GFILE TRUE -#define GFILE_NEED_MEMFS TRUE +#define GFILE_NEED_ROMFS TRUE +//#define GFILE_NEED_NATIVEFS TRUE /* Features for the GINPUT subsystem. */ #define GINPUT_NEED_MOUSE TRUE diff --git a/demos/modules/gwin/widgets/main.c b/demos/modules/gwin/widgets/main.c index 80c39dd9..7c06f3bf 100644 --- a/demos/modules/gwin/widgets/main.c +++ b/demos/modules/gwin/widgets/main.c @@ -28,16 +28,19 @@ #include "gfx.h" -// include our chibios logo in a .gif format -#include "image_chibios.h" -#include "image_yesno.h" - /** * This demo demonstrates many of the GWIN widgets. * On the "Radio" tab try playing with the color radio buttons. * On the "Checkbox" tab try playing with the "Disable All" checkbox. */ +/** + * The image files must be stored on a GFILE file-system. + * Use either GFILE_NEED_NATIVEFS or GFILE_NEED_ROMFS (or both). + * + * The ROMFS uses the file "romfs_files.h" to describe the set of files in the ROMFS. + */ + /* Our custom yellow style */ static const GWidgetStyle YellowWidgetStyle = { Yellow, // window background @@ -184,14 +187,14 @@ static void createWidgets(void) { wi.g.x = 0+2*(LIST_WIDTH+1); wi.text = "L3"; ghList3 = gwinListCreate(0, &wi, TRUE); gwinListAddItem(ghList3, "Item 0", FALSE); gwinListAddItem(ghList3, "Item 1", FALSE); gwinListAddItem(ghList3, "Item 2", FALSE); gwinListAddItem(ghList3, "Item 3", FALSE); - gdispImageOpenMemory(&imgYesNo, image_yesno); + gdispImageOpenFile(&imgYesNo, "image_yesno.gif"); gwinListItemSetImage(ghList3, 1, &imgYesNo); gwinListItemSetImage(ghList3, 3, &imgYesNo); // Image wi.g.x = ScrWidth-210; wi.g.y = TAB_HEIGHT + 10; wi.g.width = 200; wi.g.height = 200; ghImage1 = gwinImageCreate(0, &wi.g); - gwinImageOpenMemory(ghImage1, image_chibios); + gwinImageOpenFile(ghImage1, "chibios.bmp"); gwinImageCache(ghImage1); // Console - we apply some special colors before making it visible diff --git a/demos/modules/gwin/widgets/romfs_files.h b/demos/modules/gwin/widgets/romfs_files.h new file mode 100644 index 00000000..b503765d --- /dev/null +++ b/demos/modules/gwin/widgets/romfs_files.h @@ -0,0 +1,8 @@ +/** + * This file contains the list of files for the ROMFS. + * + * The files have been converted using... + * file2c -dbcs infile outfile + */ +#include "romfs_img_chibios.h" +#include "romfs_img_yesno.h" diff --git a/demos/modules/gwin/widgets/image_chibios.h b/demos/modules/gwin/widgets/romfs_img_chibios.h similarity index 99% rename from demos/modules/gwin/widgets/image_chibios.h rename to demos/modules/gwin/widgets/romfs_img_chibios.h index a052395f..14007610 100644 --- a/demos/modules/gwin/widgets/image_chibios.h +++ b/demos/modules/gwin/widgets/romfs_img_chibios.h @@ -1,4 +1,4 @@ -static const unsigned char image_chibios[] = { +static const char image_chibios[] = { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x74, 0x00, 0x74, 0x00, 0xE7, 0xFE, 0x00, 0x08, 0x07, 0x02, 0x00, 0x0A, 0x03, 0x08, 0x07, 0x0E, 0x05, 0x0D, 0x00, 0x00, 0x11, 0x02, 0x03, 0x16, 0x01, 0x09, 0x15, 0x00, 0x00, 0x19, 0x03, 0x14, 0x16, 0x06, 0x00, 0x1D, 0x02, 0x07, 0x1C, 0x01, 0x0F, 0x1A, @@ -635,3 +635,9 @@ static const unsigned char image_chibios[] = { 0xE0, 0x3F, 0x62, 0xE0, 0x07, 0x86, 0xE0, 0x08, 0x96, 0xE0, 0x09, 0xA6, 0xE0, 0x0A, 0xB6, 0xE0, 0x0B, 0xC6, 0x60, 0xF0, 0x08, 0x08, 0x00, 0x3B, }; + +#ifdef ROMFS_DIRENTRY_HEAD + static const ROMFS_DIRENTRY image_chibios_dir = { 0, 0, ROMFS_DIRENTRY_HEAD, "chibios.bmp", 634*16+8, image_chibios }; + #undef ROMFS_DIRENTRY_HEAD + #define ROMFS_DIRENTRY_HEAD &image_chibios_dir +#endif diff --git a/demos/modules/gwin/widgets/image_yesno.h b/demos/modules/gwin/widgets/romfs_img_yesno.h similarity index 77% rename from demos/modules/gwin/widgets/image_yesno.h rename to demos/modules/gwin/widgets/romfs_img_yesno.h index c3150ea7..0559330e 100644 --- a/demos/modules/gwin/widgets/image_yesno.h +++ b/demos/modules/gwin/widgets/romfs_img_yesno.h @@ -1,10 +1,10 @@ /** - * This file was generated from "yesno.gif" using... + * This file was generated from "image_yesno.gif" using... * - * file2c -bcs image_yesno.gif image_yesno.h + * file2c -bbcs image_yesno.gif romfs_img_yesno.h * */ -static const unsigned char image_yesno[] = { +static const char image_yesno[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x0B, 0x00, 0x2C, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x00, 0xC6, 0xFF, 0xC6, 0xCE, 0xFF, 0xCE, 0xFF, 0x08, 0x18, 0xFF, 0xCE, 0xDE, 0xFF, 0xDE, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -19,3 +19,9 @@ static const unsigned char image_yesno[] = { 0x05, 0x35, 0x81, 0x84, 0x86, 0x83, 0x14, 0x8B, 0x07, 0x86, 0x79, 0x8F, 0x82, 0x8F, 0x8E, 0x17, 0x8E, 0x62, 0x8B, 0x8C, 0x8A, 0x87, 0x05, 0x11, 0x00, 0x3B, }; + +#ifdef ROMFS_DIRENTRY_HEAD + static const ROMFS_DIRENTRY image_yesno_dir = { 0, 0, ROMFS_DIRENTRY_HEAD, "image_yesno.gif", 202, image_yesno }; + #undef ROMFS_DIRENTRY_HEAD + #define ROMFS_DIRENTRY_HEAD &image_yesno_dir +#endif From c5f87f9952b11f0792dd1455e3f4286123c1d388 Mon Sep 17 00:00:00 2001 From: inmarket Date: Fri, 7 Feb 2014 18:50:56 +1000 Subject: [PATCH 20/23] Update linux file2c binary. --- tools/file2c/binaries/linux/file2c | Bin 9700 -> 9700 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tools/file2c/binaries/linux/file2c b/tools/file2c/binaries/linux/file2c index 5a2a5de72deadc012ae248f603068468ec7da651..9d33e817e0802318b4535499827bd84cacc71228 100755 GIT binary patch delta 237 zcmaFj{lt4h3+oSY28JIKJM%fGh%qosna08~WilhhIAd}m?@C6W&D?wV{@uXJtF{`iBm2B delta 253 zcmaFj{lt4h3+oqg28J&aJM%dwh%qosn8v~}VKO7*bdh%X%*)P#+@U*InsqyOeoStT zK5xEx4Wls|zpc From 3ad23244f13ba4b90e954bb363dca837668c4769 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Sun, 9 Feb 2014 20:24:24 +0100 Subject: [PATCH 21/23] doc --- include/gdisp/image.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/gdisp/image.h b/include/gdisp/image.h index bcf9c497..77cd97e4 100644 --- a/include/gdisp/image.h +++ b/include/gdisp/image.h @@ -117,7 +117,7 @@ typedef struct gdispImage { extern "C" { #endif - /** + /* * Deprecated Functions. */ gdispImageError DEPRECATED("Use gdispImageOpenGFile() instead") gdispImageOpen(gdispImage *img); @@ -136,7 +136,7 @@ extern "C" { * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. * * @param[in] img The image structure - * @param[in] f The open GFILE stream. + * @param[in] filename The open GFILE stream. * * @pre The GFILE must be open for reading. * From bb1cd44824e0f70906c81842d7ff2852f354663e Mon Sep 17 00:00:00 2001 From: inmarket Date: Sat, 15 Feb 2014 22:23:32 +1000 Subject: [PATCH 22/23] Fix naming of a parameter --- include/gdisp/image.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/gdisp/image.h b/include/gdisp/image.h index 77cd97e4..607f1007 100644 --- a/include/gdisp/image.h +++ b/include/gdisp/image.h @@ -136,7 +136,7 @@ extern "C" { * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. * * @param[in] img The image structure - * @param[in] filename The open GFILE stream. + * @param[in] f The open GFILE stream. * * @pre The GFILE must be open for reading. * @@ -154,7 +154,7 @@ extern "C" { * (eg GDISP_IMAGE_ERR_UNSUPPORTED_OK) * still need to be closed when you are finished with them. */ - gdispImageError gdispImageOpenGFile(gdispImage *img, GFILE *filename); + gdispImageError gdispImageOpenGFile(gdispImage *img, GFILE *f); /** * @brief Open an image in a file and get it ready for drawing From 5edf7c956e8a00a6a49e1f3c446c80cecf0e59ef Mon Sep 17 00:00:00 2001 From: inmarket Date: Sat, 15 Feb 2014 22:28:07 +1000 Subject: [PATCH 23/23] On ARM gcc compiler it appears that non-referenced character arrays are "optimised" out (but not on x86). This conflicts with the -b parameter in the file2c tool and leads to corrupted images on ARM platforms. For now just remove the parameter when generating ROMFS files for an ARM platform. --- demos/modules/gdisp/images/romfs_testpal8.h | 20 +------------------ .../gdisp/images_animated/romfs_testanim.h | 18 +---------------- demos/modules/gwin/widgets/romfs_img_yesno.h | 2 +- 3 files changed, 3 insertions(+), 37 deletions(-) diff --git a/demos/modules/gdisp/images/romfs_testpal8.h b/demos/modules/gdisp/images/romfs_testpal8.h index a7844b0d..e6a353a2 100644 --- a/demos/modules/gdisp/images/romfs_testpal8.h +++ b/demos/modules/gdisp/images/romfs_testpal8.h @@ -1,7 +1,7 @@ /** * This file was generated from "test-pal8.bmp" using... * - * file2c -bbcs test-pal8.bmp romfs_testpal8.h + * file2c -dcs test-pal8.bmp romfs_testpal8.h * */ static const char test_pal8[] = { @@ -69,8 +69,6 @@ static const char test_pal8[] = { 0x66, 0x00, 0xFF, 0x80, 0x99, 0x00, 0xFF, 0x80, 0xCC, 0x00, 0xFF, 0x80, 0xFF, 0x00, 0xFF, 0xAA, 0x00, 0x00, 0xFF, 0xAA, 0x33, 0x00, 0xFF, 0xAA, 0x66, 0x00, 0xFF, 0xAA, 0x99, 0x00, 0xFF, 0xAA, 0xCC, 0x00, 0xFF, 0xAA, 0xFF, 0x00, 0xFF, 0xD5, 0x00, 0x00, 0xFF, 0xD5, 0x33, 0x00, 0xFF, 0xD5, -}; -static const char test_pal8_p2[] = { 0x66, 0x00, 0xFF, 0xD5, 0x99, 0x00, 0xFF, 0xD5, 0xCC, 0x00, 0xFF, 0xD5, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0xFF, 0xFF, 0x66, 0x00, 0xFF, 0xFF, 0x99, 0x00, 0xFF, 0xFF, 0xCC, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x30, 0x30, 0x30, 0x30, 0x36, @@ -135,8 +133,6 @@ static const char test_pal8_p2[] = { 0x5C, 0x2B, 0x5C, 0x56, 0x5C, 0x56, 0x87, 0x56, 0x87, 0x81, 0xB2, 0x81, 0xB2, 0x81, 0xB2, 0xAC, 0xB2, 0xAC, 0xDD, 0xAC, 0xDD, 0xD7, 0x2A, 0x00, 0x30, 0x00, 0x31, 0x06, 0x31, 0x07, 0x38, 0x07, 0x38, 0x0D, 0x3E, 0x0E, 0x3E, 0x0E, 0x45, 0x14, 0x45, 0x15, 0x46, 0x1B, 0x46, 0x1B, 0x4C, 0x22, -}; -static const char test_pal8_p3[] = { 0x4C, 0x22, 0x53, 0x22, 0x53, 0x29, 0x93, 0x62, 0x68, 0x62, 0x92, 0x62, 0x68, 0x62, 0x93, 0x62, 0x68, 0x62, 0x92, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x92, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x92, 0x62, 0x92, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x31, 0x30, 0x31, 0x30, 0x37, @@ -201,8 +197,6 @@ static const char test_pal8_p3[] = { 0x62, 0x31, 0x62, 0x5C, 0x62, 0x5C, 0x8D, 0x5C, 0x8D, 0x87, 0xB8, 0x87, 0xB8, 0x87, 0xB8, 0xB2, 0xB8, 0xB2, 0xE3, 0xB2, 0xE3, 0xDD, 0x54, 0x2A, 0x30, 0x2A, 0x5B, 0x30, 0x31, 0x31, 0x62, 0x31, 0x38, 0x37, 0x68, 0x38, 0x3E, 0x38, 0x6F, 0x3E, 0x45, 0x3F, 0x70, 0x45, 0x46, 0x45, 0x76, 0x4C, -}; -static const char test_pal8_p4[] = { 0x4C, 0x4C, 0x7D, 0x4C, 0x53, 0x53, 0x93, 0x62, 0x68, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x62, 0x93, 0x62, 0x92, 0x00, 0x01, 0x01, 0x01, 0x07, 0x01, 0x31, 0x31, 0x31, 0x31, 0x37, @@ -267,8 +261,6 @@ static const char test_pal8_p4[] = { 0x00, 0x00, 0xFB, 0xFB, 0xFB, 0x00, 0x00, 0x62, 0x8D, 0x8D, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0xB8, 0xB8, 0xE9, 0xB8, 0xE3, 0xE3, 0x54, 0x54, 0x5A, 0x2A, 0x5B, 0x30, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x68, 0x38, 0x68, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x45, 0x70, 0x45, 0x76, 0x76, -}; -static const char test_pal8_p5[] = { 0x76, 0x4C, 0x7D, 0x4C, 0x7D, 0x53, 0x93, 0x68, 0x93, 0x62, 0x93, 0x62, 0x93, 0x62, 0x93, 0x68, 0x93, 0x62, 0x93, 0x62, 0x93, 0x62, 0x93, 0x68, 0x93, 0x62, 0x93, 0x62, 0x93, 0x62, 0x93, 0x92, 0x93, 0x62, 0x93, 0x8C, 0x93, 0x00, 0x02, 0x02, 0x02, 0x08, 0x02, 0x32, 0x32, 0x32, 0x32, 0x38, @@ -333,8 +325,6 @@ static const char test_pal8_p5[] = { 0xFB, 0xFB, 0x00, 0x00, 0x68, 0x62, 0x93, 0x68, 0x93, 0x8D, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0xBE, 0xB8, 0xE9, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x54, 0x85, 0x5A, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x92, 0x62, 0x92, 0x00, 0x00, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, -}; -static const char test_pal8_p6[] = { 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x00, 0x00, 0x00, 0x93, 0x62, 0x93, 0x68, 0x93, 0x68, 0x93, 0x68, 0x93, 0x62, 0x93, 0x92, 0x93, 0x68, 0x93, 0x92, 0x93, 0x62, 0x93, 0x92, 0x93, 0x92, 0x93, 0x92, 0x93, 0x00, 0x02, 0x03, 0x02, 0x09, 0x02, 0x33, 0x32, 0x33, 0x32, 0x39, @@ -399,8 +389,6 @@ static const char test_pal8_p6[] = { 0x00, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x68, 0x99, 0x93, 0x00, 0x00, 0xFB, 0xFB, 0xFB, 0x00, 0x00, 0xBE, 0xEF, 0xBE, 0xEF, 0xE9, 0xA8, 0x7E, 0x84, 0x7E, 0xAF, 0x00, 0x00, 0xFB, 0xFB, 0xFB, 0x00, 0x00, 0xBC, 0x8C, 0x92, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -static const char test_pal8_p7[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x68, 0x99, 0x92, 0x93, 0x68, 0x99, 0x92, 0x93, 0x68, 0x99, 0x92, 0x93, 0x92, 0x99, 0x92, 0x93, 0x92, 0xC3, 0x92, 0x93, 0x92, 0xC3, 0x92, 0x93, 0x00, 0x03, 0x03, 0x03, 0x09, 0x03, 0x33, 0x33, 0x33, 0x33, 0x39, @@ -465,8 +453,6 @@ static const char test_pal8_p7[] = { 0x74, 0x43, 0x74, 0x6E, 0x74, 0x6E, 0x9F, 0x6E, 0x9F, 0x99, 0xCA, 0x99, 0xCA, 0x99, 0xCA, 0xC4, 0xCA, 0xC4, 0xF5, 0xC4, 0xF5, 0xEF, 0xA8, 0x7E, 0xAE, 0x7E, 0xAF, 0x84, 0xAF, 0x85, 0xB6, 0x85, 0xB6, 0x8B, 0xBC, 0x8C, 0xBC, 0x8C, 0xC3, 0x92, 0xC3, 0x93, 0xC4, 0x99, 0xC4, 0x99, 0xCA, 0xA0, -}; -static const char test_pal8_p8[] = { 0xCA, 0xA0, 0xD1, 0xA0, 0xD1, 0xA7, 0x99, 0x93, 0x99, 0x68, 0x99, 0x92, 0x99, 0x68, 0x99, 0x93, 0x99, 0x92, 0x99, 0x92, 0x99, 0x92, 0xC3, 0x93, 0x99, 0x92, 0xC3, 0x92, 0x99, 0x92, 0xC3, 0x93, 0xC3, 0x92, 0xC3, 0x92, 0xC3, 0x00, 0x04, 0x04, 0x04, 0x0A, 0x04, 0x34, 0x34, 0x34, 0x34, 0x3A, @@ -531,8 +517,6 @@ static const char test_pal8_p8[] = { 0x7A, 0x49, 0x7A, 0x74, 0x74, 0x74, 0xA5, 0x74, 0xA5, 0x9F, 0xD0, 0x9F, 0xCA, 0x9F, 0xD0, 0xCA, 0xD0, 0xCA, 0xFB, 0xCA, 0xF5, 0xF5, 0xD2, 0xA8, 0xD8, 0xA8, 0xD9, 0xAE, 0xD9, 0xAF, 0xE0, 0xAF, 0xE0, 0xB5, 0xE6, 0xB6, 0xE6, 0xB6, 0xED, 0xBC, 0xED, 0xBD, 0xEE, 0xC3, 0xEE, 0xC3, 0xF4, 0xCA, -}; -static const char test_pal8_p9[] = { 0xF4, 0xCA, 0xFB, 0xCA, 0xFB, 0xD1, 0x99, 0x93, 0x99, 0x93, 0x99, 0x93, 0x99, 0x92, 0xC3, 0x93, 0x99, 0x93, 0xC3, 0x93, 0x99, 0x92, 0xC3, 0x93, 0xC3, 0x93, 0xC3, 0x93, 0xC3, 0x92, 0xC3, 0x93, 0xC3, 0x93, 0xC3, 0x93, 0xC3, 0x00, 0x04, 0x04, 0x04, 0x0B, 0x04, 0x35, 0x34, 0x35, 0x34, 0x3A, @@ -597,8 +581,6 @@ static const char test_pal8_p9[] = { 0x7A, 0x4F, 0x7A, 0x7A, 0x7A, 0x7A, 0xA5, 0x7A, 0xA5, 0xA5, 0xD0, 0xA5, 0xD0, 0xA5, 0xD0, 0xD0, 0xD0, 0xD0, 0xFB, 0xD0, 0xFB, 0xFB, 0xD2, 0xD2, 0xD8, 0xD2, 0xD9, 0xD8, 0xD9, 0xD9, 0xE0, 0xD9, 0xE0, 0xDF, 0xE6, 0xE0, 0xE6, 0xE0, 0xED, 0xE6, 0xED, 0xE7, 0xEE, 0xED, 0xEE, 0xED, 0xF4, 0xF4, -}; -static const char test_pal8_p10[] = { 0xF4, 0xF4, 0xFB, 0xF4, 0xFB, 0xFB, 0xC4, 0x93, 0x99, 0x93, 0xC4, 0x93, 0x99, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x93, 0xC4, 0x93, 0xC3, 0x00, diff --git a/demos/modules/gdisp/images_animated/romfs_testanim.h b/demos/modules/gdisp/images_animated/romfs_testanim.h index 3b35b120..cbda0d79 100644 --- a/demos/modules/gdisp/images_animated/romfs_testanim.h +++ b/demos/modules/gdisp/images_animated/romfs_testanim.h @@ -1,7 +1,7 @@ /** * This file was generated from "testanim.gif" using... * - * file2c -bbcs testanim.gif romfs_testanim.h + * file2c -dcs testanim.gif romfs_testanim.h * */ static const char testanim[] = { @@ -69,8 +69,6 @@ static const char testanim[] = { 0x84, 0x61, 0x8E, 0x71, 0x05, 0x63, 0xE6, 0x5C, 0x85, 0x80, 0x80, 0xD7, 0x60, 0xB3, 0x10, 0x70, 0x40, 0x00, 0xB5, 0x61, 0xA0, 0x40, 0x04, 0x18, 0x30, 0x70, 0x80, 0x01, 0x09, 0x88, 0x35, 0xDA, 0x82, 0xD1, 0x58, 0xA0, 0xC8, 0x31, 0x79, 0xED, 0x48, 0x61, 0x95, 0x71, 0x5D, 0x68, 0xC0, 0x47, -}; -static const char testanim_p2[] = { 0x14, 0x52, 0x18, 0xD7, 0x8C, 0x0B, 0x78, 0x80, 0xC1, 0x00, 0x95, 0x65, 0xB8, 0xA5, 0x3E, 0xDF, 0x08, 0xF3, 0x4F, 0x02, 0xC9, 0x4D, 0x76, 0x90, 0x9D, 0x91, 0xCD, 0xE5, 0x81, 0x07, 0x2D, 0xE4, 0xE4, 0xD6, 0x9B, 0x23, 0x79, 0x08, 0x82, 0x7A, 0x4A, 0xC5, 0x45, 0x80, 0x04, 0x03, 0x10, 0x40, @@ -135,8 +133,6 @@ static const char testanim_p2[] = { 0x8D, 0x34, 0xE6, 0x9E, 0x0E, 0x08, 0x87, 0xEB, 0x62, 0xC5, 0x1D, 0x67, 0x16, 0x00, 0x9A, 0xF3, 0xA8, 0x00, 0xE9, 0x6E, 0x68, 0xC0, 0xF1, 0x21, 0x85, 0xA1, 0xCF, 0xA3, 0x9E, 0xE9, 0x70, 0xC3, 0xD0, 0x56, 0xF9, 0xB0, 0x9C, 0xD5, 0x1A, 0x08, 0x86, 0x16, 0xC0, 0x81, 0x0D, 0x38, 0xD1, 0x08, -}; -static const char testanim_p3[] = { 0x21, 0xC5, 0x2A, 0x86, 0x5C, 0xF7, 0x35, 0x48, 0x74, 0x55, 0x07, 0xBE, 0xD4, 0x4A, 0x14, 0x27, 0x47, 0x49, 0x84, 0x0D, 0xB3, 0x61, 0xC0, 0x88, 0xD6, 0x5C, 0x4E, 0x51, 0x9F, 0x48, 0xCE, 0x48, 0x79, 0x85, 0xC0, 0x88, 0x01, 0x62, 0x95, 0xC3, 0x34, 0x0E, 0xC0, 0xA7, 0x35, 0x2C, 0xDD, 0x51, @@ -201,8 +197,6 @@ static const char testanim_p3[] = { 0x83, 0xB2, 0x64, 0xAA, 0xF2, 0x4D, 0x4C, 0x67, 0x38, 0x33, 0x61, 0x1F, 0x1D, 0x71, 0x67, 0xAE, 0x63, 0x4A, 0x86, 0x13, 0x68, 0x7F, 0x01, 0x65, 0xAC, 0x17, 0x5F, 0x40, 0x62, 0x68, 0xBB, 0x66, 0x77, 0x53, 0xA6, 0x77, 0xA8, 0x20, 0x2B, 0xA5, 0xC3, 0x34, 0xF2, 0x86, 0x0A, 0xEC, 0xD2, 0x24, -}; -static const char testanim_p4[] = { 0xE0, 0x67, 0x2E, 0x2B, 0x24, 0x0E, 0x6B, 0x93, 0x27, 0x4B, 0x43, 0x0F, 0x5D, 0x26, 0x7C, 0x59, 0xB7, 0x21, 0x71, 0x41, 0x2F, 0x01, 0x24, 0x7B, 0xBD, 0x55, 0x3E, 0x7E, 0x38, 0x1B, 0x40, 0xE1, 0x3A, 0x08, 0x70, 0x85, 0x82, 0xE0, 0x73, 0x7A, 0x32, 0x3A, 0x06, 0xC8, 0x6E, 0xD3, 0x73, 0x6B, @@ -267,8 +261,6 @@ static const char testanim_p4[] = { 0x32, 0xA0, 0x03, 0x1D, 0x40, 0x03, 0x0B, 0x00, 0x03, 0x71, 0xFA, 0x02, 0x7A, 0x9A, 0x97, 0x40, 0x40, 0x02, 0x78, 0x69, 0x9B, 0x31, 0x26, 0x03, 0xE2, 0x33, 0x51, 0xF4, 0x30, 0xA5, 0xB3, 0x81, 0x35, 0x77, 0x42, 0x5D, 0x58, 0x5A, 0x19, 0xE5, 0xEA, 0x66, 0x27, 0x2A, 0x0B, 0x33, 0xE6, 0x6B, -}; -static const char testanim_p5[] = { 0x0A, 0x89, 0x65, 0xB3, 0x35, 0xA0, 0xA5, 0xE9, 0x93, 0xBC, 0x78, 0x9D, 0xEA, 0xFA, 0x1D, 0xAE, 0xD3, 0x88, 0x05, 0x1A, 0x00, 0x9E, 0xDA, 0x02, 0x33, 0xE2, 0x01, 0x16, 0xFA, 0x02, 0x42, 0xF0, 0x02, 0x3E, 0x90, 0x97, 0x3A, 0x80, 0x97, 0xA4, 0xEA, 0x03, 0x24, 0x45, 0x3E, 0xAC, 0x64, 0xAB, @@ -333,8 +325,6 @@ static const char testanim_p5[] = { 0xBD, 0xFC, 0x56, 0x2E, 0xE0, 0x28, 0x7B, 0xE9, 0xB4, 0xF5, 0x1A, 0x63, 0xD1, 0x1A, 0x63, 0x5D, 0x3C, 0xC3, 0x1C, 0xBD, 0xA4, 0x61, 0x79, 0x67, 0xBB, 0xA2, 0x24, 0x71, 0xE5, 0x3B, 0x3B, 0x02, 0x29, 0x2B, 0x0A, 0xD2, 0xFA, 0x8C, 0x65, 0x6F, 0x8D, 0xCD, 0xEA, 0x06, 0x6F, 0x71, 0x69, 0x4D, -}; -static const char testanim_p6[] = { 0xDD, 0x5C, 0xB4, 0x61, 0x8A, 0x55, 0x78, 0xF8, 0xD2, 0xDB, 0xD6, 0xC4, 0x2F, 0x90, 0x9E, 0xCC, 0x5A, 0xAF, 0x35, 0xD0, 0xA6, 0x82, 0xBD, 0x8A, 0xB9, 0x82, 0xA5, 0xF3, 0x59, 0x21, 0xE9, 0x04, 0x26, 0xA8, 0xA5, 0x23, 0x4A, 0xD1, 0xDA, 0x56, 0x13, 0x01, 0x74, 0x86, 0x0A, 0xD0, 0x10, 0xD9, @@ -399,8 +389,6 @@ static const char testanim_p6[] = { 0x11, 0x88, 0x8B, 0x2A, 0x2A, 0xE0, 0xE7, 0x8D, 0x05, 0xE7, 0x90, 0xA3, 0x98, 0xDF, 0x96, 0x90, 0xDD, 0xA6, 0x82, 0x9D, 0xD4, 0xD0, 0xD1, 0x98, 0x02, 0x06, 0x0C, 0xB0, 0x72, 0xB5, 0x20, 0x96, 0x87, 0x16, 0x32, 0x6C, 0xE9, 0xD2, 0x25, 0xE3, 0x85, 0x8E, 0x5E, 0x1D, 0x30, 0x6C, 0x08, 0xC6, -}; -static const char testanim_p7[] = { 0xEA, 0x40, 0x83, 0x03, 0x19, 0x1A, 0x28, 0x1B, 0xD0, 0x60, 0x9A, 0xB2, 0x4D, 0x04, 0x04, 0x39, 0xF3, 0x64, 0xA9, 0x94, 0xB7, 0x7D, 0xFB, 0xB6, 0xA9, 0x9C, 0x00, 0xCF, 0x54, 0x3E, 0x70, 0x88, 0x06, 0x88, 0x73, 0x34, 0x80, 0x82, 0x0A, 0x46, 0x88, 0x2A, 0x35, 0x6A, 0xC4, 0xA8, 0x52, 0x24, @@ -465,8 +453,6 @@ static const char testanim_p7[] = { 0x01, 0x1F, 0x50, 0x50, 0x18, 0x09, 0x67, 0x9D, 0x03, 0x6B, 0xCF, 0x18, 0x8A, 0x4F, 0x4C, 0x51, 0x8C, 0x59, 0x80, 0xC0, 0x00, 0x64, 0xAA, 0x8F, 0x04, 0x2C, 0x00, 0x9F, 0x5C, 0x60, 0x60, 0x65, 0x35, 0x78, 0x48, 0x69, 0x3A, 0xD0, 0x82, 0x91, 0x6D, 0x20, 0x22, 0x4F, 0xEC, 0x00, 0xA8, 0xD4, -}; -static const char testanim_p8[] = { 0xA2, 0x23, 0x5A, 0xE1, 0x26, 0x47, 0xC9, 0x23, 0x89, 0x63, 0x46, 0x32, 0x80, 0xB2, 0x64, 0x69, 0x50, 0xF9, 0xE8, 0x4E, 0x27, 0xCA, 0xE1, 0x38, 0x14, 0xDE, 0x30, 0x02, 0xD2, 0xB2, 0x10, 0x00, 0x70, 0xF7, 0xB3, 0xEA, 0xF0, 0xA5, 0x12, 0x56, 0xB2, 0xC4, 0x8E, 0xB2, 0x36, 0x94, 0x4C, 0xD1, @@ -531,8 +517,6 @@ static const char testanim_p8[] = { 0x12, 0x42, 0x3C, 0x6C, 0xF3, 0x51, 0x92, 0x20, 0x33, 0x82, 0x42, 0x68, 0xB4, 0xB0, 0xD5, 0x68, 0x40, 0xA2, 0x1A, 0x21, 0x87, 0x78, 0x80, 0x11, 0xD4, 0x18, 0xCC, 0x5C, 0x46, 0x80, 0xB4, 0xD0, 0x90, 0x40, 0xD2, 0x82, 0x1A, 0xDB, 0x2E, 0xCC, 0x33, 0xC2, 0x52, 0xC6, 0x0F, 0x5C, 0x32, 0x6A, -}; -static const char testanim_p9[] = { 0x0C, 0x01, 0xE2, 0xA3, 0x05, 0x86, 0x0E, 0x92, 0x0E, 0x90, 0x78, 0x61, 0x61, 0xC1, 0x0B, 0x1B, 0xFE, 0x2F, 0x3C, 0xD1, 0x20, 0x08, 0xE4, 0xE3, 0x8F, 0x17, 0x35, 0x6A, 0xB4, 0x70, 0x61, 0xD5, 0xC8, 0x82, 0xBF, 0x5C, 0x49, 0xB8, 0xF0, 0xF1, 0x71, 0x88, 0x8C, 0x8F, 0x3E, 0x78, 0x1A, 0x21, diff --git a/demos/modules/gwin/widgets/romfs_img_yesno.h b/demos/modules/gwin/widgets/romfs_img_yesno.h index 0559330e..6b2c1290 100644 --- a/demos/modules/gwin/widgets/romfs_img_yesno.h +++ b/demos/modules/gwin/widgets/romfs_img_yesno.h @@ -1,7 +1,7 @@ /** * This file was generated from "image_yesno.gif" using... * - * file2c -bbcs image_yesno.gif romfs_img_yesno.h + * file2c -dcs image_yesno.gif romfs_img_yesno.h * */ static const char image_yesno[] = {