Put icons on buflib:

Removes the max icon size limitation and doesnt waste RAM

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30931 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jonathan Gordon 2011-11-08 09:36:35 +00:00
parent 64c73c4751
commit 452a3ce274
2 changed files with 86 additions and 79 deletions

View file

@ -23,6 +23,7 @@
#include <string.h> #include <string.h>
#include "inttypes.h" #include "inttypes.h"
#include "config.h" #include "config.h"
#include "core_alloc.h"
#include "icon.h" #include "icon.h"
#include "screen_access.h" #include "screen_access.h"
#include "icons.h" #include "icons.h"
@ -40,15 +41,6 @@
#define DEFAULT_VIEWER_BMP "viewers" #define DEFAULT_VIEWER_BMP "viewers"
#define DEFAULT_REMOTE_VIEWER_BMP "remote_viewers" #define DEFAULT_REMOTE_VIEWER_BMP "remote_viewers"
/* These can be defined in config-<target>.h, if it is not provide defaults */
#if !defined(MAX_ICON_HEIGHT)
#define MAX_ICON_HEIGHT 24
#endif
#if !defined(MAX_ICON_WIDTH)
#define MAX_ICON_WIDTH 24
#endif
/* We dont actually do anything with these pointers, /* We dont actually do anything with these pointers,
but they need to be grouped like this to save code but they need to be grouped like this to save code
so storing them as void* is ok. (stops compile warning) */ so storing them as void* is ok. (stops compile warning) */
@ -68,23 +60,25 @@ static const struct bitmap inbuilt_iconset[NB_SCREENS] =
#endif #endif
}; };
#define IMG_BUFSIZE (MAX_ICON_HEIGHT * MAX_ICON_WIDTH * \ enum Iconset {
Icon_Last_Themeable *LCD_DEPTH/8) Iconset_user,
static unsigned char icon_buffer[NB_SCREENS][IMG_BUFSIZE]; Iconset_viewers,
static bool custom_icons_loaded[NB_SCREENS] = {false}; Iconset_Count
static struct bitmap user_iconset[NB_SCREENS]; };
static unsigned char viewer_icon_buffer[NB_SCREENS][IMG_BUFSIZE]; struct iconset {
static bool viewer_icons_loaded[NB_SCREENS] = {false}; struct bitmap bmp;
static struct bitmap viewer_iconset[NB_SCREENS]; bool loaded;
int handle;
int handle_locked;
} iconsets[Iconset_Count][NB_SCREENS];
#define ICON_HEIGHT(screen) (!iconsets[Iconset_user][screen].loaded ? \
#define ICON_HEIGHT(screen) (!custom_icons_loaded[screen]? \ inbuilt_iconset[screen] : iconsets[Iconset_user][screen].bmp).height \
inbuilt_iconset : user_iconset)[screen].height \
/ Icon_Last_Themeable / Icon_Last_Themeable
#define ICON_WIDTH(screen) (!custom_icons_loaded[screen]? \ #define ICON_WIDTH(screen) (!iconsets[Iconset_user][screen].loaded ? \
inbuilt_iconset : user_iconset)[screen].width inbuilt_iconset[screen] : iconsets[Iconset_user][screen].bmp).width
/* x,y in letters, not pixles */ /* x,y in letters, not pixles */
void screen_put_icon(struct screen * display, void screen_put_icon(struct screen * display,
@ -133,9 +127,9 @@ void screen_put_iconxy(struct screen * display,
} }
else if (icon >= Icon_Last_Themeable) else if (icon >= Icon_Last_Themeable)
{ {
iconset = &viewer_iconset[screen]; iconset = &iconsets[Iconset_viewers][screen].bmp;
icon -= Icon_Last_Themeable; icon -= Icon_Last_Themeable;
if (!viewer_icons_loaded[screen] || if (!iconsets[Iconset_viewers][screen].loaded ||
(global_status.viewer_icon_count * height > iconset->height) || (global_status.viewer_icon_count * height > iconset->height) ||
(icon * height + height > iconset->height)) (icon * height + height > iconset->height))
{ {
@ -143,9 +137,9 @@ void screen_put_iconxy(struct screen * display,
return; return;
} }
} }
else if (custom_icons_loaded[screen]) else if (iconsets[Iconset_user][screen].loaded)
{ {
iconset = &user_iconset[screen]; iconset = &iconsets[Iconset_user][screen].bmp;
} }
else else
{ {
@ -180,95 +174,111 @@ void screen_put_cursorxy(struct screen * display, int x, int y, bool on)
#endif #endif
} }
enum Iconset { static int buflib_move_callback(int handle, void* current, void* new)
Iconset_Mainscreen, {
Iconset_Mainscreen_viewers, (void)current;
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) (void)new;
Iconset_Remotescreen, int i;
Iconset_Remotescreen_viewers, FOR_NB_SCREENS(j)
#endif {
}; for (i=0; i<Iconset_Count; i++)
{
if (iconsets[i][j].handle == handle)
{
if (iconsets[i][j].handle_locked > 0)
return BUFLIB_CB_CANNOT_MOVE;
ptrdiff_t diff = new - current;
iconsets[i][j].bmp.data += diff;
return BUFLIB_CB_OK;
}
}
}
return BUFLIB_CB_OK;
}
static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL};
static void load_icons(const char* filename, enum Iconset iconset) static void load_icons(const char* filename, enum Iconset iconset,
enum screen_type screen)
{ {
int size_read; int size_read;
bool *loaded_ok = NULL;
struct bitmap *bmp = NULL;
int bmpformat = (FORMAT_NATIVE|FORMAT_DITHER); int bmpformat = (FORMAT_NATIVE|FORMAT_DITHER);
struct iconset *ic = &iconsets[iconset][screen];
int fd;
switch (iconset) ic->loaded = false;
{
case Iconset_Mainscreen:
loaded_ok = &custom_icons_loaded[SCREEN_MAIN];
bmp = &user_iconset[SCREEN_MAIN];
bmp->data = icon_buffer[SCREEN_MAIN];
break;
case Iconset_Mainscreen_viewers:
loaded_ok = &viewer_icons_loaded[SCREEN_MAIN];
bmp = &viewer_iconset[SCREEN_MAIN];
bmp->data = viewer_icon_buffer[SCREEN_MAIN];
break;
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
case Iconset_Remotescreen:
loaded_ok = &custom_icons_loaded[SCREEN_REMOTE];
bmp = &user_iconset[SCREEN_REMOTE];
bmp->data = icon_buffer[SCREEN_REMOTE];
bmpformat |= FORMAT_REMOTE;
break;
case Iconset_Remotescreen_viewers:
loaded_ok = &viewer_icons_loaded[SCREEN_REMOTE];
bmp = &viewer_iconset[SCREEN_REMOTE];
bmp->data = viewer_icon_buffer[SCREEN_REMOTE];
bmpformat |= FORMAT_REMOTE;
break;
#endif
}
*loaded_ok = false;
if (filename[0] && filename[0] != '-') if (filename[0] && filename[0] != '-')
{ {
char path[MAX_PATH]; char path[MAX_PATH];
snprintf(path, sizeof(path), ICON_DIR "/%s.bmp", filename); snprintf(path, sizeof(path), ICON_DIR "/%s.bmp", filename);
size_read = read_bmp_file(path, bmp, IMG_BUFSIZE, bmpformat, NULL); fd = open(path, O_RDONLY);
if (size_read > 0) if (fd < 0)
return;
size_t buf_size = read_bmp_fd(fd, &ic->bmp, 0,
bmpformat|FORMAT_RETURN_SIZE, NULL);
ic->handle = core_alloc_ex(filename, buf_size, &buflib_ops);
if (ic->handle < 0)
{ {
*loaded_ok = true; close(fd);
return;
} }
lseek(fd, 0, SEEK_SET);
ic->handle_locked = 1;
ic->bmp.data = core_get_data(ic->handle);
size_read = read_bmp_fd(fd, &ic->bmp, buf_size, bmpformat, NULL);
if (size_read <= 0)
{
core_free(ic->handle);
return;
}
ic->handle_locked = 0;
ic->loaded = true;
} }
} }
void icons_init(void) void icons_init(void)
{ {
load_icons(global_settings.icon_file, Iconset_Mainscreen); int i;
FOR_NB_SCREENS(j)
{
for (i=0; i<Iconset_Count; i++)
{
if (iconsets[i][j].loaded && iconsets[i][j].handle > 0)
{
core_free(iconsets[i][j].handle);
iconsets[i][j].loaded = false;
}
}
}
load_icons(global_settings.icon_file, Iconset_user, SCREEN_MAIN);
if (global_settings.viewers_icon_file[0] && if (global_settings.viewers_icon_file[0] &&
global_settings.viewers_icon_file[0] != '-') global_settings.viewers_icon_file[0] != '-')
{ {
load_icons(global_settings.viewers_icon_file, load_icons(global_settings.viewers_icon_file,
Iconset_Mainscreen_viewers); Iconset_viewers, SCREEN_MAIN);
read_viewer_theme_file(); read_viewer_theme_file();
} }
else else
{ {
load_icons(DEFAULT_VIEWER_BMP, Iconset_Mainscreen_viewers); load_icons(DEFAULT_VIEWER_BMP, Iconset_viewers, SCREEN_MAIN);
} }
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
load_icons(global_settings.remote_icon_file, load_icons(global_settings.remote_icon_file,
Iconset_Remotescreen); Iconset_user, SCREEN_REMOTE);
if (global_settings.remote_viewers_icon_file[0] && if (global_settings.remote_viewers_icon_file[0] &&
global_settings.remote_viewers_icon_file[0] != '-') global_settings.remote_viewers_icon_file[0] != '-')
{ {
load_icons(global_settings.remote_viewers_icon_file, load_icons(global_settings.remote_viewers_icon_file,
Iconset_Remotescreen_viewers); Iconset_viewers, SCREEN_REMOTE);
} }
else else
{ {
load_icons(DEFAULT_REMOTE_VIEWER_BMP, load_icons(DEFAULT_REMOTE_VIEWER_BMP,
Iconset_Remotescreen_viewers); Iconset_viewers, SCREEN_REMOTE);
} }
#endif #endif
} }

View file

@ -112,9 +112,6 @@
#define LCD_DEPTH 16 /* 65k colours */ #define LCD_DEPTH 16 /* 65k colours */
#define LCD_PIXELFORMAT RGB565 /* rgb565 */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */
#define MAX_ICON_HEIGHT 35
#define MAX_ICON_WIDTH 35
/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE /* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE
should be defined as well. */ should be defined as well. */
#define HAVE_LCD_SLEEP #define HAVE_LCD_SLEEP