forked from len0rd/rockbox
PictureFlow fixes and improvements:
* Reduced popping effect (FS#8303) * Scale the empty slide to average album width * Introduced some visual settings * Fix FS#8298 but make the criteria a screen height of less than 100 px so that only the c200 gets 50x50 slides The scaling code is added as a lib function with a basic test plugin that's not compiled by default. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15913 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
303cf259d9
commit
a7d08774dc
5 changed files with 322 additions and 66 deletions
|
@ -517,7 +517,7 @@ matrix_normal.bmp
|
||||||
#else
|
#else
|
||||||
pictureflow_logo.193x34x16.bmp
|
pictureflow_logo.193x34x16.bmp
|
||||||
#endif
|
#endif
|
||||||
#if (LCD_HEIGHT < 200 )
|
#if (LCD_HEIGHT < 100 )
|
||||||
pictureflow_emptyslide.50x50x16.bmp
|
pictureflow_emptyslide.50x50x16.bmp
|
||||||
#else
|
#else
|
||||||
pictureflow_emptyslide.100x100x16.bmp
|
pictureflow_emptyslide.100x100x16.bmp
|
||||||
|
|
|
@ -82,3 +82,36 @@ int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb )
|
||||||
rb->close( fh );
|
rb->close( fh );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Very simple image scale from src to dst (nearest neighbour).
|
||||||
|
Source and destination dimensions are read from the struct bitmap.
|
||||||
|
*/
|
||||||
|
void simple_resize_bitmap(struct bitmap *src, struct bitmap *dst)
|
||||||
|
{
|
||||||
|
const int srcw = src->width;
|
||||||
|
const int srch = src->height;
|
||||||
|
const int dstw = dst->width;
|
||||||
|
const int dsth = dst->height;
|
||||||
|
const fb_data *srcd = (fb_data*)(src->data);
|
||||||
|
const fb_data *dstd = (fb_data*)(dst->data);
|
||||||
|
|
||||||
|
const long xrstep = ((srcw-1) << 8) / (dstw-1);
|
||||||
|
const long yrstep = ((srch-1) << 8) / (dsth-1);
|
||||||
|
fb_data *src_row, *dst_row;
|
||||||
|
long xr, yr = 0;
|
||||||
|
int src_x, src_y, dst_x, dst_y;
|
||||||
|
for (dst_y=0; dst_y < dsth; dst_y++)
|
||||||
|
{
|
||||||
|
src_y = (yr >> 8);
|
||||||
|
src_row = (fb_data*)&srcd[src_y * srcw];
|
||||||
|
dst_row = (fb_data*)&dstd[dst_y * dstw];
|
||||||
|
for (xr=0,dst_x=0; dst_x < dstw; dst_x++)
|
||||||
|
{
|
||||||
|
src_x = (xr >> 8);
|
||||||
|
dst_row[dst_x] = src_row[src_x];
|
||||||
|
xr += xrstep;
|
||||||
|
}
|
||||||
|
yr += yrstep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,4 +27,10 @@
|
||||||
*/
|
*/
|
||||||
int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb );
|
int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Very simple image scale from src to dst (nearest neighbour).
|
||||||
|
Source and destination dimensions are read from the struct bitmap.
|
||||||
|
*/
|
||||||
|
void simple_resize_bitmap(struct bitmap *src, struct bitmap *dst);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "pluginlib_actions.h"
|
#include "pluginlib_actions.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
#include "lib/bmp.h"
|
#include "bmp.h"
|
||||||
#include "picture.h"
|
#include "picture.h"
|
||||||
#include "pictureflow_logo.h"
|
#include "pictureflow_logo.h"
|
||||||
#include "pictureflow_emptyslide.h"
|
#include "pictureflow_emptyslide.h"
|
||||||
|
@ -77,7 +77,7 @@ const struct button_mapping *plugin_contexts[]
|
||||||
#define MAX_IMG_WIDTH LCD_WIDTH
|
#define MAX_IMG_WIDTH LCD_WIDTH
|
||||||
#define MAX_IMG_HEIGHT LCD_HEIGHT
|
#define MAX_IMG_HEIGHT LCD_HEIGHT
|
||||||
|
|
||||||
#if (LCD_WIDTH < 200)
|
#if (LCD_HEIGHT < 100)
|
||||||
#define PREFERRED_IMG_WIDTH 50
|
#define PREFERRED_IMG_WIDTH 50
|
||||||
#define PREFERRED_IMG_HEIGHT 50
|
#define PREFERRED_IMG_HEIGHT 50
|
||||||
#else
|
#else
|
||||||
|
@ -90,8 +90,10 @@ const struct button_mapping *plugin_contexts[]
|
||||||
|
|
||||||
#define SLIDE_CACHE_SIZE 100
|
#define SLIDE_CACHE_SIZE 100
|
||||||
|
|
||||||
#define LEFT_SLIDES_COUNT 3
|
#define MAX_SLIDES_COUNT 10
|
||||||
#define RIGHT_SLIDES_COUNT 3
|
|
||||||
|
#define SPACING_BETWEEN_SLIDE 40
|
||||||
|
#define EXTRA_SPACING_FOR_CENTER_SLIDE 0
|
||||||
|
|
||||||
#define THREAD_STACK_SIZE DEFAULT_STACK_SIZE + 0x200
|
#define THREAD_STACK_SIZE DEFAULT_STACK_SIZE + 0x200
|
||||||
#define CACHE_PREFIX PLUGIN_DEMOS_DIR "/pictureflow"
|
#define CACHE_PREFIX PLUGIN_DEMOS_DIR "/pictureflow"
|
||||||
|
@ -106,6 +108,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 CONFIG_FILE CACHE_PREFIX "/pictureflow.config"
|
||||||
|
|
||||||
/* Error return values */
|
/* Error return values */
|
||||||
#define ERROR_NO_ALBUMS -1
|
#define ERROR_NO_ALBUMS -1
|
||||||
|
@ -154,7 +157,12 @@ const struct picture logos[]={
|
||||||
{pictureflow_logo, BMPWIDTH_pictureflow_logo, BMPHEIGHT_pictureflow_logo},
|
{pictureflow_logo, BMPWIDTH_pictureflow_logo, BMPHEIGHT_pictureflow_logo},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct config_data {
|
||||||
|
long avg_album_width;
|
||||||
|
int spacing_between_slides;
|
||||||
|
int extra_spacing_for_center_slide;
|
||||||
|
int show_slides;
|
||||||
|
};
|
||||||
|
|
||||||
/** below we allocate the memory we want to use **/
|
/** below we allocate the memory we want to use **/
|
||||||
|
|
||||||
|
@ -162,15 +170,14 @@ static fb_data *buffer; /* for now it always points to the lcd framebuffer */
|
||||||
static PFreal rays[BUFFER_WIDTH];
|
static PFreal rays[BUFFER_WIDTH];
|
||||||
static bool animation_is_active; /* an animation is currently running */
|
static bool animation_is_active; /* an animation is currently running */
|
||||||
static struct slide_data center_slide;
|
static struct slide_data center_slide;
|
||||||
static struct slide_data left_slides[LEFT_SLIDES_COUNT];
|
static struct slide_data left_slides[MAX_SLIDES_COUNT];
|
||||||
static struct slide_data right_slides[RIGHT_SLIDES_COUNT];
|
static struct slide_data right_slides[MAX_SLIDES_COUNT];
|
||||||
static int slide_frame;
|
static int slide_frame;
|
||||||
static int step;
|
static int step;
|
||||||
static int target;
|
static int target;
|
||||||
static int fade;
|
static int fade;
|
||||||
static int center_index; /* index of the slide that is in the center */
|
static int center_index; /* index of the slide that is in the center */
|
||||||
static int itilt;
|
static int itilt;
|
||||||
static int spacing; /* spacing between slides */
|
|
||||||
static int zoom;
|
static int zoom;
|
||||||
static PFreal offsetX;
|
static PFreal offsetX;
|
||||||
static PFreal offsetY;
|
static PFreal offsetY;
|
||||||
|
@ -204,6 +211,7 @@ static fb_data *input_bmp_buffer;
|
||||||
static fb_data *output_bmp_buffer;
|
static fb_data *output_bmp_buffer;
|
||||||
static int input_hid;
|
static int input_hid;
|
||||||
static int output_hid;
|
static int output_hid;
|
||||||
|
static struct config_data config;
|
||||||
|
|
||||||
static bool thread_is_running;
|
static bool thread_is_running;
|
||||||
|
|
||||||
|
@ -343,7 +351,7 @@ PFreal sinTable[] = { /* 10 */
|
||||||
/** code */
|
/** code */
|
||||||
|
|
||||||
|
|
||||||
bool create_bmp(struct bitmap* input_bmp, char *target_path);
|
bool create_bmp(struct bitmap* input_bmp, char *target_path, bool resize);
|
||||||
int load_surface(int);
|
int load_surface(int);
|
||||||
|
|
||||||
/* There are some precision issues when not using (long long) which in turn
|
/* There are some precision issues when not using (long long) which in turn
|
||||||
|
@ -386,6 +394,7 @@ static inline PFreal fdiv(PFreal n, PFreal m)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
inline PFreal fsin(int iangle)
|
inline PFreal fsin(int iangle)
|
||||||
{
|
{
|
||||||
while (iangle < 0)
|
while (iangle < 0)
|
||||||
|
@ -569,15 +578,12 @@ bool free_buffers(void)
|
||||||
*/
|
*/
|
||||||
bool create_albumart_cache(bool force)
|
bool create_albumart_cache(bool force)
|
||||||
{
|
{
|
||||||
/* FIXME: currently we check for the file CACHE_PREFIX/ready
|
|
||||||
We need a real menu etc. to recreate cache. For now, delete
|
|
||||||
the file to recreate the cache. */
|
|
||||||
|
|
||||||
number_of_slides = album_count;
|
number_of_slides = album_count;
|
||||||
|
int fh,ret;
|
||||||
|
|
||||||
if ( ! force && rb->file_exists( CACHE_PREFIX "/ready" ) ) return true;
|
if ( ! force && rb->file_exists( CACHE_PREFIX "/ready" ) ) return true;
|
||||||
|
|
||||||
int i;
|
int i, slides = 0;
|
||||||
struct bitmap input_bmp;
|
struct bitmap input_bmp;
|
||||||
|
|
||||||
for (i=0; i < album_count; i++)
|
for (i=0; i < album_count; i++)
|
||||||
|
@ -586,7 +592,6 @@ bool create_albumart_cache(bool force)
|
||||||
if (!get_albumart_for_index_from_db(i, tmp_path_name, MAX_PATH))
|
if (!get_albumart_for_index_from_db(i, tmp_path_name, MAX_PATH))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int ret;
|
|
||||||
input_bmp.data = (char *)input_bmp_buffer;
|
input_bmp.data = (char *)input_bmp_buffer;
|
||||||
ret = rb->read_bmp_file(tmp_path_name, &input_bmp,
|
ret = rb->read_bmp_file(tmp_path_name, &input_bmp,
|
||||||
sizeof(fb_data)*MAX_IMG_WIDTH*MAX_IMG_HEIGHT,
|
sizeof(fb_data)*MAX_IMG_WIDTH*MAX_IMG_HEIGHT,
|
||||||
|
@ -596,13 +601,21 @@ bool create_albumart_cache(bool force)
|
||||||
continue; /* skip missing/broken files */
|
continue; /* skip missing/broken files */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw", i);
|
rb->snprintf(tmp_path_name, sizeof(tmp_path_name), CACHE_PREFIX "/%d.pfraw", i);
|
||||||
if (!create_bmp(&input_bmp, tmp_path_name)) {
|
if (!create_bmp(&input_bmp, tmp_path_name, false)) {
|
||||||
rb->splash(HZ, "couldn't write bmp");
|
rb->splash(HZ, "couldn't write bmp");
|
||||||
}
|
}
|
||||||
|
config.avg_album_width += input_bmp.width;
|
||||||
|
slides++;
|
||||||
if ( rb->button_get(false) == PICTUREFLOW_MENU ) return false;
|
if ( rb->button_get(false) == PICTUREFLOW_MENU ) return false;
|
||||||
}
|
}
|
||||||
int fh = rb->creat( CACHE_PREFIX "/ready" );
|
config.avg_album_width /= slides;
|
||||||
|
if ( config.avg_album_width == 0 ) {
|
||||||
|
rb->splash(HZ, "album size is 0");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fh = rb->creat( CACHE_PREFIX "/ready" );
|
||||||
rb->close(fh);
|
rb->close(fh);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -847,25 +860,38 @@ int read_pfraw(char* filename)
|
||||||
Create the slide with it's reflection for the given slide_index and filename
|
Create the slide with it's 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 create_bmp(struct bitmap *input_bmp, char *target_path, bool resize)
|
||||||
{
|
{
|
||||||
fb_data *src = (fb_data *)input_bmp->data;
|
|
||||||
struct bitmap output_bmp;
|
struct bitmap output_bmp;
|
||||||
|
|
||||||
output_bmp.width = input_bmp->width * 2;
|
|
||||||
output_bmp.height = input_bmp->height;
|
|
||||||
output_bmp.format = input_bmp->format;
|
output_bmp.format = input_bmp->format;
|
||||||
output_bmp.data = (char *)output_bmp_buffer;
|
output_bmp.data = (char *)output_bmp_buffer;
|
||||||
|
if ( resize ) { /* resize image and swap buffers */
|
||||||
|
output_bmp.width = config.avg_album_width;
|
||||||
|
output_bmp.height = config.avg_album_width;
|
||||||
|
simple_resize_bitmap(input_bmp, &output_bmp);
|
||||||
|
input_bmp->data = output_bmp.data;
|
||||||
|
input_bmp->width = output_bmp.width;
|
||||||
|
input_bmp->height = output_bmp.height;
|
||||||
|
output_bmp.data = (char *)input_bmp_buffer;
|
||||||
|
output_bmp.width = input_bmp->width * 2;
|
||||||
|
output_bmp.height = input_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;
|
||||||
|
|
||||||
/* 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 = input_bmp->width / 3;
|
||||||
rb->memset(output_bmp_buffer, 0, sizeof(fb_data) * output_bmp.width * output_bmp.height);
|
rb->memset(dst, 0, sizeof(fb_data) * 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++)
|
||||||
output_bmp_buffer[output_bmp.width * x + (hofs + y)] =
|
dst[output_bmp.width * x + (hofs + y)] =
|
||||||
src[y * input_bmp->width + x];
|
src[y * input_bmp->width + x];
|
||||||
|
|
||||||
/* create the reflection */
|
/* create the reflection */
|
||||||
|
@ -877,7 +903,7 @@ bool create_bmp(struct bitmap *input_bmp, char *target_path)
|
||||||
int r = RGB_UNPACK_RED(color) * (hte - y) / hte * 3 / 5;
|
int r = RGB_UNPACK_RED(color) * (hte - y) / hte * 3 / 5;
|
||||||
int g = RGB_UNPACK_GREEN(color) * (hte - y) / hte * 3 / 5;
|
int g = RGB_UNPACK_GREEN(color) * (hte - y) / hte * 3 / 5;
|
||||||
int b = RGB_UNPACK_BLUE(color) * (hte - y) / hte * 3 / 5;
|
int b = RGB_UNPACK_BLUE(color) * (hte - y) / hte * 3 / 5;
|
||||||
output_bmp_buffer[output_bmp.height + hofs + y + output_bmp.width * x] =
|
dst[output_bmp.height + hofs + y + output_bmp.width * x] =
|
||||||
LCD_RGBPACK(r, g, b);
|
LCD_RGBPACK(r, g, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -988,18 +1014,18 @@ void reset_slides(void)
|
||||||
center_slide.slide_index = center_index;
|
center_slide.slide_index = center_index;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < LEFT_SLIDES_COUNT; i++) {
|
for (i = 0; i < config.show_slides; i++) {
|
||||||
struct slide_data *si = &left_slides[i];
|
struct slide_data *si = &left_slides[i];
|
||||||
si->angle = itilt;
|
si->angle = itilt;
|
||||||
si->cx = -(offsetX + spacing * i * PFREAL_ONE);
|
si->cx = -(offsetX + config.spacing_between_slides * i * PFREAL_ONE);
|
||||||
si->cy = offsetY;
|
si->cy = offsetY;
|
||||||
si->slide_index = center_index - 1 - i;
|
si->slide_index = center_index - 1 - i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < RIGHT_SLIDES_COUNT; i++) {
|
for (i = 0; i < config.show_slides; i++) {
|
||||||
struct slide_data *si = &right_slides[i];
|
struct slide_data *si = &right_slides[i];
|
||||||
si->angle = -itilt;
|
si->angle = -itilt;
|
||||||
si->cx = offsetX + spacing * i * PFREAL_ONE;
|
si->cx = offsetX + config.spacing_between_slides * i * PFREAL_ONE;
|
||||||
si->cy = offsetY;
|
si->cy = offsetY;
|
||||||
si->slide_index = center_index + 1 + i;
|
si->slide_index = center_index + 1 + i;
|
||||||
}
|
}
|
||||||
|
@ -1023,11 +1049,11 @@ void recalc_table(void)
|
||||||
|
|
||||||
itilt = 70 * IANGLE_MAX / 360; /* approx. 70 degrees tilted */
|
itilt = 70 * IANGLE_MAX / 360; /* approx. 70 degrees tilted */
|
||||||
|
|
||||||
offsetX = PREFERRED_IMG_WIDTH / 2 * (PFREAL_ONE - fcos(itilt));
|
offsetX = config.avg_album_width / 2 * (PFREAL_ONE - fcos(itilt));
|
||||||
offsetY = PREFERRED_IMG_HEIGHT / 2 * fsin(itilt);
|
offsetY = config.avg_album_width / 2 * fsin(itilt);
|
||||||
offsetX += PREFERRED_IMG_WIDTH * PFREAL_ONE;
|
offsetX += config.avg_album_width * PFREAL_ONE;
|
||||||
offsetY += PREFERRED_IMG_HEIGHT * PFREAL_ONE / 4;
|
offsetY += config.avg_album_width * PFREAL_ONE / 4;
|
||||||
spacing = 40;
|
offsetX += config.extra_spacing_for_center_slide << PFREAL_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1236,8 +1262,8 @@ void render(void)
|
||||||
rb->lcd_set_background(LCD_RGBPACK(0,0,0));
|
rb->lcd_set_background(LCD_RGBPACK(0,0,0));
|
||||||
rb->lcd_clear_display(); /* TODO: Optimizes this by e.g. invalidating rects */
|
rb->lcd_clear_display(); /* TODO: Optimizes this by e.g. invalidating rects */
|
||||||
|
|
||||||
int nleft = LEFT_SLIDES_COUNT;
|
int nleft = config.show_slides;
|
||||||
int nright = RIGHT_SLIDES_COUNT;
|
int nright = config.show_slides;
|
||||||
|
|
||||||
struct rect r;
|
struct rect r;
|
||||||
render_slide(¢er_slide, &r, 256, -1, -1);
|
render_slide(¢er_slide, &r, 256, -1, -1);
|
||||||
|
@ -1271,6 +1297,7 @@ void render(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if ( step < 0 ) c1 = BUFFER_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;
|
||||||
|
@ -1289,6 +1316,7 @@ void render(void)
|
||||||
c1 = r.left;
|
c1 = r.left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( step > 0 ) c2 = 0;
|
||||||
for (index = 0; index < nright; index++) {
|
for (index = 0; index < nright; index++) {
|
||||||
int alpha = (index < nright - 2) ? 256 : 128;
|
int alpha = (index < nright - 2) ? 256 : 128;
|
||||||
if (index == nright - 1)
|
if (index == nright - 1)
|
||||||
|
@ -1354,9 +1382,9 @@ void update_animation(void)
|
||||||
center_index = index;
|
center_index = index;
|
||||||
slide_frame = index << 16;
|
slide_frame = index << 16;
|
||||||
center_slide.slide_index = center_index;
|
center_slide.slide_index = center_index;
|
||||||
for (i = 0; i < LEFT_SLIDES_COUNT; i++)
|
for (i = 0; i < config.show_slides; i++)
|
||||||
left_slides[i].slide_index = center_index - 1 - i;
|
left_slides[i].slide_index = center_index - 1 - i;
|
||||||
for (i = 0; i < RIGHT_SLIDES_COUNT; i++)
|
for (i = 0; i < config.show_slides; i++)
|
||||||
right_slides[i].slide_index = center_index + 1 + i;
|
right_slides[i].slide_index = center_index + 1 + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1372,19 +1400,19 @@ void update_animation(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < LEFT_SLIDES_COUNT; i++) {
|
for (i = 0; i < config.show_slides; i++) {
|
||||||
struct slide_data *si = &left_slides[i];
|
struct slide_data *si = &left_slides[i];
|
||||||
si->angle = itilt;
|
si->angle = itilt;
|
||||||
si->cx =
|
si->cx =
|
||||||
-(offsetX + spacing * i * PFREAL_ONE + step * spacing * ftick);
|
-(offsetX + config.spacing_between_slides * i * PFREAL_ONE + step * config.spacing_between_slides * ftick);
|
||||||
si->cy = offsetY;
|
si->cy = offsetY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < RIGHT_SLIDES_COUNT; i++) {
|
for (i = 0; i < config.show_slides; i++) {
|
||||||
struct slide_data *si = &right_slides[i];
|
struct slide_data *si = &right_slides[i];
|
||||||
si->angle = -itilt;
|
si->angle = -itilt;
|
||||||
si->cx =
|
si->cx =
|
||||||
offsetX + spacing * i * PFREAL_ONE - step * spacing * ftick;
|
offsetX + config.spacing_between_slides * i * PFREAL_ONE - step * config.spacing_between_slides * ftick;
|
||||||
si->cy = offsetY;
|
si->cy = offsetY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1438,9 +1466,8 @@ int create_empty_slide(bool force)
|
||||||
input_bmp.width = BMPWIDTH_pictureflow_emptyslide;
|
input_bmp.width = BMPWIDTH_pictureflow_emptyslide;
|
||||||
input_bmp.height = BMPHEIGHT_pictureflow_emptyslide;
|
input_bmp.height = BMPHEIGHT_pictureflow_emptyslide;
|
||||||
input_bmp.format = FORMAT_NATIVE;
|
input_bmp.format = FORMAT_NATIVE;
|
||||||
DEBUGF("The empty slide is %d x %d\n", input_bmp.width, input_bmp.height);
|
|
||||||
input_bmp.data = (char*) &pictureflow_emptyslide;
|
input_bmp.data = (char*) &pictureflow_emptyslide;
|
||||||
if ( ! create_bmp(&input_bmp, EMPTY_SLIDE) ) return false;
|
if ( ! create_bmp(&input_bmp, EMPTY_SLIDE, true) ) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
empty_slide_hid = read_pfraw( EMPTY_SLIDE );
|
empty_slide_hid = read_pfraw( EMPTY_SLIDE );
|
||||||
|
@ -1456,30 +1483,54 @@ int create_empty_slide(bool force)
|
||||||
int settings_menu(void) {
|
int settings_menu(void) {
|
||||||
int selection = 0;
|
int selection = 0;
|
||||||
|
|
||||||
MENUITEM_STRINGLIST(settings_menu,"PictureFlow Settings",NULL,"Show FPS", "Rebuild cache");
|
MENUITEM_STRINGLIST(settings_menu,"PictureFlow Settings",NULL,"Show FPS", "Spacing", "Center margin", "Number of slides", "Rebuild cache");
|
||||||
|
|
||||||
selection=rb->do_menu(&settings_menu,&selection);
|
do {
|
||||||
switch(selection) {
|
selection=rb->do_menu(&settings_menu,&selection);
|
||||||
case 0:
|
switch(selection) {
|
||||||
rb->set_bool("Show FPS", &show_fps);
|
case 0:
|
||||||
break;
|
rb->set_bool("Show FPS", &show_fps);
|
||||||
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
rb->remove(CACHE_PREFIX "/ready");
|
rb->set_int("Spacing between slides", "", 1, &(config.spacing_between_slides),
|
||||||
rb->remove(EMPTY_SLIDE);
|
NULL, 1, 0, 100, NULL );
|
||||||
rb->splash(HZ, "Cache will be rebuilt on next restart");
|
recalc_table();
|
||||||
break;
|
reset_slides();
|
||||||
|
break;
|
||||||
|
|
||||||
case MENU_ATTACHED_USB:
|
case 2:
|
||||||
return PLUGIN_USB_CONNECTED;
|
rb->set_int("Center margin", "", 1, &(config.extra_spacing_for_center_slide),
|
||||||
}
|
NULL, 1, -50, 50, NULL );
|
||||||
|
recalc_table();
|
||||||
|
reset_slides();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
rb->set_int("Number of slides", "", 1, &(config.show_slides),
|
||||||
|
NULL, 1, 1, MAX_SLIDES_COUNT, NULL );
|
||||||
|
recalc_table();
|
||||||
|
reset_slides();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
rb->remove(CACHE_PREFIX "/ready");
|
||||||
|
rb->remove(EMPTY_SLIDE);
|
||||||
|
rb->splash(HZ, "Cache will be rebuilt on next restart");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MENU_ATTACHED_USB:
|
||||||
|
return PLUGIN_USB_CONNECTED;
|
||||||
|
}
|
||||||
|
} while ( selection >= 0 );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Show the main menu
|
Show the main menu
|
||||||
*/
|
*/
|
||||||
int main_menu(void) {
|
int main_menu(void)
|
||||||
|
{
|
||||||
int selection = 0;
|
int selection = 0;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -1510,6 +1561,30 @@ int main_menu(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool read_pfconfig(void)
|
||||||
|
{
|
||||||
|
/* defaults */
|
||||||
|
config.spacing_between_slides = 40;
|
||||||
|
config.extra_spacing_for_center_slide = 0;
|
||||||
|
config.show_slides = 3;
|
||||||
|
int fh = rb->open( CONFIG_FILE, O_RDONLY );
|
||||||
|
if ( fh < 0 ) { /* no config yet */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int ret = rb->read(fh, &config, sizeof(struct config_data));
|
||||||
|
rb->close(fh);
|
||||||
|
return ( ret == sizeof(struct config_data) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write_pfconfig(void)
|
||||||
|
{
|
||||||
|
int fh = rb->creat( CONFIG_FILE );
|
||||||
|
if( fh < 0 ) return false;
|
||||||
|
rb->write( fh, &config, sizeof( struct config_data ) );
|
||||||
|
rb->close( fh );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Main function that also contain the main plasma
|
Main function that also contain the main plasma
|
||||||
algorithm.
|
algorithm.
|
||||||
|
@ -1526,13 +1601,13 @@ int main(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allocate_buffers()) {
|
if (!read_pfconfig()) {
|
||||||
rb->splash(HZ, "Could not allocate temporary buffers");
|
rb->splash(HZ, "Error in config. Please delete " CONFIG_FILE);
|
||||||
return PLUGIN_ERROR;
|
return PLUGIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!create_empty_slide(false)) {
|
if (!allocate_buffers()) {
|
||||||
rb->splash(HZ, "Could not load the empty slide");
|
rb->splash(HZ, "Could not allocate temporary buffers");
|
||||||
return PLUGIN_ERROR;
|
return PLUGIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1545,11 +1620,16 @@ int main(void)
|
||||||
return PLUGIN_ERROR;
|
return PLUGIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!create_albumart_cache(false)) {
|
if (!create_albumart_cache(config.avg_album_width == 0)) {
|
||||||
rb->splash(HZ, "Could not create album art cache");
|
rb->splash(HZ, "Could not create album art cache");
|
||||||
return PLUGIN_ERROR;
|
return PLUGIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!create_empty_slide(false)) {
|
||||||
|
rb->splash(HZ, "Could not load the empty slide");
|
||||||
|
return PLUGIN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!free_buffers()) {
|
if (!free_buffers()) {
|
||||||
rb->splash(HZ, "Could not free temporary buffers");
|
rb->splash(HZ, "Could not free temporary buffers");
|
||||||
return PLUGIN_ERROR;
|
return PLUGIN_ERROR;
|
||||||
|
@ -1563,12 +1643,13 @@ int main(void)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* initialize */
|
/* initialize */
|
||||||
for (i = 0; i < SLIDE_CACHE_SIZE; i++) {
|
int min_slide_cache = fmin(number_of_slides, SLIDE_CACHE_SIZE);
|
||||||
|
for (i = 0; i < min_slide_cache; i++) {
|
||||||
cache[i].hid = -1;
|
cache[i].hid = -1;
|
||||||
cache[i].touched = 0;
|
cache[i].touched = 0;
|
||||||
slide_cache_stack[i] = SLIDE_CACHE_SIZE-i-1;
|
slide_cache_stack[i] = SLIDE_CACHE_SIZE-i-1;
|
||||||
}
|
}
|
||||||
slide_cache_stack_index = SLIDE_CACHE_SIZE-2;
|
slide_cache_stack_index = min_slide_cache-1;
|
||||||
slide_cache_in_use = 0;
|
slide_cache_in_use = 0;
|
||||||
buffer = rb->lcd_framebuffer;
|
buffer = rb->lcd_framebuffer;
|
||||||
animation_is_active = false;
|
animation_is_active = false;
|
||||||
|
@ -1676,6 +1757,8 @@ int main(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************** Plugin entry point ****************************/
|
/*************************** Plugin entry point ****************************/
|
||||||
|
@ -1692,6 +1775,13 @@ enum plugin_status plugin_start(struct plugin_api *api, void *parameter)
|
||||||
/* Turn off backlight timeout */
|
/* Turn off backlight timeout */
|
||||||
backlight_force_on(rb); /* backlight control in lib/helper.c */
|
backlight_force_on(rb); /* backlight control in lib/helper.c */
|
||||||
ret = main();
|
ret = main();
|
||||||
|
if ( ret == PLUGIN_OK ) {
|
||||||
|
if (!write_pfconfig()) {
|
||||||
|
rb->splash(HZ, "Error writing config.");
|
||||||
|
return PLUGIN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end_pf_thread();
|
end_pf_thread();
|
||||||
cleanup(NULL);
|
cleanup(NULL);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
127
apps/plugins/resize_test.c
Normal file
127
apps/plugins/resize_test.c
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Jonas Hurrelmann
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Resizing test plugin. Loads /test.bmp (max 100x100) and displays a resized
|
||||||
|
* version. Use the scrollwheel or the left/right keys to change the size of
|
||||||
|
* the resizded version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin.h"
|
||||||
|
#include "pluginlib_actions.h"
|
||||||
|
#include "bmp.h"
|
||||||
|
|
||||||
|
PLUGIN_HEADER
|
||||||
|
|
||||||
|
static struct plugin_api* rb;
|
||||||
|
|
||||||
|
const struct button_mapping *plugin_contexts[]
|
||||||
|
= {generic_actions, generic_directions};
|
||||||
|
|
||||||
|
#define NB_ACTION_CONTEXTS sizeof(plugin_contexts)/sizeof(plugin_contexts[0])
|
||||||
|
|
||||||
|
/* Key assignement */
|
||||||
|
#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) \
|
||||||
|
|| (CONFIG_KEYPAD == IPOD_3G_PAD) \
|
||||||
|
|| (CONFIG_KEYPAD == IPOD_4G_PAD) \
|
||||||
|
|| (CONFIG_KEYPAD == SANSA_E200_PAD)
|
||||||
|
#define SIZE_INCREASE PLA_UP
|
||||||
|
#define SIZE_INCREASE_REPEAT PLA_UP_REPEAT
|
||||||
|
#define SIZE_DECREASE PLA_DOWN
|
||||||
|
#define SIZE_DECREASE_REPEAT PLA_DOWN_REPEAT
|
||||||
|
#else
|
||||||
|
#define SIZE_INCREASE PLA_RIGHT
|
||||||
|
#define SIZE_INCREASE_REPEAT PLA_RIGHT_REPEAT
|
||||||
|
#define SIZE_DECREASE PLA_LEFT
|
||||||
|
#define SIZE_DECREASE_REPEAT PLA_LEFT_REPEAT
|
||||||
|
#endif
|
||||||
|
#define BUTTON_QUIT PLA_QUIT
|
||||||
|
|
||||||
|
#define MAX_OUTPUT_WIDTH 200
|
||||||
|
#define MAX_OUTPUT_HEIGHT 200
|
||||||
|
|
||||||
|
static fb_data *b;
|
||||||
|
|
||||||
|
static struct bitmap input_bmp;
|
||||||
|
static struct bitmap output_bmp;
|
||||||
|
|
||||||
|
static fb_data input_bmp_data[100*100];
|
||||||
|
static fb_data output_bmp_data[MAX_OUTPUT_WIDTH*MAX_OUTPUT_HEIGHT];
|
||||||
|
|
||||||
|
|
||||||
|
/* this is the plugin entry point */
|
||||||
|
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
|
{
|
||||||
|
(void)parameter;
|
||||||
|
|
||||||
|
rb = api;
|
||||||
|
b = rb->lcd_framebuffer;
|
||||||
|
|
||||||
|
rb->lcd_set_background(LCD_RGBPACK(0,0,0));
|
||||||
|
rb->lcd_clear_display(); // TODO: Optimizes this by e.g. invalidating rects
|
||||||
|
|
||||||
|
input_bmp.data = (char*)input_bmp_data;
|
||||||
|
output_bmp.data = (char*)output_bmp_data;
|
||||||
|
|
||||||
|
int ret = rb->read_bmp_file("/test.bmp", &input_bmp, sizeof(input_bmp_data),
|
||||||
|
FORMAT_NATIVE);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
rb->splash(HZ, "Could not load /test.bmp");
|
||||||
|
return PLUGIN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int button;
|
||||||
|
output_bmp.width = 50;
|
||||||
|
output_bmp.height = 50;
|
||||||
|
|
||||||
|
DEBUGF("input_bmp_data starts at %p\n", input_bmp_data);
|
||||||
|
DEBUGF("output_bmp_data starts at %p\n", output_bmp_data);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
rb->lcd_clear_display();
|
||||||
|
rb->lcd_bitmap(input_bmp_data, 0, 0, input_bmp.width, input_bmp.height);
|
||||||
|
|
||||||
|
simple_resize_bitmap(&input_bmp, &output_bmp);
|
||||||
|
|
||||||
|
rb->lcd_bitmap(output_bmp_data, 0, 100, output_bmp.width,
|
||||||
|
output_bmp.height);
|
||||||
|
|
||||||
|
rb->lcd_update();
|
||||||
|
button = pluginlib_getaction(rb, HZ,
|
||||||
|
plugin_contexts, NB_ACTION_CONTEXTS);
|
||||||
|
switch (button) {
|
||||||
|
case BUTTON_QUIT:
|
||||||
|
return PLUGIN_OK;
|
||||||
|
case SIZE_INCREASE:
|
||||||
|
case SIZE_INCREASE_REPEAT:
|
||||||
|
if (output_bmp.width < MAX_OUTPUT_WIDTH - 2)
|
||||||
|
output_bmp.width += 2;
|
||||||
|
if (output_bmp.height < MAX_OUTPUT_HEIGHT - 2)
|
||||||
|
output_bmp.height += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIZE_DECREASE:
|
||||||
|
case SIZE_DECREASE_REPEAT:
|
||||||
|
if (output_bmp.width >= 2) output_bmp.width -= 2;
|
||||||
|
if (output_bmp.height >= 2) output_bmp.height -= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PLUGIN_OK;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue