1
0
Fork 0
forked from len0rd/rockbox

Add support for scaled bitmap loads, and for greylib display, to

pictureflow, as well as several small fixes in the areas modified.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19598 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Andrew Mahone 2008-12-27 00:26:15 +00:00
parent 78d625f840
commit 932f30d825
4 changed files with 199 additions and 202 deletions

View file

@ -129,11 +129,10 @@ splitedit.c
#if LCD_DEPTH > 1 /* non-mono bitmap targets */ #if LCD_DEPTH > 1 /* non-mono bitmap targets */
matrix.c matrix.c
#endif #if defined(HAVE_ALBUMART) && defined(HAVE_TAGCACHE)
#if defined(HAVE_LCD_COLOR) && defined(HAVE_ALBUMART) && defined(HAVE_TAGCACHE)
pictureflow.c pictureflow.c
#endif #endif
#endif
/* Platform-specific plugins */ /* Platform-specific plugins */
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)

View file

@ -669,17 +669,12 @@ matrix_normal.bmp
#endif #endif
/* pictureflow */ /* pictureflow */
#if defined(HAVE_LCD_COLOR) && defined(HAVE_ALBUMART) && defined(HAVE_TAGCACHE) #if defined(HAVE_ALBUMART) && defined(HAVE_TAGCACHE)
#if (LCD_WIDTH < 200) #if (LCD_WIDTH < 200)
pictureflow_logo.100x18x16.bmp pictureflow_logo.100x18x16.bmp
#else #else
pictureflow_logo.193x34x16.bmp pictureflow_logo.193x34x16.bmp
#endif #endif
#if (LCD_HEIGHT < 100 )
pictureflow_emptyslide.50x50x16.bmp
#else
pictureflow_emptyslide.100x100x16.bmp
#endif
#endif #endif
/* Sliding puzzle */ /* Sliding puzzle */

View file

@ -26,11 +26,9 @@
#include "plugin.h" #include "plugin.h"
#include "lib/pluginlib_actions.h" #include "lib/pluginlib_actions.h"
#include "lib/helper.h" #include "lib/helper.h"
#include "lib/bmp.h"
#include "lib/picture.h" #include "lib/picture.h"
#include "pluginbitmaps/pictureflow_logo.h" #include "pluginbitmaps/pictureflow_logo.h"
#include "pluginbitmaps/pictureflow_emptyslide.h" #include "lib/grey.h"
PLUGIN_HEADER PLUGIN_HEADER
@ -43,7 +41,34 @@ const struct button_mapping *plugin_contexts[]
#define NB_ACTION_CONTEXTS sizeof(plugin_contexts)/sizeof(plugin_contexts[0]) #define NB_ACTION_CONTEXTS sizeof(plugin_contexts)/sizeof(plugin_contexts[0])
#if LCD_DEPTH < 8
#define USEGSLIB
GREY_INFO_STRUCT
#define FPLUGIN &format_grey
#define LCD_BUF _grey_info.buffer
#define MYLCD(fn) grey_ ## fn
#define G_PIX(r,g,b) \
(77 * (unsigned)(r) + 150 * (unsigned)(g) + 29 * (unsigned)(b)) / 256
#define N_PIX(r,g,b) LCD_BRIGHTNESS(G_PIX(r,g,b))
#define G_BRIGHT(y) (y)
#define N_BRIGHT(y) LCD_BRIGHTNESS(y)
#define BUFFER_WIDTH _grey_info.width
#define BUFFER_HEIGHT _grey_info.height
typedef unsigned char pix_t;
#else
#define FPLUGIN NULL
#define LCD_BUF rb->lcd_framebuffer
#define MYLCD(fn) rb->lcd_ ## fn
#define G_PIX LCD_RGBPACK
#define N_PIX LCD_RGBPACK
#define G_BRIGHT(y) LCD_RGBPACK(y,y,y)
#define N_BRIGHT(y) LCD_RGBPACK(y,y,y)
#define BUFFER_WIDTH LCD_WIDTH
#define BUFFER_HEIGHT LCD_HEIGHT
typedef fb_data pix_t;
#endif
#define WRNDUP(w, size) (((w)+(size)-1)/(size)*(size))
#ifdef HAVE_SCROLLWHEEL #ifdef HAVE_SCROLLWHEEL
#define PICTUREFLOW_NEXT_ALBUM PLA_DOWN #define PICTUREFLOW_NEXT_ALBUM PLA_DOWN
#define PICTUREFLOW_NEXT_ALBUM_REPEAT PLA_DOWN_REPEAT #define PICTUREFLOW_NEXT_ALBUM_REPEAT PLA_DOWN_REPEAT
@ -76,20 +101,11 @@ const struct button_mapping *plugin_contexts[]
#define IANGLE_MAX 1024 #define IANGLE_MAX 1024
#define IANGLE_MASK 1023 #define IANGLE_MASK 1023
/* maximum size of an slide */ #define DISPLAY_SIZE (LCD_HEIGHT/2)
#define MAX_IMG_WIDTH LCD_WIDTH #define REFLECT_TOP (DISPLAY_SIZE * 4 / 3)
#define MAX_IMG_HEIGHT LCD_HEIGHT #define REFLECT_HEIGHT ((DISPLAY_SIZE * 2) - REFLECT_TOP)
#define REFLECT_SC ((0x10000U * 3 + (REFLECT_HEIGHT * 5 - 1)) / \
#if (LCD_HEIGHT < 100) (REFLECT_HEIGHT * 5))
#define PREFERRED_IMG_WIDTH 50
#define PREFERRED_IMG_HEIGHT 50
#else
#define PREFERRED_IMG_WIDTH 100
#define PREFERRED_IMG_HEIGHT 100
#endif
#define BUFFER_WIDTH LCD_WIDTH
#define BUFFER_HEIGHT LCD_HEIGHT
#define SLIDE_CACHE_SIZE 100 #define SLIDE_CACHE_SIZE 100
@ -115,6 +131,7 @@ const struct button_mapping *plugin_contexts[]
#define UNIQBUF_SIZE (64*1024) #define UNIQBUF_SIZE (64*1024)
#define EMPTY_SLIDE CACHE_PREFIX "/emptyslide.pfraw" #define EMPTY_SLIDE CACHE_PREFIX "/emptyslide.pfraw"
#define EMPTY_SLIDE_BMP PLUGIN_DEMOS_DIR "/pictureflow_emptyslide.bmp"
#define CONFIG_FILE CACHE_PREFIX "/pictureflow.config" #define CONFIG_FILE CACHE_PREFIX "/pictureflow.config"
/* Error return values */ /* Error return values */
@ -185,8 +202,8 @@ struct config_data {
/** below we allocate the memory we want to use **/ /** below we allocate the memory we want to use **/
static fb_data *buffer; /* for now it always points to the lcd framebuffer */ static pix_t *buffer; /* for now it always points to the lcd framebuffer */
static PFreal rays[BUFFER_WIDTH]; static PFreal rays[LCD_WIDTH];
static struct slide_data center_slide; static struct slide_data center_slide;
static struct slide_data left_slides[MAX_SLIDES_COUNT]; static struct slide_data left_slides[MAX_SLIDES_COUNT];
static struct slide_data right_slides[MAX_SLIDES_COUNT]; static struct slide_data right_slides[MAX_SLIDES_COUNT];
@ -228,10 +245,12 @@ static int track_index;
static int selected_track; static int selected_track;
static int selected_track_pulse; static int selected_track_pulse;
static fb_data *input_bmp_buffer; #define INPUT_SIZE BM_SIZE(DISPLAY_SIZE, DISPLAY_SIZE, FORMAT_NATIVE, 0)
static fb_data *output_bmp_buffer; #define SC_BUF_SIZE BM_SCALED_SIZE(DISPLAY_SIZE, 0, FORMAT_NATIVE, 0)
static int input_hid; #define OUTPUT_SIZE BM_SIZE(DISPLAY_SIZE * 2, DISPLAY_SIZE, FORMAT_NATIVE, 0)
static int output_hid;
void * plugin_buf;
size_t plugin_buf_size;
static struct config_data config; static struct config_data config;
static int old_drawmode; static int old_drawmode;
@ -278,7 +297,8 @@ static int pf_state;
/** code */ /** code */
bool create_bmp(struct bitmap* input_bmp, char *target_path, bool resize); bool create_bmp(struct bitmap* input_bmp, void *buf, size_t buf_size,
char *target_path);
int load_surface(int); int load_surface(int);
static inline PFreal fmul(PFreal a, PFreal b) static inline PFreal fmul(PFreal a, PFreal b)
@ -496,17 +516,12 @@ bool get_albumart_for_index_from_db(const int slide_index, char *buf, int buflen
if ( rb->tagcache_get_next(&tcs) ) { if ( rb->tagcache_get_next(&tcs) ) {
struct mp3entry id3; struct mp3entry id3;
char size[9];
int fd; int fd;
rb->snprintf(size, sizeof(size), ".%dx%d", PREFERRED_IMG_WIDTH,
PREFERRED_IMG_HEIGHT);
fd = rb->open(tcs.result, O_RDONLY); fd = rb->open(tcs.result, O_RDONLY);
rb->get_metadata(&id3, fd, tcs.result); rb->get_metadata(&id3, fd, tcs.result);
rb->close(fd); rb->close(fd);
if ( rb->search_albumart_files(&id3, size, buf, buflen) ) if ( rb->search_albumart_files(&id3, "", buf, buflen) )
result = true;
else if ( rb->search_albumart_files(&id3, "", buf, buflen) )
result = true; result = true;
else else
result = false; result = false;
@ -526,8 +541,8 @@ void draw_splashscreen(void)
{ {
struct screen* display = rb->screens[0]; struct screen* display = rb->screens[0];
rb->lcd_set_background(LCD_RGBPACK(0,0,0)); rb->lcd_set_background(N_BRIGHT(0));
rb->lcd_set_foreground(LCD_RGBPACK(255,255,255)); rb->lcd_set_foreground(N_BRIGHT(255));
rb->lcd_clear_display(); rb->lcd_clear_display();
const struct picture* logo = &(logos[display->screen_type]); const struct picture* logo = &(logos[display->screen_type]);
@ -554,59 +569,16 @@ void draw_progressbar(int step)
rb->lcd_putsxy((LCD_WIDTH - txt_w)/2, y, "Preparing album artwork"); rb->lcd_putsxy((LCD_WIDTH - txt_w)/2, y, "Preparing album artwork");
y += (txt_h + 5); y += (txt_h + 5);
rb->lcd_set_foreground(LCD_RGBPACK(100,100,100)); rb->lcd_set_foreground(N_BRIGHT(100));
rb->lcd_drawrect(x, y, w+2, bar_height); rb->lcd_drawrect(x, y, w+2, bar_height);
rb->lcd_set_foreground(LCD_RGBPACK(165, 231, 82)); rb->lcd_set_foreground(N_PIX(165, 231, 82));
rb->lcd_fillrect(x+1, y+1, step * w / album_count, bar_height-2); rb->lcd_fillrect(x+1, y+1, step * w / album_count, bar_height-2);
rb->lcd_set_foreground(LCD_RGBPACK(255,255,255)); rb->lcd_set_foreground(N_BRIGHT(255));
rb->lcd_update(); rb->lcd_update();
rb->yield(); rb->yield();
} }
/**
Allocate temporary buffers
*/
bool allocate_buffers(void)
{
int input_size = MAX_IMG_WIDTH * MAX_IMG_HEIGHT * sizeof( fb_data );
int output_size = MAX_IMG_WIDTH * MAX_IMG_HEIGHT * sizeof( fb_data ) * 2;
input_hid = rb->bufalloc(NULL, input_size, TYPE_BITMAP);
if (input_hid < 0)
return false;
if (rb->bufgetdata(input_hid, 0, (void *)&input_bmp_buffer) < input_size) {
rb->bufclose(input_hid);
return false;
}
output_hid = rb->bufalloc(NULL, output_size, TYPE_BITMAP);
if (output_hid < 0) {
rb->bufclose(input_hid);
return false;
}
if (rb->bufgetdata(output_hid, 0, (void *)&output_bmp_buffer) < output_size) {
rb->bufclose(output_hid);
return false;
}
return true;
}
/**
Free the temporary buffers
*/
bool free_buffers(void)
{
rb->bufclose(input_hid);
rb->bufclose(output_hid);
return true;
}
/** /**
Precomupte the album art images and store them in CACHE_PREFIX. Precomupte the album art images and store them in CACHE_PREFIX.
*/ */
@ -622,7 +594,7 @@ bool create_albumart_cache(bool force)
config.avg_album_width = 0; config.avg_album_width = 0;
char pfraw_file[MAX_PATH]; char pfraw_file[MAX_PATH];
char arlbumart_file[MAX_PATH]; char albumart_file[MAX_PATH];
for (i=0; i < album_count; i++) for (i=0; i < album_count; i++)
{ {
rb->snprintf(pfraw_file, sizeof(pfraw_file), CACHE_PREFIX "/%d.pfraw", i); rb->snprintf(pfraw_file, sizeof(pfraw_file), CACHE_PREFIX "/%d.pfraw", i);
@ -630,18 +602,23 @@ bool create_albumart_cache(bool force)
if(rb->file_exists(pfraw_file)) if(rb->file_exists(pfraw_file))
rb->remove(pfraw_file); rb->remove(pfraw_file);
draw_progressbar(i); draw_progressbar(i);
if (!get_albumart_for_index_from_db(i, arlbumart_file, MAX_PATH)) if (!get_albumart_for_index_from_db(i, albumart_file, MAX_PATH))
continue; continue;
input_bmp.data = (char *)input_bmp_buffer; input_bmp.data = plugin_buf;
ret = rb->read_bmp_file(arlbumart_file, &input_bmp, input_bmp.width = DISPLAY_SIZE;
sizeof(fb_data)*MAX_IMG_WIDTH*MAX_IMG_HEIGHT, input_bmp.height = DISPLAY_SIZE;
FORMAT_NATIVE, NULL); ret = rb->read_bmp_file(albumart_file, &input_bmp,
plugin_buf_size,
FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT,
FPLUGIN);
if (ret <= 0) { if (ret <= 0) {
rb->splash(HZ, "Could not read bmp"); rb->splash(HZ, "Could not read bmp");
continue; /* skip missing/broken files */ continue; /* skip missing/broken files */
} }
if (!create_bmp(&input_bmp, pfraw_file, false)) { if (!create_bmp(&input_bmp, plugin_buf + WRNDUP(ret, 4),
plugin_buf_size - WRNDUP(ret, 4), pfraw_file))
{
rb->splash(HZ, "Could not write bmp"); rb->splash(HZ, "Could not write bmp");
} }
config.avg_album_width += input_bmp.width; config.avg_album_width += input_bmp.width;
@ -850,8 +827,8 @@ bool save_pfraw(char* filename, struct bitmap *bm)
int y; int y;
for( y = 0; y < bm->height; y++ ) for( y = 0; y < bm->height; y++ )
{ {
fb_data *d = (fb_data*)( bm->data ) + (y*bm->width); pix_t *d = (pix_t*)( bm->data ) + (y*bm->width);
rb->write( fh, d, sizeof( fb_data ) * bm->width ); rb->write( fh, d, sizeof( pix_t ) * bm->width );
} }
rb->close( fh ); rb->close( fh );
return true; return true;
@ -870,7 +847,8 @@ int read_pfraw(char* filename)
return empty_slide_hid; return empty_slide_hid;
} }
int size = sizeof(struct bitmap) + sizeof( fb_data ) * bmph.width * bmph.height; int size = sizeof(struct bitmap) + sizeof( pix_t ) *
bmph.width * bmph.height;
int hid = rb->bufalloc(NULL, size, TYPE_BITMAP); int hid = rb->bufalloc(NULL, size, TYPE_BITMAP);
if (hid < 0) { if (hid < 0) {
@ -892,8 +870,8 @@ int read_pfraw(char* filename)
int y; int y;
for( y = 0; y < bm->height; y++ ) for( y = 0; y < bm->height; y++ )
{ {
fb_data *d = (fb_data*)( bm->data ) + (y*bm->width); pix_t *d = (pix_t*)( bm->data ) + (y*bm->width);
rb->read( fh, d , sizeof( fb_data ) * bm->width ); rb->read( fh, d , sizeof( pix_t ) * bm->width );
} }
rb->close( fh ); rb->close( fh );
return hid; return hid;
@ -904,39 +882,26 @@ int read_pfraw(char* filename)
Create the slide with its reflection for the given slide_index and filename Create the slide with its reflection for the given slide_index and filename
and store it as pfraw in CACHE_PREFIX/[slide_index].pfraw and store it as pfraw in CACHE_PREFIX/[slide_index].pfraw
*/ */
bool create_bmp(struct bitmap *input_bmp, char *target_path, bool resize) bool create_bmp(struct bitmap *input_bmp, void * buffer, size_t buffer_len,
char *target_path)
{ {
struct bitmap output_bmp; struct bitmap output_bmp;
output_bmp.format = input_bmp->format; output_bmp.format = input_bmp->format;
output_bmp.data = (char *)output_bmp_buffer; output_bmp.data = (char *)buffer;
if ( resize ) { output_bmp.width = 2 * DISPLAY_SIZE;
/* resize image */ output_bmp.height = input_bmp->width;
output_bmp.width = config.avg_album_width;
output_bmp.height = config.avg_album_width;
smooth_resize_bitmap(input_bmp, &output_bmp);
/* Resized bitmap is now in the output buffer,
copy it back to the input buffer */
rb->memcpy(input_bmp_buffer, output_bmp_buffer,
config.avg_album_width * config.avg_album_width * sizeof(fb_data));
input_bmp->data = (char *)input_bmp_buffer;
input_bmp->width = output_bmp.width;
input_bmp->height = output_bmp.height;
}
output_bmp.width = input_bmp->width * 2;
output_bmp.height = input_bmp->height;
fb_data *src = (fb_data *)input_bmp->data;
fb_data *dst = (fb_data *)output_bmp.data;
pix_t *src = (pix_t *)input_bmp->data;
pix_t *dst = (pix_t *)output_bmp.data;
if (sizeof(pix_t) * output_bmp.width * output_bmp.height > buffer_len)
return 0;
/* transpose the image, this is to speed-up the rendering /* transpose the image, this is to speed-up the rendering
because we process one column at a time because we process one column at a time
(and much better and faster to work row-wise, i.e in one scanline) */ (and much better and faster to work row-wise, i.e in one scanline) */
int hofs = input_bmp->width / 3; int hofs = REFLECT_TOP - input_bmp->height;
rb->memset(dst, 0, sizeof(fb_data) * output_bmp.width * output_bmp.height); rb->memset(dst, 0, sizeof(pix_t) * output_bmp.width * output_bmp.height);
int x, y; int x, y;
for (x = 0; x < input_bmp->width; x++) for (x = 0; x < input_bmp->width; x++)
for (y = 0; y < input_bmp->height; y++) for (y = 0; y < input_bmp->height; y++)
@ -944,16 +909,20 @@ bool create_bmp(struct bitmap *input_bmp, char *target_path, bool resize)
src[y * input_bmp->width + x]; src[y * input_bmp->width + x];
/* create the reflection */ /* create the reflection */
int ht = input_bmp->height - hofs; for (y = 0; y < REFLECT_HEIGHT; y++) {
int hte = ht; uint32_t sc = (REFLECT_HEIGHT - y) * REFLECT_SC;
for (x = 0; x < input_bmp->width; x++) { for (x = 0; x < input_bmp->width; x++) {
for (y = 0; y < ht; y++) { pix_t color = src[x + input_bmp->width *
fb_data color = src[x + input_bmp->width * (input_bmp->height - y - 1)]; (input_bmp->height - y - 1)];
int r = RGB_UNPACK_RED(color) * (hte - y) / hte * 3 / 5; #ifdef USEGSLIB
int g = RGB_UNPACK_GREEN(color) * (hte - y) / hte * 3 / 5; pix_t out = color * sc >> 16;
int b = RGB_UNPACK_BLUE(color) * (hte - y) / hte * 3 / 5; #else
dst[output_bmp.height + hofs + y + output_bmp.width * x] = int r = RGB_UNPACK_RED(color) * sc >> 16;
LCD_RGBPACK(r, g, b); int g = RGB_UNPACK_GREEN(color) * sc >> 16;
int b = RGB_UNPACK_BLUE(color) * sc >> 16;
pix_t out = LCD_RGBPACK(r, g, b);
#endif
dst[input_bmp->height + hofs + y + output_bmp.width * x] = out;
} }
} }
return save_pfraw(target_path, &output_bmp); return save_pfraw(target_path, &output_bmp);
@ -1093,8 +1062,8 @@ void reset_slides(void)
*/ */
void recalc_table(void) void recalc_table(void)
{ {
int w = (BUFFER_WIDTH + 1) / 2; int w = (LCD_WIDTH + 1) / 2;
int h = (BUFFER_HEIGHT + 1) / 2; int h = (LCD_HEIGHT + 1) / 2;
int i; int i;
for (i = 0; i < w; i++) { for (i = 0; i < w; i++) {
PFreal gg = (PFREAL_HALF + i * PFREAL_ONE) / (2 * h); PFreal gg = (PFREAL_HALF + i * PFREAL_ONE) / (2 * h);
@ -1106,7 +1075,7 @@ void recalc_table(void)
offsetX = config.avg_album_width / 2 * (PFREAL_ONE - fcos(itilt)); offsetX = config.avg_album_width / 2 * (PFREAL_ONE - fcos(itilt));
offsetY = config.avg_album_width / 2 * fsin(itilt); offsetY = config.avg_album_width / 2 * fsin(itilt);
offsetX += config.avg_album_width * PFREAL_ONE; offsetX += config.avg_album_width * PFREAL_ONE * 3 / 4;
offsetY += config.avg_album_width * PFREAL_ONE / 4; offsetY += config.avg_album_width * PFREAL_ONE / 4;
offsetX += config.extra_spacing_for_center_slide << PFREAL_SHIFT; offsetX += config.extra_spacing_for_center_slide << PFREAL_SHIFT;
} }
@ -1117,23 +1086,25 @@ void recalc_table(void)
to an uint, multiply and compress the result back to a ushort. to an uint, multiply and compress the result back to a ushort.
*/ */
#if (LCD_PIXELFORMAT == RGB565SWAPPED) #if (LCD_PIXELFORMAT == RGB565SWAPPED)
static inline fb_data fade_color(fb_data c, unsigned int a) static inline pix_t fade_color(pix_t c, unsigned int a)
{ {
c = swap16(c); c = swap16(c);
unsigned int p = ((((c|(c<<16)) & 0x07e0f81f) * a) >> 5) & 0x07e0f81f; unsigned int p = ((((c|(c<<16)) & 0x07e0f81f) * a) >> 5) & 0x07e0f81f;
return swap16( (fb_data) (p | ( p >> 16 )) ); return swap16( (pix_t) (p | ( p >> 16 )) );
} }
#else #elif LCD_PIXELFORMAT == RGB565
static inline fb_data fade_color(fb_data c, unsigned int a) static inline pix_t fade_color(pix_t c, unsigned int a)
{ {
unsigned int p = ((((c|(c<<16)) & 0x07e0f81f) * a) >> 5) & 0x07e0f81f; unsigned int p = ((((c|(c<<16)) & 0x07e0f81f) * a) >> 5) & 0x07e0f81f;
return (p | ( p >> 16 )); return (p | ( p >> 16 ));
} }
#else
static inline pix_t fade_color(pix_t c, unsigned int a)
{
return (unsigned int)c * a >> 8;
}
#endif #endif
/** /**
Render a single slide Render a single slide
*/ */
@ -1145,7 +1116,7 @@ void render_slide(struct slide_data *slide, struct rect *result_rect,
if (!bmp) { if (!bmp) {
return; return;
} }
fb_data *src = (fb_data *)bmp->data; pix_t *src = (pix_t *)bmp->data;
const int sw = bmp->height; const int sw = bmp->height;
const int sh = bmp->width; const int sh = bmp->width;
@ -1172,7 +1143,11 @@ void render_slide(struct slide_data *slide, struct rect *result_rect,
PFreal ys = slide->cy - bmp->width * sdy / 4; PFreal ys = slide->cy - bmp->width * sdy / 4;
PFreal dist = distance * PFREAL_ONE; PFreal dist = distance * PFREAL_ONE;
const int alpha4 = alpha >> 3; #ifdef USEGSLIB
const int alphasc = alpha;
#else
const int alphasc = alpha >> 3;
#endif
int xi = fmax((PFreal) 0, int xi = fmax((PFreal) 0,
((w * PFREAL_ONE / 2) + ((w * PFREAL_ONE / 2) +
@ -1189,9 +1164,10 @@ void render_slide(struct slide_data *slide, struct rect *result_rect,
PFreal fk = rays[x]; PFreal fk = rays[x];
if (sdy) { if (sdy) {
fk = fk - fdiv(sdx, sdy); fk = fk - fdiv(sdx, sdy);
hity = -fdiv(( rays[x] * distance if (fk)
- slide->cx hity = -fdiv(( rays[x] * distance
+ slide->cy * sdx / sdy), fk); - slide->cx
+ slide->cy * sdx / sdy), fk);
} }
dist = distance * PFREAL_ONE + hity; dist = distance * PFREAL_ONE + hity;
@ -1216,8 +1192,8 @@ void render_slide(struct slide_data *slide, struct rect *result_rect,
int y1 = (h >> 1); int y1 = (h >> 1);
int y2 = y1 + 1; int y2 = y1 + 1;
fb_data *pixel1 = &buffer[y1 * BUFFER_WIDTH + x]; pix_t *pixel1 = &buffer[y1 * BUFFER_WIDTH + x];
fb_data *pixel2 = &buffer[y2 * BUFFER_WIDTH + x]; pix_t *pixel2 = &buffer[y2 * BUFFER_WIDTH + x];
const int pixelstep = pixel2 - pixel1; const int pixelstep = pixel2 - pixel1;
int center = (sh >> 1); int center = (sh >> 1);
@ -1225,7 +1201,7 @@ void render_slide(struct slide_data *slide, struct rect *result_rect,
int p1 = center * PFREAL_ONE - (dy >> 2); int p1 = center * PFREAL_ONE - (dy >> 2);
int p2 = center * PFREAL_ONE + (dy >> 2); int p2 = center * PFREAL_ONE + (dy >> 2);
const fb_data *ptr = &src[column * bmp->width]; const pix_t *ptr = &src[column * bmp->width];
if (alpha == 256) if (alpha == 256)
while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) {
@ -1239,8 +1215,8 @@ void render_slide(struct slide_data *slide, struct rect *result_rect,
pixel2 += pixelstep; pixel2 += pixelstep;
} else } else
while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) {
*pixel1 = fade_color(ptr[p1 >> PFREAL_SHIFT], alpha4); *pixel1 = fade_color(ptr[p1 >> PFREAL_SHIFT], alphasc);
*pixel2 = fade_color(ptr[p2 >> PFREAL_SHIFT], alpha4); *pixel2 = fade_color(ptr[p2 >> PFREAL_SHIFT], alphasc);
p1 -= dy; p1 -= dy;
p2 += dy; p2 += dy;
y1--; y1--;
@ -1332,8 +1308,9 @@ static inline bool is_empty_rect(struct rect *r)
*/ */
void render_all_slides(void) void render_all_slides(void)
{ {
rb->lcd_set_background(LCD_RGBPACK(0,0,0)); MYLCD(set_background)(G_BRIGHT(0));
rb->lcd_clear_display(); /* TODO: Optimizes this by e.g. invalidating rects */ /* TODO: Optimizes this by e.g. invalidating rects */
MYLCD(clear_display)();
int nleft = config.show_slides; int nleft = config.show_slides;
int nright = config.show_slides; int nright = config.show_slides;
@ -1342,7 +1319,7 @@ void render_all_slides(void)
r.left = LCD_WIDTH; r.top = 0; r.bottom = 0; r.right = 0; r.left = LCD_WIDTH; r.top = 0; r.bottom = 0; r.right = 0;
render_slide(&center_slide, &r, 256, -1, -1); render_slide(&center_slide, &r, 256, -1, -1);
#ifdef DEBUG_DRAW #ifdef DEBUG_DRAW
rb->lcd_drawrect(r.left, r.top, r.right - r.left, r.bottom - r.top); MYLCD(drawrect)(r.left, r.top, r.right - r.left, r.bottom - r.top);
#endif #endif
int c1 = r.left; int c1 = r.left;
int c2 = r.right; int c2 = r.right;
@ -1356,7 +1333,8 @@ void render_all_slides(void)
render_slide(&left_slides[index], &r, alpha, 0, c1 - 1); render_slide(&left_slides[index], &r, alpha, 0, c1 - 1);
if (!is_empty_rect(&r)) { if (!is_empty_rect(&r)) {
#ifdef DEBUG_DRAW #ifdef DEBUG_DRAW
rb->lcd_drawrect(r.left, r.top, r.right - r.left, r.bottom - r.top); MYLCD->(drawrect)(r.left, r.top, r.right - r.left,
r.bottom - r.top);
#endif #endif
c1 = r.left; c1 = r.left;
} }
@ -1366,16 +1344,17 @@ void render_all_slides(void)
alpha -= extra_fade; alpha -= extra_fade;
if (alpha < 0 ) alpha = 0; if (alpha < 0 ) alpha = 0;
render_slide(&right_slides[index], &r, alpha, c2 + 1, render_slide(&right_slides[index], &r, alpha, c2 + 1,
BUFFER_WIDTH); LCD_WIDTH);
if (!is_empty_rect(&r)) { if (!is_empty_rect(&r)) {
#ifdef DEBUG_DRAW #ifdef DEBUG_DRAW
rb->lcd_drawrect(r.left, r.top, r.right - r.left, r.bottom - r.top); MYLCD(drawrect)(r.left, r.top, r.right - r.left,
r.bottom - r.top);
#endif #endif
c2 = r.right; c2 = r.right;
} }
} }
} else { } else {
if ( step < 0 ) c1 = BUFFER_WIDTH; if ( step < 0 ) c1 = LCD_WIDTH;
/* the first and last slide must fade in/fade out */ /* the first and last slide must fade in/fade out */
for (index = 0; index < nleft; index++) { for (index = 0; index < nleft; index++) {
int alpha = 256; int alpha = 256;
@ -1389,7 +1368,8 @@ void render_all_slides(void)
if (!is_empty_rect(&r)) { if (!is_empty_rect(&r)) {
#ifdef DEBUG_DRAW #ifdef DEBUG_DRAW
rb->lcd_drawrect(r.left, r.top, r.right - r.left, r.bottom - r.top); MYLCD(drawrect)(r.left, r.top, r.right - r.left,
r.bottom - r.top);
#endif #endif
c1 = r.left; c1 = r.left;
} }
@ -1404,10 +1384,11 @@ void render_all_slides(void)
if (index == nright - 3) if (index == nright - 3)
alpha = (step > 0) ? 256 : 128 + fade / 2; alpha = (step > 0) ? 256 : 128 + fade / 2;
render_slide(&right_slides[index], &r, alpha, c2 + 1, render_slide(&right_slides[index], &r, alpha, c2 + 1,
BUFFER_WIDTH); LCD_WIDTH);
if (!is_empty_rect(&r)) { if (!is_empty_rect(&r)) {
#ifdef DEBUG_DRAW #ifdef DEBUG_DRAW
rb->lcd_drawrect(r.left, r.top, r.right - r.left, r.bottom - r.top); MYLCD(drawrect)(r.left, r.top, r.right - r.left,
r.bottom - r.top);
#endif #endif
c2 = r.right; c2 = r.right;
} }
@ -1531,6 +1512,9 @@ void cleanup(void *parameter)
} }
if ( empty_slide_hid != - 1) if ( empty_slide_hid != - 1)
rb->bufclose(empty_slide_hid); rb->bufclose(empty_slide_hid);
#ifdef USEGSLIB
grey_release();
#endif
rb->lcd_set_drawmode(old_drawmode); rb->lcd_set_drawmode(old_drawmode);
} }
@ -1542,11 +1526,18 @@ int create_empty_slide(bool force)
{ {
if ( force || ! rb->file_exists( EMPTY_SLIDE ) ) { if ( force || ! rb->file_exists( EMPTY_SLIDE ) ) {
struct bitmap input_bmp; struct bitmap input_bmp;
input_bmp.width = BMPWIDTH_pictureflow_emptyslide; int ret;
input_bmp.height = BMPHEIGHT_pictureflow_emptyslide; input_bmp.width = DISPLAY_SIZE;
input_bmp.height = DISPLAY_SIZE;
input_bmp.format = FORMAT_NATIVE; input_bmp.format = FORMAT_NATIVE;
input_bmp.data = (char*) &pictureflow_emptyslide; input_bmp.data = (char*)plugin_buf;
if ( ! create_bmp(&input_bmp, EMPTY_SLIDE, true) ) return false; ret = rb->read_bmp_file(EMPTY_SLIDE_BMP, &input_bmp,
plugin_buf_size,
FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT,
FPLUGIN);
if ( ! create_bmp(&input_bmp, plugin_buf + WRNDUP(ret, 4),
plugin_buf_size - WRNDUP(ret, 4), EMPTY_SLIDE) )
return false;
} }
empty_slide_hid = read_pfraw( EMPTY_SLIDE ); empty_slide_hid = read_pfraw( EMPTY_SLIDE );
@ -1623,11 +1614,10 @@ int main_menu(void)
int selection = 0; int selection = 0;
int result; int result;
rb->lcd_set_foreground(LCD_RGBPACK(255,255,255)); rb->lcd_set_foreground(N_BRIGHT(255));
MENUITEM_STRINGLIST(main_menu,"PictureFlow Main Menu",NULL, MENUITEM_STRINGLIST(main_menu,"PictureFlow Main Menu",NULL,
"Settings", "Return", "Quit"); "Settings", "Return", "Quit");
while (1) { while (1) {
switch (rb->do_menu(&main_menu,&selection, NULL, false)) { switch (rb->do_menu(&main_menu,&selection, NULL, false)) {
case 0: case 0:
@ -1750,9 +1740,9 @@ static inline void draw_gradient(int y, int h)
selected_track_pulse = (selected_track_pulse+1) % 10; selected_track_pulse = (selected_track_pulse+1) % 10;
int c2 = selected_track_pulse - 5; int c2 = selected_track_pulse - 5;
for (r=0; r<h; r++) { for (r=0; r<h; r++) {
rb->lcd_set_foreground(LCD_RGBPACK(c2+80-(c >> 9), c2+100-(c >> 9), MYLCD(set_foreground)(G_PIX(c2+80-(c >> 9), c2+100-(c >> 9),
c2+250-(c >> 8))); c2+250-(c >> 8)));
rb->lcd_hline(0, LCD_WIDTH, r+y); MYLCD(hline)(0, LCD_WIDTH, r+y);
if ( r > h/2 ) if ( r > h/2 )
c-=inc; c-=inc;
else else
@ -1768,7 +1758,7 @@ void reset_track_list(void)
{ {
int albumtxt_w, albumtxt_h; int albumtxt_w, albumtxt_h;
const char* albumtxt = get_album_name(center_index); const char* albumtxt = get_album_name(center_index);
rb->lcd_getstringsize(albumtxt, &albumtxt_w, &albumtxt_h); MYLCD(getstringsize)(albumtxt, &albumtxt_w, &albumtxt_h);
const int height = const int height =
LCD_HEIGHT-albumtxt_h-10 - (config.show_fps?(albumtxt_h + 5):0); LCD_HEIGHT-albumtxt_h-10 - (config.show_fps?(albumtxt_h + 5):0);
track_list_visible_entries = fmin( height/albumtxt_h , track_count ); track_list_visible_entries = fmin( height/albumtxt_h , track_count );
@ -1783,18 +1773,18 @@ void reset_track_list(void)
*/ */
void show_track_list(void) void show_track_list(void)
{ {
rb->lcd_clear_display(); MYLCD(clear_display)();
if ( center_slide.slide_index != track_index ) { if ( center_slide.slide_index != track_index ) {
create_track_index(center_slide.slide_index); create_track_index(center_slide.slide_index);
reset_track_list(); reset_track_list();
} }
static int titletxt_w, titletxt_h, titletxt_y, titletxt_x, i, color; static int titletxt_w, titletxt_h, titletxt_y, titletxt_x, i, color;
rb->lcd_getstringsize("W", NULL, &titletxt_h); MYLCD(getstringsize)("W", NULL, &titletxt_h);
if (track_list_visible_entries >= track_count) if (track_list_visible_entries >= track_count)
{ {
int albumtxt_h; int albumtxt_h;
const char* albumtxt = get_album_name(center_index); const char* albumtxt = get_album_name(center_index);
rb->lcd_getstringsize(albumtxt, NULL, &albumtxt_h); MYLCD(getstringsize)(albumtxt, NULL, &albumtxt_h);
titletxt_y = ((LCD_HEIGHT-albumtxt_h-10)-(track_count*albumtxt_h))/2; titletxt_y = ((LCD_HEIGHT-albumtxt_h-10)-(track_count*albumtxt_h))/2;
} }
else if (config.show_fps) else if (config.show_fps)
@ -1805,11 +1795,11 @@ void show_track_list(void)
int track_i; int track_i;
for (i=0; i < track_list_visible_entries; i++) { for (i=0; i < track_list_visible_entries; i++) {
track_i = i+start_index_track_list; track_i = i+start_index_track_list;
rb->lcd_getstringsize(get_track_name(track_i), &titletxt_w, NULL); MYLCD(getstringsize)(get_track_name(track_i), &titletxt_w, NULL);
titletxt_x = (LCD_WIDTH-titletxt_w)/2; titletxt_x = (LCD_WIDTH-titletxt_w)/2;
if ( track_i == selected_track ) { if ( track_i == selected_track ) {
draw_gradient(titletxt_y, titletxt_h); draw_gradient(titletxt_y, titletxt_h);
rb->lcd_set_foreground(LCD_RGBPACK(255,255,255)); MYLCD(set_foreground)(G_BRIGHT(255));
if (titletxt_w > LCD_WIDTH ) { if (titletxt_w > LCD_WIDTH ) {
if ( titletxt_w + track_scroll_index <= LCD_WIDTH ) if ( titletxt_w + track_scroll_index <= LCD_WIDTH )
track_scroll_dir = 1; track_scroll_dir = 1;
@ -1817,12 +1807,12 @@ void show_track_list(void)
track_scroll_index += track_scroll_dir*2; track_scroll_index += track_scroll_dir*2;
titletxt_x = track_scroll_index; titletxt_x = track_scroll_index;
} }
rb->lcd_putsxy(titletxt_x,titletxt_y,get_track_name(track_i)); MYLCD(putsxy)(titletxt_x,titletxt_y,get_track_name(track_i));
} }
else { else {
color = 250 - (abs(selected_track - track_i) * 200 / track_count); color = 250 - (abs(selected_track - track_i) * 200 / track_count);
rb->lcd_set_foreground(LCD_RGBPACK(color,color,color)); MYLCD(set_foreground)(G_BRIGHT(color));
rb->lcd_putsxy(titletxt_x,titletxt_y,get_track_name(track_i)); MYLCD(putsxy)(titletxt_x,titletxt_y,get_track_name(track_i));
} }
titletxt_y += titletxt_h; titletxt_y += titletxt_h;
} }
@ -1877,8 +1867,8 @@ void draw_album_text(void)
albumtxt = get_album_name(center_index); albumtxt = get_album_name(center_index);
} }
rb->lcd_set_foreground(LCD_RGBPACK(c,c,c)); MYLCD(set_foreground)(G_BRIGHT(c));
rb->lcd_getstringsize(albumtxt, &albumtxt_w, &albumtxt_h); MYLCD(getstringsize)(albumtxt, &albumtxt_w, &albumtxt_h);
if (center_index != prev_center_index) { if (center_index != prev_center_index) {
albumtxt_x = 0; albumtxt_x = 0;
albumtxt_dir = -1; albumtxt_dir = -1;
@ -1887,7 +1877,7 @@ void draw_album_text(void)
albumtxt_y = LCD_HEIGHT-albumtxt_h-10; albumtxt_y = LCD_HEIGHT-albumtxt_h-10;
if (albumtxt_w > LCD_WIDTH ) { if (albumtxt_w > LCD_WIDTH ) {
rb->lcd_putsxy(albumtxt_x, albumtxt_y , albumtxt); MYLCD(putsxy)(albumtxt_x, albumtxt_y , albumtxt);
if ( pf_state == pf_idle || pf_state == pf_show_tracks ) { if ( pf_state == pf_idle || pf_state == pf_show_tracks ) {
if ( albumtxt_w + albumtxt_x <= LCD_WIDTH ) albumtxt_dir = 1; if ( albumtxt_w + albumtxt_x <= LCD_WIDTH ) albumtxt_dir = 1;
else if ( albumtxt_x >= 0 ) albumtxt_dir = -1; else if ( albumtxt_x >= 0 ) albumtxt_dir = -1;
@ -1895,7 +1885,7 @@ void draw_album_text(void)
} }
} }
else { else {
rb->lcd_putsxy((LCD_WIDTH - albumtxt_w) /2, albumtxt_y , albumtxt); MYLCD(putsxy)((LCD_WIDTH - albumtxt_w) /2, albumtxt_y , albumtxt);
} }
@ -1923,11 +1913,6 @@ int main(void)
return PLUGIN_ERROR; return PLUGIN_ERROR;
} }
if (!allocate_buffers()) {
rb->splash(HZ, "Could not allocate temporary buffers");
return PLUGIN_ERROR;
}
ret = create_album_index(); ret = create_album_index();
if (ret == ERROR_BUFFER_FULL) { if (ret == ERROR_BUFFER_FULL) {
rb->splash(HZ, "Not enough memory for album names"); rb->splash(HZ, "Not enough memory for album names");
@ -1947,11 +1932,6 @@ int main(void)
return PLUGIN_ERROR; return PLUGIN_ERROR;
} }
if (!free_buffers()) {
rb->splash(HZ, "Could not free temporary buffers");
return PLUGIN_ERROR;
}
if (!create_pf_thread()) { if (!create_pf_thread()) {
rb->splash(HZ, "Cannot create thread!"); rb->splash(HZ, "Cannot create thread!");
return PLUGIN_ERROR; return PLUGIN_ERROR;
@ -1968,7 +1948,12 @@ int main(void)
} }
slide_cache_stack_index = min_slide_cache-1; slide_cache_stack_index = min_slide_cache-1;
slide_cache_in_use = 0; slide_cache_in_use = 0;
buffer = rb->lcd_framebuffer; #ifdef USEGSLIB
if (!grey_init(rb, plugin_buf, plugin_buf_size, GREY_BUFFERED|GREY_ON_COP,
LCD_WIDTH, LCD_HEIGHT, NULL))
rb->splash(HZ, "Greylib init failed!");
#endif
buffer = LCD_BUF;
pf_state = pf_idle; pf_state = pf_idle;
@ -1994,7 +1979,10 @@ int main(void)
bool instant_update; bool instant_update;
old_drawmode = rb->lcd_get_drawmode(); old_drawmode = rb->lcd_get_drawmode();
rb->lcd_set_drawmode(DRMODE_FG); #ifdef USEGSLIB
grey_show(true);
#endif
MYLCD(set_drawmode)(DRMODE_FG);
while (true) { while (true) {
current_update = *rb->current_tick; current_update = *rb->current_tick;
frames++; frames++;
@ -2033,19 +2021,21 @@ int main(void)
last_update = current_update; last_update = current_update;
frames = 0; frames = 0;
} }
/* Draw FPS */ /* Draw FPS */
if (config.show_fps) { if (config.show_fps) {
rb->lcd_set_foreground(LCD_RGBPACK(255, 0, 0)); #ifdef USEGSLIB
MYLCD(set_foreground)(G_BRIGHT(255));
#else
MYLCD(set_foreground)(G_PIX(255,0,0));
#endif
rb->snprintf(fpstxt, sizeof(fpstxt), "FPS: %d", fps); rb->snprintf(fpstxt, sizeof(fpstxt), "FPS: %d", fps);
rb->lcd_putsxy(0, 0, fpstxt); MYLCD(putsxy)(0, 0, fpstxt);
} }
draw_album_text(); draw_album_text();
/* Copy offscreen buffer to LCD and give time to other threads */ /* Copy offscreen buffer to LCD and give time to other threads */
rb->lcd_update(); MYLCD(update)();
rb->yield(); rb->yield();
/*/ Handle buttons */ /*/ Handle buttons */
@ -2058,10 +2048,16 @@ int main(void)
case PICTUREFLOW_MENU: case PICTUREFLOW_MENU:
if ( pf_state == pf_idle || pf_state == pf_scrolling ) { if ( pf_state == pf_idle || pf_state == pf_scrolling ) {
#ifdef USEGSLIB
grey_show(false);
#endif
ret = main_menu(); ret = main_menu();
if ( ret == -1 ) return PLUGIN_OK; if ( ret == -1 ) return PLUGIN_OK;
if ( ret != 0 ) return i; if ( ret != 0 ) return i;
rb->lcd_set_drawmode(DRMODE_FG); #ifdef USEGSLIB
grey_show(true);
#endif
MYLCD(set_drawmode)(DRMODE_FG);
} }
else { else {
pf_state = pf_cover_out; pf_state = pf_cover_out;
@ -2137,6 +2133,9 @@ enum plugin_status plugin_start(const struct plugin_api *api, const void *parame
#ifdef HAVE_ADJUSTABLE_CPU_FREQ #ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(true); rb->cpu_boost(true);
#endif #endif
plugin_buf = rb->plugin_get_buffer(&plugin_buf_size);
plugin_buf_size = rb->align_buffer(PUN_PTR(void**,&plugin_buf),
plugin_buf_size, 4);
ret = main(); ret = main();
#ifdef HAVE_ADJUSTABLE_CPU_FREQ #ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(false); rb->cpu_boost(false);

View file

@ -345,6 +345,10 @@ STOP
copy("$ROOT/apps/plugins/snake2.levels", "$rbdir/rocks/games/snake2.levels"); # snake2 levels copy("$ROOT/apps/plugins/snake2.levels", "$rbdir/rocks/games/snake2.levels"); # snake2 levels
} }
if(-e "$rbdir/rocks/demos/pictureflow.rock") {
copy("$ROOT/apps/plugins/bitmaps/native/pictureflow_emptyslide.100x100x16.bmp", "$rbdir/rocks/demos/pictureflow_emptyslide.bmp");
}
if($image) { if($image) {
# image is blank when this is a simulator # image is blank when this is a simulator
if( filesize("rockbox.ucl") > 1000 ) { if( filesize("rockbox.ucl") > 1000 ) {