202f9df0c1
putting a framebuffer on the stack is never a good idea Added comments Change-Id: I5553050785b74cb847db03957c6377cab11e816c
259 lines
7.3 KiB
C
259 lines
7.3 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2007 Dave Chapman
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "plugin.h"
|
|
|
|
#ifdef HAVE_LCD_COLOR
|
|
#define BGCOLOR_1 LCD_RGBPACK(255,255,0)
|
|
#define BGCOLOR_2 LCD_RGBPACK(0,255,0)
|
|
#define FGCOLOR_1 LCD_RGBPACK(0,0,255)
|
|
#elif LCD_DEPTH > 1
|
|
#define BGCOLOR_1 LCD_DARKGRAY
|
|
#define BGCOLOR_2 LCD_LIGHTGRAY
|
|
#define FGCOLOR_1 LCD_WHITE
|
|
#endif
|
|
|
|
static struct viewport vp0 =
|
|
{
|
|
.x = 0,
|
|
.y = 0,
|
|
.width = LCD_WIDTH/ 2 + LCD_WIDTH / 3,
|
|
.height = 20,
|
|
.font = FONT_UI,
|
|
.drawmode = DRMODE_SOLID,
|
|
#if LCD_DEPTH > 1
|
|
.fg_pattern = LCD_DEFAULT_FG,
|
|
.bg_pattern = BGCOLOR_1,
|
|
#endif
|
|
};
|
|
|
|
static struct viewport vp1 =
|
|
{
|
|
.x = LCD_WIDTH / 10,
|
|
.y = 20,
|
|
.width = LCD_WIDTH / 3,
|
|
.height = LCD_HEIGHT / 2,
|
|
.font = FONT_SYSFIXED,
|
|
.drawmode = DRMODE_SOLID,
|
|
#if LCD_DEPTH > 1
|
|
.fg_pattern = LCD_DEFAULT_FG,
|
|
.bg_pattern = LCD_DEFAULT_BG,
|
|
#endif
|
|
};
|
|
|
|
static struct viewport vp2 =
|
|
{
|
|
.x = LCD_WIDTH / 2,
|
|
.y = 40,
|
|
.width = LCD_WIDTH / 3,
|
|
.height = (LCD_HEIGHT / 2),
|
|
.font = FONT_UI,
|
|
.drawmode = DRMODE_SOLID,
|
|
#if LCD_DEPTH > 1
|
|
.fg_pattern = FGCOLOR_1,
|
|
.bg_pattern = BGCOLOR_2,
|
|
#endif
|
|
};
|
|
|
|
|
|
static struct viewport vp3 =
|
|
{
|
|
.x = LCD_WIDTH / 4,
|
|
.y = (5 * LCD_HEIGHT) / 8,
|
|
.width = LCD_WIDTH / 2,
|
|
.height = (LCD_HEIGHT / 4),
|
|
.font = FONT_SYSFIXED,
|
|
.drawmode = DRMODE_SOLID,
|
|
#if LCD_DEPTH > 1
|
|
.fg_pattern = LCD_BLACK,
|
|
.bg_pattern = LCD_WHITE,
|
|
#endif
|
|
};
|
|
|
|
|
|
#ifdef HAVE_REMOTE_LCD
|
|
static struct viewport rvp0 =
|
|
{
|
|
.x = 0,
|
|
.y = 10,
|
|
.width = LCD_REMOTE_WIDTH / 3,
|
|
.height = LCD_REMOTE_HEIGHT - 10,
|
|
.font = FONT_SYSFIXED,
|
|
.drawmode = DRMODE_SOLID,
|
|
#if LCD_REMOTE_DEPTH > 1
|
|
.fg_pattern = LCD_REMOTE_BLACK,
|
|
.bg_pattern = LCD_REMOTE_LIGHTGRAY,
|
|
#endif
|
|
};
|
|
|
|
static struct viewport rvp1 =
|
|
{
|
|
.x = LCD_REMOTE_WIDTH / 2,
|
|
.y = 0,
|
|
.width = LCD_REMOTE_WIDTH / 3,
|
|
.height = LCD_REMOTE_HEIGHT - 10,
|
|
.font = FONT_SYSFIXED,
|
|
.drawmode = DRMODE_SOLID,
|
|
#if LCD_REMOTE_DEPTH > 1
|
|
.fg_pattern = LCD_REMOTE_DEFAULT_FG,
|
|
.bg_pattern = LCD_REMOTE_DEFAULT_BG
|
|
#endif
|
|
};
|
|
|
|
#endif
|
|
|
|
static void *test_address_fn(int x, int y)
|
|
{
|
|
/* Address lookup function
|
|
* core will use this to get an address from x/y coord
|
|
* depending on the lcd function core sometimes uses this for
|
|
* only the first and last address
|
|
* and handles subsequent address based on stride */
|
|
|
|
struct frame_buffer_t *fb = vp0.buffer;
|
|
/* LCD_STRIDEFORMAT & LCD_NATIVE_STRIDE macros allow Horiz screens to work with RB */
|
|
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
|
|
size_t element = (x * LCD_NATIVE_STRIDE(fb->stride)) + y;
|
|
#else
|
|
size_t element = (y * LCD_NATIVE_STRIDE(fb->stride)) + x;
|
|
#endif
|
|
/* use mod fb->elems to protect from buffer ovfl */
|
|
return fb->fb_ptr + (element % fb->elems);
|
|
}
|
|
|
|
enum plugin_status plugin_start(const void* parameter)
|
|
{
|
|
(void)parameter;
|
|
char buf[80];
|
|
int i,y;
|
|
|
|
size_t plugin_buf_len;
|
|
void* plugin_buf = (unsigned char *)rb->plugin_get_buffer(&plugin_buf_len);
|
|
|
|
/* Here we will test if viewports of non standard size work with the rb core */
|
|
struct frame_buffer_t fb;
|
|
|
|
rb->font_getstringsize("W", NULL, &vp0.height, vp0.font);
|
|
fb.elems = LCD_NBELEMS(vp0.width, vp0.height);
|
|
|
|
/* set stride based on the with or height of our buffer (macro picks the proper one) */
|
|
fb.stride = STRIDE_MAIN(vp0.width, vp0.height);
|
|
|
|
/*set the framebuffer pointer to our buffer (union - pick appropriate data type) */
|
|
fb.data = plugin_buf;
|
|
/* Valid data types for fb union
|
|
void* - data
|
|
char* - ch_ptr,
|
|
fb_data* - fb_ptr,
|
|
fb_remote_data - fb_remote_ptr;
|
|
*/
|
|
if (fb.elems * sizeof(fb_data) > plugin_buf_len)
|
|
return PLUGIN_ERROR;
|
|
|
|
plugin_buf += fb.elems * sizeof(fb_data);
|
|
plugin_buf_len -= fb.elems * sizeof(fb_data); /* buffer bookkeeping */
|
|
|
|
/* set a frame buffer address lookup function */
|
|
fb.get_address_fn = &test_address_fn;
|
|
|
|
/* set our newly built buffer to the viewport */
|
|
rb->viewport_set_buffer(&vp0, &fb, SCREEN_MAIN);
|
|
|
|
rb->screens[SCREEN_MAIN]->set_viewport(&vp0);
|
|
rb->screens[SCREEN_MAIN]->clear_viewport();
|
|
|
|
rb->screens[SCREEN_MAIN]->puts_scroll(0,0,"Viewport testing plugin - this is a scrolling title");
|
|
|
|
rb->screens[SCREEN_MAIN]->set_viewport(&vp1);
|
|
rb->screens[SCREEN_MAIN]->clear_viewport();
|
|
|
|
for (i = 0 ; i < 3; i++)
|
|
{
|
|
rb->snprintf(buf,sizeof(buf),"Left text, scrolling_line %d",i);
|
|
rb->screens[SCREEN_MAIN]->puts_scroll(0,i,buf);
|
|
}
|
|
|
|
rb->screens[SCREEN_MAIN]->set_viewport(&vp2);
|
|
rb->screens[SCREEN_MAIN]->clear_viewport();
|
|
for (i = 1 ; i < 3; i++)
|
|
{
|
|
rb->snprintf(buf,sizeof(buf),"Right text, scrolling line %d",i);
|
|
rb->screens[SCREEN_MAIN]->puts_scroll(1,i,buf);
|
|
}
|
|
|
|
y = -10;
|
|
for (i = -10; i < vp2.width + 10; i += 5)
|
|
{
|
|
rb->screens[SCREEN_MAIN]->drawline(i, y, i, vp2.height - y);
|
|
}
|
|
|
|
rb->screens[SCREEN_MAIN]->set_viewport(&vp3);
|
|
rb->screens[SCREEN_MAIN]->clear_viewport();
|
|
for (i = 1 ; i < 2; i++)
|
|
{
|
|
rb->snprintf(buf,sizeof(buf),"Bottom text, a scrolling line %d",i);
|
|
rb->screens[SCREEN_MAIN]->puts_scroll(2,i,buf);
|
|
}
|
|
rb->screens[SCREEN_MAIN]->puts_scroll(4,i,"Short line");
|
|
rb->screens[SCREEN_MAIN]->update();
|
|
|
|
|
|
#ifdef HAVE_REMOTE_LCD
|
|
rb->screens[SCREEN_REMOTE]->set_viewport(&rvp0);
|
|
rb->screens[SCREEN_REMOTE]->clear_viewport();
|
|
|
|
for (i = 0 ; i < 5; i++)
|
|
{
|
|
rb->snprintf(buf,sizeof(buf),"Left text, scrolling_line %d",i);
|
|
rb->screens[SCREEN_REMOTE]->puts_scroll(0,i,buf);
|
|
}
|
|
rb->screens[SCREEN_REMOTE]->puts(1,i,"Static");
|
|
|
|
rb->screens[SCREEN_REMOTE]->set_viewport(&rvp1);
|
|
rb->screens[SCREEN_REMOTE]->clear_viewport();
|
|
for (i = 1 ; i < 3; i++)
|
|
{
|
|
rb->snprintf(buf,sizeof(buf),"Right text, scrolling line %d",i);
|
|
rb->screens[SCREEN_REMOTE]->puts_scroll(1,i,buf);
|
|
}
|
|
|
|
y = -10;
|
|
for (i = -10; i < rvp1.width + 10; i += 5)
|
|
{
|
|
rb->screens[SCREEN_REMOTE]->drawline(i, y, i, rvp1.height - y);
|
|
}
|
|
|
|
rb->screens[SCREEN_REMOTE]->update();
|
|
#endif
|
|
rb->button_clear_queue();
|
|
while(rb->button_get(true) <= BUTTON_NONE)
|
|
;;
|
|
|
|
rb->button_get(true);
|
|
|
|
/* Restore the default viewport */
|
|
rb->screens[SCREEN_MAIN]->set_viewport(NULL);
|
|
#ifdef HAVE_REMOTE_LCD
|
|
rb->screens[SCREEN_REMOTE]->set_viewport(NULL);
|
|
#endif
|
|
|
|
return PLUGIN_OK;
|
|
}
|