summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2020-10-07 02:01:35 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2020-10-26 12:28:48 -0400
commit3237ae4a4ff9296a377ff9194a11038da161208f (patch)
treeaf4338c78467b9b0845d76c39da1fbe10f25e23e /firmware
parent12f3ed1699d6bef25bed90ba95cbcc1a6bb4934a (diff)
downloadrockbox-3237ae4a4ff9296a377ff9194a11038da161208f.tar.gz
rockbox-3237ae4a4ff9296a377ff9194a11038da161208f.zip
LCD core move buf ptr and address look up function viewport struct
I'm currently running up against the limitations of the lcd_draw functions I want these functions to be able to be used on any size buffer not just buffers with a stride matching the underlying device [DONE] allow the framebuffer to be decoupled from the device framebuffer [DONE need examples] allow for some simple blit like transformations [DONE] remove the device framebuffer from the plugin api [DONE}ditto remote framebuffer [DONE] remove _viewport_get_framebuffer you can call struct *vp = lcd_set_viewport(NULL) and vp->buffer->fb_ptr while remote lcds may compile (and work in the sim) its not been tested on targets [FIXED] backdrops need work to be screen agnostic [FIXED] screen statusbar is not being combined into the main viewport correctly yet [FIXED] screen elements are displayed incorrectly after switch to void* [FIXED] core didn't restore proper viewport on splash etc. [NEEDS TESTING] remote lcd garbled data [FIXED] osd lib garbled screen on bmp_part [FIXED] grey_set_vp needs to return old viewport like lcd_set_viewport [FIXED] Viewport update now handles viewports with differing buffers/strides by copying to the main buffer [FIXED] splash on top of WPS leaves old framebuffer data (doesn't redraw) [UPDATE] refined this a bit more to have clear_viewport set the clean bit and have skin_render do its own screen clear scrolling viewports no longer trigger wps refresh also fixed a bug where guisyncyesno was displaying and then disappearing [ADDED!] New LCD macros that allow you to create properly size frame buffers in you desired size without wasting bytes (LCD_ and LCD_REMOTE_) LCD_STRIDE(w, h) same as STRIDE_MAIN LCD_FBSTRIDE(w, h) returns target specific stride for a buffer W x H LCD_NBELEMS(w, h) returns the number of fb_data sized elemenst needed for a buffer W x H LCD_NATIVE_STRIDE(s) conversion between rockbox native vertical and lcd native stride (2bitH) test_viewports.c has an example of usage [FIXED!!] 2bit targets don't respect non-native strides [FIXED] Few define snags Change-Id: I0d04c3834e464eca84a5a715743a297a0cefd0af
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/lcd-16bit-common.c112
-rw-r--r--firmware/drivers/lcd-16bit-vert.c98
-rw-r--r--firmware/drivers/lcd-16bit.c93
-rw-r--r--firmware/drivers/lcd-1bit-vert.c176
-rw-r--r--firmware/drivers/lcd-24bit.c180
-rw-r--r--firmware/drivers/lcd-2bit-horz.c215
-rw-r--r--firmware/drivers/lcd-2bit-vert.c210
-rw-r--r--firmware/drivers/lcd-2bit-vi.c202
-rw-r--r--firmware/drivers/lcd-bitmap-common.c166
-rw-r--r--firmware/drivers/lcd-color-common.c95
-rw-r--r--firmware/drivers/lcd-scroll.c8
-rw-r--r--firmware/export/lcd-remote.h74
-rw-r--r--firmware/export/lcd.h271
-rw-r--r--firmware/target/arm/as3525/lcd-fuze.c2
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c2
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c4
-rw-r--r--firmware/target/coldfire/iriver/h300/lcd-h300.c2
-rw-r--r--firmware/target/coldfire/mpio/hd200/lcd-hd200.c2
-rw-r--r--firmware/target/hosted/android/lcd-android.c4
-rw-r--r--firmware/target/hosted/sdl/lcd-sdl.c2
20 files changed, 1123 insertions, 795 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c
index a7e80c7244..7c766dab8a 100644
--- a/firmware/drivers/lcd-16bit-common.c
+++ b/firmware/drivers/lcd-16bit-common.c
@@ -35,10 +35,10 @@ void lcd_clear_viewport(void)
int x, y, width, height;
int len, step;
- x = current_vp->x;
- y = current_vp->y;
- width = current_vp->width;
- height = current_vp->height;
+ x = lcd_current_viewport->x;
+ y = lcd_current_viewport->y;
+ width = lcd_current_viewport->width;
+ height = lcd_current_viewport->height;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -70,11 +70,11 @@ void lcd_clear_viewport(void)
dst = FBADDR(x, y);
dst_end = FBADDR(x + width - 1 , y + height - 1);
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
do
{
- memset16(dst, current_vp->fg_pattern, len);
+ memset16(dst, lcd_current_viewport->fg_pattern, len);
dst += step;
}
while (dst <= dst_end);
@@ -85,7 +85,7 @@ void lcd_clear_viewport(void)
{
do
{
- memset16(dst, current_vp->bg_pattern, len);
+ memset16(dst, lcd_current_viewport->bg_pattern, len);
dst += step;
}
while (dst <= dst_end);
@@ -102,22 +102,24 @@ void lcd_clear_viewport(void)
}
}
- if (current_vp == &default_vp)
+ if (lcd_current_viewport == &default_vp)
lcd_scroll_stop();
else
- lcd_scroll_stop_viewport(current_vp);
+ lcd_scroll_stop_viewport(lcd_current_viewport);
+
+ lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN);
}
/*** low-level drawing functions ***/
static void ICODE_ATTR setpixel(fb_data *address)
{
- *address = current_vp->fg_pattern;
+ *address = lcd_current_viewport->fg_pattern;
}
static void ICODE_ATTR clearpixel(fb_data *address)
{
- *address = current_vp->bg_pattern;
+ *address = lcd_current_viewport->bg_pattern;
}
static void ICODE_ATTR clearimgpixel(fb_data *address)
@@ -157,8 +159,8 @@ void lcd_fillrect(int x, int y, int width, int height)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -171,14 +173,14 @@ void lcd_fillrect(int x, int y, int width, int height)
height += y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -205,14 +207,14 @@ void lcd_fillrect(int x, int y, int width, int height)
#endif
/* drawmode and optimisation */
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
- if (current_vp->drawmode & DRMODE_BG)
+ if (lcd_current_viewport->drawmode & DRMODE_BG)
{
if (!lcd_backdrop)
{
fillopt = OPT_SET;
- bits = current_vp->bg_pattern;
+ bits = lcd_current_viewport->bg_pattern;
}
else
fillopt = OPT_COPY;
@@ -220,13 +222,13 @@ void lcd_fillrect(int x, int y, int width, int height)
}
else
{
- if (current_vp->drawmode & DRMODE_FG)
+ if (lcd_current_viewport->drawmode & DRMODE_FG)
{
fillopt = OPT_SET;
- bits = current_vp->fg_pattern;
+ bits = lcd_current_viewport->fg_pattern;
}
}
- if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
+ if (fillopt == OPT_NONE && lcd_current_viewport->drawmode != DRMODE_COMPLEMENT)
return;
dst = FBADDR(x, y);
@@ -284,13 +286,13 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
const unsigned char *src_end;
fb_data *dst, *dst_col;
unsigned dmask = 0x100; /* bit 8 == sentinel */
- int drmode = current_vp->drawmode;
+ int drmode = lcd_current_viewport->drawmode;
int row;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -305,14 +307,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -404,7 +406,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
break;
case DRMODE_BG:
- bg = current_vp->bg_pattern;
+ bg = lcd_current_viewport->bg_pattern;
do
{
if (!(data & 0x01))
@@ -417,7 +419,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
break;
case DRMODE_FG:
- fg = current_vp->fg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
do
{
if (data & 0x01)
@@ -430,7 +432,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
break;
case DRMODE_SOLID|DRMODE_INT_BD:
- fg = current_vp->fg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
bo = lcd_backdrop_offset;
do
{
@@ -443,8 +445,8 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
break;
case DRMODE_SOLID:
- fg = current_vp->fg_pattern;
- bg = current_vp->bg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
+ bg = lcd_current_viewport->bg_pattern;
do
{
*dst = (data & 0x01) ? fg : bg;
@@ -549,10 +551,10 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
{
fb_data *dst, *dst_row;
unsigned dmask = 0x00000000;
- int drmode = current_vp->drawmode;
+ int drmode = lcd_current_viewport->drawmode;
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
/* initialize blending */
BLEND_INIT;
@@ -570,14 +572,14 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -668,7 +670,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
/* go through the rows and update each pixel */
do
{
- /* saving current_vp->fg/bg_pattern and lcd_backdrop_offset into these
+ /* saving lcd_current_viewport->fg/bg_pattern and lcd_backdrop_offset into these
* temp vars just before the loop helps gcc to opimize the loop better
* (testing showed ~15% speedup) */
unsigned fg, bg;
@@ -727,7 +729,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
while (--col);
break;
case DRMODE_BG:
- bg = current_vp->bg_pattern;
+ bg = lcd_current_viewport->bg_pattern;
do
{
*dst = blend_two_colors(bg, *dst, data & ALPHA_COLOR_LOOKUP_SIZE );
@@ -747,7 +749,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
while (--col);
break;
case DRMODE_FG:
- fg = current_vp->fg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
do
{
*dst = blend_two_colors(*dst, fg, data & ALPHA_COLOR_LOOKUP_SIZE );
@@ -758,7 +760,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
break;
case DRMODE_SOLID|DRMODE_INT_BD:
bo = lcd_backdrop_offset;
- fg = current_vp->fg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
do
{
fb_data *c = (fb_data *)((uintptr_t)dst + bo);
@@ -769,7 +771,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
while (--col);
break;
case DRMODE_SOLID|DRMODE_INT_IMG:
- bg = current_vp->bg_pattern;
+ bg = lcd_current_viewport->bg_pattern;
img_offset = image - dst;
do
{
@@ -792,8 +794,8 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
while (--col);
break;
case DRMODE_SOLID:
- bg = current_vp->bg_pattern;
- fg = current_vp->fg_pattern;
+ bg = lcd_current_viewport->bg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
do
{
*dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE );
diff --git a/firmware/drivers/lcd-16bit-vert.c b/firmware/drivers/lcd-16bit-vert.c
index ffe2b85b3c..b336e78c78 100644
--- a/firmware/drivers/lcd-16bit-vert.c
+++ b/firmware/drivers/lcd-16bit-vert.c
@@ -39,7 +39,7 @@
#include "scroll_engine.h"
#define ROW_INC 1
-#define COL_INC LCD_HEIGHT
+#define COL_INC lcd_current_viewport->buffer->stride
extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[];
extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_bgcolor[];
@@ -61,7 +61,9 @@ void lcd_hline(int x1, int x2, int y)
{
int x;
fb_data *dst, *dst_end;
- lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
+ int stride_dst;
+
+ lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode];
/* direction flip */
if (x2 < x1)
@@ -73,20 +75,20 @@ void lcd_hline(int x1, int x2, int y)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)y >= (unsigned)current_vp->height) ||
- (x1 >= current_vp->width) ||
+ if (((unsigned)y >= (unsigned)lcd_current_viewport->height) ||
+ (x1 >= lcd_current_viewport->width) ||
(x2 < 0))
return;
if (x1 < 0)
x1 = 0;
- if (x2 >= current_vp->width)
- x2 = current_vp->width-1;
+ if (x2 >= lcd_current_viewport->width)
+ x2 = lcd_current_viewport->width-1;
/* Adjust x1 and y to viewport */
- x1 += current_vp->x;
- x2 += current_vp->x;
- y += current_vp->y;
+ x1 += lcd_current_viewport->x;
+ x2 += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -103,12 +105,13 @@ void lcd_hline(int x1, int x2, int y)
#endif
dst = FBADDR(x1 , y );
- dst_end = dst + (x2 - x1) * LCD_HEIGHT;
+ stride_dst = lcd_current_viewport->buffer->stride;
+ dst_end = dst + (x2 - x1) * stride_dst;
do
{
pfunc(dst);
- dst += LCD_HEIGHT;
+ dst += stride_dst;
}
while (dst <= dst_end);
}
@@ -131,20 +134,20 @@ void lcd_vline(int x, int y1, int y2)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)x >= (unsigned)current_vp->width) ||
- (y1 >= current_vp->height) ||
+ if (((unsigned)x >= (unsigned)lcd_current_viewport->width) ||
+ (y1 >= lcd_current_viewport->height) ||
(y2 < 0))
return;
if (y1 < 0)
y1 = 0;
- if (y2 >= current_vp->height)
- y2 = current_vp->height-1;
+ if (y2 >= lcd_current_viewport->height)
+ y2 = lcd_current_viewport->height-1;
/* adjust for viewport */
- x += current_vp->x;
- y1 += current_vp->y;
- y2 += current_vp->y;
+ x += lcd_current_viewport->x;
+ y1 += lcd_current_viewport->y;
+ y2 += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -163,14 +166,14 @@ void lcd_vline(int x, int y1, int y2)
height = y2 - y1 + 1;
/* drawmode and optimisation */
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
- if (current_vp->drawmode & DRMODE_BG)
+ if (lcd_current_viewport->drawmode & DRMODE_BG)
{
if (!lcd_backdrop)
{
fillopt = OPT_SET;
- bits = current_vp->bg_pattern;
+ bits = lcd_current_viewport->bg_pattern;
}
else
fillopt = OPT_COPY;
@@ -178,13 +181,13 @@ void lcd_vline(int x, int y1, int y2)
}
else
{
- if (current_vp->drawmode & DRMODE_FG)
+ if (lcd_current_viewport->drawmode & DRMODE_FG)
{
fillopt = OPT_SET;
- bits = current_vp->fg_pattern;
+ bits = lcd_current_viewport->fg_pattern;
}
}
- if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
+ if (fillopt == OPT_NONE && lcd_current_viewport->drawmode != DRMODE_COMPLEMENT)
return;
dst = FBADDR(x, y1);
@@ -215,11 +218,11 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
int height)
{
fb_data *dst;
-
+ int stride_dst;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -235,14 +238,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -272,13 +275,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
src += stride * src_x + src_y; /* move starting point */
dst = FBADDR(x, y);
- fb_data *dst_end = dst + width * LCD_HEIGHT;
+ stride_dst = lcd_current_viewport->buffer->stride;
+ fb_data *dst_end = dst + width * stride_dst;
do
{
memcpy(dst, src, height * sizeof(fb_data));
src += stride;
- dst += LCD_HEIGHT;
+ dst += stride_dst;
}
while (dst < dst_end);
}
@@ -289,11 +293,12 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
int y, int width, int height)
{
fb_data *dst, *dst_end;
+ int stride_dst;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -309,14 +314,14 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -346,7 +351,8 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
src += stride * src_x + src_y; /* move starting point */
dst = FBADDR(x, y);
- dst_end = dst + width * LCD_HEIGHT;
+ stride_dst = lcd_current_viewport->buffer->stride;
+ dst_end = dst + width * stride_dst;
do
{
@@ -354,12 +360,12 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
for(i = 0;i < height;i++)
{
if (src[i] == REPLACEWITHFG_COLOR)
- dst[i] = current_vp->fg_pattern;
+ dst[i] = lcd_current_viewport->fg_pattern;
else if(src[i] != TRANSPARENT_COLOR)
dst[i] = src[i];
}
src += stride;
- dst += LCD_HEIGHT;
+ dst += stride_dst;
}
while (dst < dst_end);
}
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index b792be4e02..03c50f8ebf 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -38,7 +38,7 @@
#include "bidi.h"
#include "scroll_engine.h"
-#define ROW_INC LCD_WIDTH
+#define ROW_INC lcd_current_viewport->buffer->stride
#define COL_INC 1
extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[];
@@ -74,20 +74,20 @@ void lcd_hline(int x1, int x2, int y)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)y >= (unsigned)current_vp->height) ||
- (x1 >= current_vp->width) ||
+ if (((unsigned)y >= (unsigned)lcd_current_viewport->height) ||
+ (x1 >= lcd_current_viewport->width) ||
(x2 < 0))
return;
if (x1 < 0)
x1 = 0;
- if (x2 >= current_vp->width)
- x2 = current_vp->width-1;
+ if (x2 >= lcd_current_viewport->width)
+ x2 = lcd_current_viewport->width-1;
/* Adjust x1 and y to viewport */
- x1 += current_vp->x;
- x2 += current_vp->x;
- y += current_vp->y;
+ x1 += lcd_current_viewport->x;
+ x2 += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -106,14 +106,14 @@ void lcd_hline(int x1, int x2, int y)
width = x2 - x1 + 1;
/* drawmode and optimisation */
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
- if (current_vp->drawmode & DRMODE_BG)
+ if (lcd_current_viewport->drawmode & DRMODE_BG)
{
if (!lcd_backdrop)
{
fillopt = OPT_SET;
- bits = current_vp->bg_pattern;
+ bits = lcd_current_viewport->bg_pattern;
}
else
fillopt = OPT_COPY;
@@ -121,13 +121,13 @@ void lcd_hline(int x1, int x2, int y)
}
else
{
- if (current_vp->drawmode & DRMODE_FG)
+ if (lcd_current_viewport->drawmode & DRMODE_FG)
{
fillopt = OPT_SET;
- bits = current_vp->fg_pattern;
+ bits = lcd_current_viewport->fg_pattern;
}
}
- if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
+ if (fillopt == OPT_NONE && lcd_current_viewport->drawmode != DRMODE_COMPLEMENT)
return;
dst = FBADDR(x1, y);
@@ -157,7 +157,8 @@ void lcd_vline(int x, int y1, int y2)
{
int y;
fb_data *dst, *dst_end;
- lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
+ int stride_dst;
+ lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode];
/* direction flip */
if (y2 < y1)
@@ -169,20 +170,20 @@ void lcd_vline(int x, int y1, int y2)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)x >= (unsigned)current_vp->width) ||
- (y1 >= current_vp->height) ||
+ if (((unsigned)x >= (unsigned)lcd_current_viewport->width) ||
+ (y1 >= lcd_current_viewport->height) ||
(y2 < 0))
return;
if (y1 < 0)
y1 = 0;
- if (y2 >= current_vp->height)
- y2 = current_vp->height-1;
+ if (y2 >= lcd_current_viewport->height)
+ y2 = lcd_current_viewport->height-1;
/* adjust for viewport */
- x += current_vp->x;
- y1 += current_vp->y;
- y2 += current_vp->y;
+ x += lcd_current_viewport->x;
+ y1 += lcd_current_viewport->y;
+ y2 += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -199,12 +200,13 @@ void lcd_vline(int x, int y1, int y2)
#endif
dst = FBADDR(x , y1);
- dst_end = dst + (y2 - y1) * LCD_WIDTH;
+ stride_dst = lcd_current_viewport->buffer->stride;
+ dst_end = dst + (y2 - y1) * stride_dst;
do
{
pfunc(dst);
- dst += LCD_WIDTH;
+ dst += stride_dst;
}
while (dst <= dst_end);
}
@@ -215,11 +217,12 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
int height)
{
fb_data *dst;
+ int stride_dst;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -235,14 +238,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -272,12 +275,13 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
src += stride * src_y + src_x; /* move starting point */
dst = FBADDR(x, y);
+ stride_dst = lcd_current_viewport->buffer->stride;
do
{
memcpy(dst, src, width * sizeof(fb_data));
src += stride;
- dst += LCD_WIDTH;
+ dst += stride_dst;
}
while (--height > 0);
}
@@ -288,12 +292,13 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
int y, int width, int height)
{
fb_data *dst;
- unsigned fg = current_vp->fg_pattern;
+ unsigned fg = lcd_current_viewport->fg_pattern;
+ int stride_dst = lcd_current_viewport->buffer->stride;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -309,14 +314,14 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -371,7 +376,7 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
[s]"+&r"(src), [d]"+&r"(dst)
: [width]"r"(width),
[sstp]"r"(stride - width),
- [dstp]"r"(LCD_WIDTH - width),
+ [dstp]"r"(stride_dst - width),
[transcolor]"r"(TRANSPARENT_COLOR),
[fgcolor]"r"(REPLACEWITHFG_COLOR),
[fgpat]"r"(fg)
@@ -395,7 +400,7 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
}
while (++dst_row < row_end);
src += stride;
- dst += LCD_WIDTH;
+ dst += stride_dst;
}
while (--height > 0);
#endif
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c
index 668c685187..57abdb91a6 100644
--- a/firmware/drivers/lcd-1bit-vert.c
+++ b/firmware/drivers/lcd-1bit-vert.c
@@ -44,9 +44,26 @@
#define MAIN_LCD
#endif
+#ifdef MAIN_LCD
+#define THIS_STRIDE STRIDE_MAIN
+#else
+#define THIS_STRIDE STRIDE_REMOTE
+#endif
+
+#define CURRENT_VP LCDFN(current_viewport)
/*** globals ***/
-FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER;
-FBFN(data) *LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0];
+static FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER;
+
+static void *LCDFN(frameaddress_default)(int x, int y);
+
+/* shouldn't be changed unless you want system-wide framebuffer changes! */
+struct frame_buffer_t LCDFN(framebuffer_default) =
+{
+ .FBFN(ptr) = &LCDFN(static_framebuffer)[0][0],
+ .get_address_fn = &LCDFN(frameaddress_default),
+ .stride = THIS_STRIDE(LCDM(WIDTH), LCDM(HEIGHT)),
+ .elems = (LCDM(FBWIDTH)*LCDM(FBHEIGHT)),
+};
static struct viewport default_vp =
{
@@ -56,55 +73,73 @@ static struct viewport default_vp =
.height = LCDM(HEIGHT),
.font = FONT_SYSFIXED,
.drawmode = DRMODE_SOLID,
+ .buffer = NULL,
};
-static struct viewport* current_vp = &default_vp;
+struct viewport* CURRENT_VP;
+
+static void *LCDFN(frameaddress_default)(int x, int y)
+{
+ /* the default expects a buffer the same size as the screen */
+ struct frame_buffer_t *fb = CURRENT_VP->buffer;
+#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
+ size_t element = (x * LCDM(NATIVE_STRIDE)(fb->stride)) + y;
+#else
+ size_t element = (y * LCDM(NATIVE_STRIDE)(fb->stride)) + x;
+#endif
+
+ return fb->FBFN(ptr) + element;/*(element % fb->elems);*/
+}
/* LCD init */
void LCDFN(init)(void)
{
+
+ /* Initialize the viewport */
+ LCDFN(set_viewport)(NULL);
LCDFN(clear_display)();
LCDFN(init_device)();
#ifdef MAIN_LCD
scroll_init();
#endif
+
}
/*** parameter handling ***/
void LCDFN(set_drawmode)(int mode)
{
- current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
+ CURRENT_VP->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
}
int LCDFN(get_drawmode)(void)
{
- return current_vp->drawmode;
+ return CURRENT_VP->drawmode;
}
int LCDFN(getwidth)(void)
{
- return current_vp->width;
+ return CURRENT_VP->width;
}
int LCDFN(getheight)(void)
{
- return current_vp->height;
+ return CURRENT_VP->height;
}
void LCDFN(setfont)(int newfont)
{
- current_vp->font = newfont;
+ CURRENT_VP->font = newfont;
}
int LCDFN(getfont)(void)
{
- return current_vp->font;
+ return CURRENT_VP->font;
}
int LCDFN(getstringsize)(const unsigned char *str, int *w, int *h)
{
- return font_getstringsize(str, w, h, current_vp->font);
+ return font_getstringsize(str, w, h, CURRENT_VP->font);
}
/*** low-level drawing functions ***/
@@ -134,7 +169,7 @@ LCDFN(pixelfunc_type)* const LCDFN(pixelfuncs)[8] = {
flippixel, nopixel, setpixel, setpixel,
nopixel, clearpixel, nopixel, clearpixel
};
-
+
static void ICODE_ATTR flipblock(FBFN(data) *address, unsigned mask,
unsigned bits)
{
@@ -199,9 +234,9 @@ LCDFN(blockfunc_type)* const LCDFN(blockfuncs)[8] = {
/* Clear the whole display */
void LCDFN(clear_display)(void)
{
- unsigned bits = (current_vp->drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0;
+ unsigned bits = (CURRENT_VP->drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0;
- memset(LCDFN(framebuffer), bits, FBSIZE);
+ memset(LCDFB(0, 0), bits, FBSIZE);
LCDFN(scroll_info).lines = 0;
}
@@ -210,37 +245,40 @@ void LCDFN(clear_viewport)(void)
{
int oldmode;
- if (current_vp == &default_vp)
+ if (CURRENT_VP == &default_vp &&
+ default_vp.buffer == &LCDFN(framebuffer_default))
{
LCDFN(clear_display)();
}
else
{
- oldmode = current_vp->drawmode;
+ oldmode = CURRENT_VP->drawmode;
/* Invert the INVERSEVID bit and set basic mode to SOLID */
- current_vp->drawmode = (~current_vp->drawmode & DRMODE_INVERSEVID) |
+ CURRENT_VP->drawmode = (~CURRENT_VP->drawmode & DRMODE_INVERSEVID) |
DRMODE_SOLID;
- LCDFN(fillrect)(0, 0, current_vp->width, current_vp->height);
+ LCDFN(fillrect)(0, 0, CURRENT_VP->width, CURRENT_VP->height);
- current_vp->drawmode = oldmode;
+ CURRENT_VP->drawmode = oldmode;
- LCDFN(scroll_stop_viewport)(current_vp);
+ LCDFN(scroll_stop_viewport)(CURRENT_VP);
}
+
+ CURRENT_VP->flags &= ~(VP_FLAG_VP_SET_CLEAN);
}
/* Set a single pixel */
void LCDFN(drawpixel)(int x, int y)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)CURRENT_VP->width)
+ && ((unsigned)y < (unsigned)CURRENT_VP->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCDM(WIDTH))
&& ((unsigned)y < (unsigned)LCDM(HEIGHT))
#endif
)
- LCDFN(pixelfuncs)[current_vp->drawmode](current_vp->x + x, current_vp->y + y);
+ LCDFN(pixelfuncs)[CURRENT_VP->drawmode](CURRENT_VP->x + x, CURRENT_VP->y + y);
}
/* Draw a line */
@@ -252,7 +290,7 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2)
int d, dinc1, dinc2;
int x, xinc1, xinc2;
int y, yinc1, yinc2;
- LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[current_vp->drawmode];
+ LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode];
deltax = abs(x2 - x1);
if (deltax == 0)
@@ -308,14 +346,14 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2)
for (i = 0; i < numpixels; i++)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)CURRENT_VP->width)
+ && ((unsigned)y < (unsigned)CURRENT_VP->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCDM(WIDTH))
&& ((unsigned)y < (unsigned)LCDM(HEIGHT))
#endif
)
- pfunc(current_vp->x + x, current_vp->y + y);
+ pfunc(CURRENT_VP->x + x, CURRENT_VP->y + y);
if (d < 0)
{
@@ -350,19 +388,19 @@ void LCDFN(hline)(int x1, int x2, int y)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
+ if (((unsigned)y >= (unsigned)CURRENT_VP->height) || (x1 >= CURRENT_VP->width)
|| (x2 < 0))
return;
if (x1 < 0)
x1 = 0;
- if (x2 >= current_vp->width)
- x2 = current_vp->width-1;
+ if (x2 >= CURRENT_VP->width)
+ x2 = CURRENT_VP->width-1;
/* adjust to viewport */
- x1 += current_vp->x;
- x2 += current_vp->x;
- y += current_vp->y;
+ x1 += CURRENT_VP->x;
+ x2 += CURRENT_VP->x;
+ y += CURRENT_VP->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -380,7 +418,7 @@ void LCDFN(hline)(int x1, int x2, int y)
width = x2 - x1 + 1;
- bfunc = LCDFN(blockfuncs)[current_vp->drawmode];
+ bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
dst = LCDFB(x1,y>>3);
mask = BIT_N(y & 7);
@@ -395,6 +433,7 @@ void LCDFN(vline)(int x, int y1, int y2)
{
int ny;
FBFN(data) *dst;
+ int stride_dst;
unsigned mask, mask_bottom;
LCDFN(blockfunc_type) *bfunc;
@@ -408,19 +447,19 @@ void LCDFN(vline)(int x, int y1, int y2)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
+ if (((unsigned)x >= (unsigned)CURRENT_VP->width) || (y1 >= CURRENT_VP->height)
|| (y2 < 0))
return;
if (y1 < 0)
y1 = 0;
- if (y2 >= current_vp->height)
- y2 = current_vp->height-1;
+ if (y2 >= CURRENT_VP->height)
+ y2 = CURRENT_VP->height-1;
/* adjust for viewport */
- y1 += current_vp->y;
- y2 += current_vp->y;
- x += current_vp->x;
+ y1 += CURRENT_VP->y;
+ y2 += CURRENT_VP->y;
+ x += CURRENT_VP->x;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -436,16 +475,17 @@ void LCDFN(vline)(int x, int y1, int y2)
y2 = LCDM(HEIGHT)-1;
#endif
- bfunc = LCDFN(blockfuncs)[current_vp->drawmode];
+ bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
dst = LCDFB(x,y1>>3);
ny = y2 - (y1 & ~7);
mask = 0xFFu << (y1 & 7);
mask_bottom = 0xFFu >> (~ny & 7);
+ stride_dst = CURRENT_VP->buffer->stride;
for (; ny >= 8; ny -= 8)
{
bfunc(dst, mask, 0xFFu);
- dst += LCDM(WIDTH);
+ dst += stride_dst;
mask = 0xFFu;
}
mask &= mask_bottom;
@@ -472,6 +512,7 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
{
int ny;
FBFN(data) *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_bottom;
unsigned bits = 0;
LCDFN(blockfunc_type) *bfunc;
@@ -479,8 +520,8 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
- || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width)
+ || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -493,14 +534,14 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
height += y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > CURRENT_VP->width)
+ width = CURRENT_VP->width - x;
+ if (y + height > CURRENT_VP->height)
+ height = CURRENT_VP->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += CURRENT_VP->x;
+ y += CURRENT_VP->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -526,26 +567,27 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
height = LCDM(HEIGHT) - y;
#endif
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (CURRENT_VP->drawmode & DRMODE_INVERSEVID)
{
- if (current_vp->drawmode & DRMODE_BG)
+ if (CURRENT_VP->drawmode & DRMODE_BG)
{
fillopt = true;
}
}
else
{
- if (current_vp->drawmode & DRMODE_FG)
+ if (CURRENT_VP->drawmode & DRMODE_FG)
{
fillopt = true;
bits = 0xFFu;
}
}
- bfunc = LCDFN(blockfuncs)[current_vp->drawmode];
+ bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
dst = LCDFB(x,y>>3);
ny = height - 1 + (y & 7);
mask = 0xFFu << (y & 7);
mask_bottom = 0xFFu >> (~ny & 7);
+ stride_dst = CURRENT_VP->buffer->stride;
for (; ny >= 8; ny -= 8)
{
@@ -561,7 +603,7 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
while (dst_row < dst_end);
}
- dst += LCDM(WIDTH);
+ dst += stride_dst;
mask = 0xFFu;
}
mask &= mask_bottom;
@@ -595,13 +637,14 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x,
{
int shift, ny;
FBFN(data) *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_bottom;
LCDFN(blockfunc_type) *bfunc;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
- || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width)
+ || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0))
return;
/* clip image in viewport */
@@ -617,14 +660,14 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > CURRENT_VP->width)
+ width = CURRENT_VP->width - x;
+ if (y + height > CURRENT_VP->height)
+ height = CURRENT_VP->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += CURRENT_VP->x;
+ y += CURRENT_VP->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -656,16 +699,17 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x,
src_y &= 7;
y -= src_y;
dst = LCDFB(x,y>>3);
+ stride_dst = CURRENT_VP->buffer->stride;
shift = y & 7;
ny = height - 1 + shift + src_y;
- bfunc = LCDFN(blockfuncs)[current_vp->drawmode];
+ bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
mask = 0xFFu << (shift + src_y);
mask_bottom = 0xFFu >> (~ny & 7);
if (shift == 0)
{
- bool copyopt = (current_vp->drawmode == DRMODE_SOLID);
+ bool copyopt = (CURRENT_VP->drawmode == DRMODE_SOLID);
for (; ny >= 8; ny -= 8)
{
@@ -683,7 +727,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x,
}
src += stride;
- dst += LCDM(WIDTH);
+ dst += stride_dst;
mask = 0xFFu;
}
mask &= mask_bottom;
@@ -721,7 +765,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x,
mask_col >>= 8;
src_col += stride;
- dst_col += LCDM(WIDTH);
+ dst_col += stride_dst;
data >>= 8;
}
data |= *src_col << shift;
diff --git a/firmware/drivers/lcd-24bit.c b/firmware/drivers/lcd-24bit.c
index 8820e632d4..65fa01f37f 100644
--- a/firmware/drivers/lcd-24bit.c
+++ b/firmware/drivers/lcd-24bit.c
@@ -39,7 +39,7 @@
#include "bidi.h"
#include "scroll_engine.h"
-#define ROW_INC LCD_WIDTH
+#define ROW_INC lcd_current_viewport->buffer->stride
#define COL_INC 1
extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[];
@@ -62,10 +62,10 @@ void lcd_clear_viewport(void)
int x, y, width, height;
int len, step;
- x = current_vp->x;
- y = current_vp->y;
- width = current_vp->width;
- height = current_vp->height;
+ x = lcd_current_viewport->x;
+ y = lcd_current_viewport->y;
+ width = lcd_current_viewport->width;
+ height = lcd_current_viewport->height;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -97,9 +97,9 @@ void lcd_clear_viewport(void)
dst = FBADDR(x, y);
dst_end = FBADDR(x + width - 1 , y + height - 1);
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
- fb_data px = FB_SCALARPACK(current_vp->fg_pattern);
+ fb_data px = FB_SCALARPACK(lcd_current_viewport->fg_pattern);
do
{
fb_data *end = dst + len;
@@ -114,7 +114,7 @@ void lcd_clear_viewport(void)
{
if (!lcd_backdrop)
{
- fb_data px = FB_SCALARPACK(current_vp->bg_pattern);
+ fb_data px = FB_SCALARPACK(lcd_current_viewport->bg_pattern);
do
{
fb_data *end = dst + len;
@@ -137,22 +137,24 @@ void lcd_clear_viewport(void)
}
}
- if (current_vp == &default_vp)
+ if (lcd_current_viewport == &default_vp)
lcd_scroll_stop();
else
- lcd_scroll_stop_viewport(current_vp);
+ lcd_scroll_stop_viewport(lcd_current_viewport);
+
+ lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN);
}
/*** low-level drawing functions ***/
static void ICODE_ATTR setpixel(fb_data *address)
{
- *address = FB_SCALARPACK(current_vp->fg_pattern);
+ *address = FB_SCALARPACK(lcd_current_viewport->fg_pattern);
}
static void ICODE_ATTR clearpixel(fb_data *address)
{
- *address = FB_SCALARPACK(current_vp->bg_pattern);
+ *address = FB_SCALARPACK(lcd_current_viewport->bg_pattern);
}
static void ICODE_ATTR clearimgpixel(fb_data *address)
@@ -194,8 +196,8 @@ void lcd_fillrect(int x, int y, int width, int height)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -208,14 +210,14 @@ void lcd_fillrect(int x, int y, int width, int height)
height += y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -242,14 +244,14 @@ void lcd_fillrect(int x, int y, int width, int height)
#endif
/* drawmode and optimisation */
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
- if (current_vp->drawmode & DRMODE_BG)
+ if (lcd_current_viewport->drawmode & DRMODE_BG)
{
if (!lcd_backdrop)
{
fillopt = OPT_SET;
- bits = FB_SCALARPACK(current_vp->bg_pattern);
+ bits = FB_SCALARPACK(lcd_current_viewport->bg_pattern);
}
else
fillopt = OPT_COPY;
@@ -257,13 +259,13 @@ void lcd_fillrect(int x, int y, int width, int height)
}
else
{
- if (current_vp->drawmode & DRMODE_FG)
+ if (lcd_current_viewport->drawmode & DRMODE_FG)
{
fillopt = OPT_SET;
- bits = FB_SCALARPACK(current_vp->fg_pattern);
+ bits = FB_SCALARPACK(lcd_current_viewport->fg_pattern);
}
}
- if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
+ if (fillopt == OPT_NONE && lcd_current_viewport->drawmode != DRMODE_COMPLEMENT)
return;
dst = FBADDR(x, y);
@@ -327,13 +329,13 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
const unsigned char *src_end;
fb_data *dst, *dst_col;
unsigned dmask = 0x100; /* bit 8 == sentinel */
- int drmode = current_vp->drawmode;
+ int drmode = lcd_current_viewport->drawmode;
int row;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -348,14 +350,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -447,7 +449,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
break;
case DRMODE_BG:
- bg = FB_SCALARPACK(current_vp->bg_pattern);
+ bg = FB_SCALARPACK(lcd_current_viewport->bg_pattern);
do
{
if (!(data & 0x01))
@@ -460,7 +462,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
break;
case DRMODE_FG:
- fg = FB_SCALARPACK(current_vp->fg_pattern);
+ fg = FB_SCALARPACK(lcd_current_viewport->fg_pattern);
do
{
if (data & 0x01)
@@ -473,7 +475,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
break;
case DRMODE_SOLID|DRMODE_INT_BD:
- fg = FB_SCALARPACK(current_vp->fg_pattern);
+ fg = FB_SCALARPACK(lcd_current_viewport->fg_pattern);
bo = lcd_backdrop_offset;
do
{
@@ -486,8 +488,8 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
break;
case DRMODE_SOLID:
- fg = FB_SCALARPACK(current_vp->fg_pattern);
- bg = FB_SCALARPACK(current_vp->bg_pattern);
+ fg = FB_SCALARPACK(lcd_current_viewport->fg_pattern);
+ bg = FB_SCALARPACK(lcd_current_viewport->bg_pattern);
do
{
*dst = (data & 0x01) ? fg : bg;
@@ -559,10 +561,10 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
{
fb_data *dst, *dst_row;
unsigned dmask = 0x00000000;
- int drmode = current_vp->drawmode;
+ int drmode = lcd_current_viewport->drawmode;
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
/* clipping */
@@ -578,14 +580,14 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -673,7 +675,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
/* go through the rows and update each pixel */
do
{
- /* saving current_vp->fg/bg_pattern and lcd_backdrop_offset into these
+ /* saving lcd_current_viewport->fg/bg_pattern and lcd_backdrop_offset into these
* temp vars just before the loop helps gcc to opimize the loop better
* (testing showed ~15% speedup) */
unsigned fg, bg;
@@ -734,7 +736,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
while (--col);
break;
case DRMODE_BG:
- bg = current_vp->bg_pattern;
+ bg = lcd_current_viewport->bg_pattern;
do
{
unsigned px = FB_UNPACK_SCALAR_LCD(*dst);
@@ -757,7 +759,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
while (--col);
break;
case DRMODE_FG:
- fg = current_vp->fg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
do
{
unsigned px = FB_UNPACK_SCALAR_LCD(*dst);
@@ -769,7 +771,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
break;
case DRMODE_SOLID|DRMODE_INT_BD:
bo = lcd_backdrop_offset;
- fg = current_vp->fg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
do
{
unsigned c = FB_UNPACK_SCALAR_LCD(*(fb_data *)((uintptr_t)dst + bo));
@@ -780,7 +782,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
while (--col);
break;
case DRMODE_SOLID|DRMODE_INT_IMG:
- bg = current_vp->bg_pattern;
+ bg = lcd_current_viewport->bg_pattern;
img_offset = image - dst;
do
{
@@ -805,8 +807,8 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
while (--col);
break;
case DRMODE_SOLID:
- bg = current_vp->bg_pattern;
- fg = current_vp->fg_pattern;
+ bg = lcd_current_viewport->bg_pattern;
+ fg = lcd_current_viewport->fg_pattern;
do
{
*dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE );
@@ -855,7 +857,7 @@ void lcd_hline(int x1, int x2, int y)
{
int x, width;
fb_data *dst, *dst_end;
- lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
+ lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode];
/* direction flip */
if (x2 < x1)
@@ -867,20 +869,20 @@ void lcd_hline(int x1, int x2, int y)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)y >= (unsigned)current_vp->height) ||
- (x1 >= current_vp->width) ||
+ if (((unsigned)y >= (unsigned)lcd_current_viewport->height) ||
+ (x1 >= lcd_current_viewport->width) ||
(x2 < 0))
return;
if (x1 < 0)
x1 = 0;
- if (x2 >= current_vp->width)
- x2 = current_vp->width-1;
+ if (x2 >= lcd_current_viewport->width)
+ x2 = lcd_current_viewport->width-1;
/* Adjust x1 and y to viewport */
- x1 += current_vp->x;
- x2 += current_vp->x;
- y += current_vp->y;
+ x1 += lcd_current_viewport->x;
+ x2 += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -912,7 +914,7 @@ void lcd_vline(int x, int y1, int y2)
{
int y;
fb_data *dst, *dst_end;
- lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
+ lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode];
/* direction flip */
if (y2 < y1)
@@ -924,20 +926,20 @@ void lcd_vline(int x, int y1, int y2)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)x >= (unsigned)current_vp->width) ||
- (y1 >= current_vp->height) ||
+ if (((unsigned)x >= (unsigned)lcd_current_viewport->width) ||
+ (y1 >= lcd_current_viewport->height) ||
(y2 < 0))
return;
if (y1 < 0)
y1 = 0;
- if (y2 >= current_vp->height)
- y2 = current_vp->height-1;
+ if (y2 >= lcd_current_viewport->height)
+ y2 = lcd_current_viewport->height-1;
/* adjust for viewport */
- x += current_vp->x;
- y1 += current_vp->y;
- y2 += current_vp->y;
+ x += lcd_current_viewport->x;
+ y1 += lcd_current_viewport->y;
+ y2 += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -973,8 +975,8 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -990,14 +992,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -1047,8 +1049,8 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -1064,14 +1066,14 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -1104,7 +1106,7 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
transparent = FB_SCALARPACK(TRANSPARENT_COLOR);
replacewithfg = FB_SCALARPACK(REPLACEWITHFG_COLOR);
- fg = FB_SCALARPACK(current_vp->fg_pattern);
+ fg = FB_SCALARPACK(lcd_current_viewport->fg_pattern);
#define CMP(c1, c2) (c1.r == c2.r && c1.g == c2.g && c1.b == c2.b)
do
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index 1d256e5f58..35a2be5b2c 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -39,8 +39,8 @@
/*** globals ***/
-unsigned char lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER;
-unsigned char *lcd_framebuffer = &lcd_static_framebuffer[0][0];
+static unsigned char lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER;
+static void *lcd_frameaddress_default(int x, int y);
static const unsigned char pixmask[4] ICONST_ATTR = {
0xC0, 0x30, 0x0C, 0x03
@@ -49,6 +49,15 @@ static const unsigned char pixmask[4] ICONST_ATTR = {
static fb_data* lcd_backdrop = NULL;
static long lcd_backdrop_offset IDATA_ATTR = 0;
+/* shouldn't be changed unless you want system-wide framebuffer changes! */
+struct frame_buffer_t lcd_framebuffer_default =
+{
+ .fb_ptr = &lcd_static_framebuffer[0][0],
+ .get_address_fn = &lcd_frameaddress_default,
+ .stride = STRIDE_MAIN(LCD_WIDTH, LCD_HEIGHT),
+ .elems = (LCD_FBWIDTH*LCD_FBHEIGHT),
+};
+
static struct viewport default_vp =
{
.x = 0,
@@ -57,18 +66,32 @@ static struct viewport default_vp =
.height = LCD_HEIGHT,
.font = FONT_SYSFIXED,
.drawmode = DRMODE_SOLID,
+ .buffer = NULL,
.fg_pattern = LCD_DEFAULT_FG,
.bg_pattern = LCD_DEFAULT_BG
};
-static struct viewport* current_vp IBSS_ATTR;
+struct viewport* lcd_current_viewport IBSS_ATTR;
static unsigned fg_pattern IBSS_ATTR;
static unsigned bg_pattern IBSS_ATTR;
+static void *lcd_frameaddress_default(int x, int y)
+{
+ /* the default expects a buffer the same size as the screen */
+ struct frame_buffer_t *fb = lcd_current_viewport->buffer;
+
+#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
+ return fb->fb_ptr + element;/*(element % fb->elems);*/
+}
+
/* LCD init */
void lcd_init(void)
{
- /* Initialise the viewport */
+ /* Initialize the viewport */
lcd_set_viewport(NULL);
lcd_clear_display();
@@ -81,34 +104,34 @@ void lcd_init(void)
void lcd_set_drawmode(int mode)
{
- current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
+ lcd_current_viewport->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
}
int lcd_get_drawmode(void)
{
- return current_vp->drawmode;
+ return lcd_current_viewport->drawmode;
}
void lcd_set_foreground(unsigned brightness)
{
- current_vp->fg_pattern = brightness;
+ lcd_current_viewport->fg_pattern = brightness;
fg_pattern = 0x55 * (~brightness & 3);
}
unsigned lcd_get_foreground(void)
{
- return current_vp->fg_pattern;
+ return lcd_current_viewport->fg_pattern;
}
void lcd_set_background(unsigned brightness)
{
- current_vp->bg_pattern = brightness;
+ lcd_current_viewport->bg_pattern = brightness;
bg_pattern = 0x55 * (~brightness & 3);
}
unsigned lcd_get_background(void)
{
- return current_vp->bg_pattern;
+ return lcd_current_viewport->bg_pattern;
}
void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
@@ -120,27 +143,27 @@ void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
int lcd_getwidth(void)
{
- return current_vp->width;
+ return lcd_current_viewport->width;
}
int lcd_getheight(void)
{
- return current_vp->height;
+ return lcd_current_viewport->height;
}
void lcd_setfont(int newfont)
{
- current_vp->font = newfont;
+ lcd_current_viewport->font = newfont;
}
int lcd_getfont(void)
{
- return current_vp->font;
+ return lcd_current_viewport->font;
}
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
{
- return font_getstringsize(str, w, h, current_vp->font);
+ return font_getstringsize(str, w, h, lcd_current_viewport->font);
}
/*** low-level drawing functions ***/
@@ -318,7 +341,7 @@ void lcd_set_backdrop(fb_data* backdrop)
lcd_backdrop = backdrop;
if (backdrop)
{
- lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer;
+ lcd_backdrop_offset = (long)backdrop - (long)FBADDR(0,0);
lcd_pixelfuncs = lcd_pixelfuncs_backdrop;
lcd_blockfuncs = lcd_blockfuncs_backdrop;
}
@@ -349,16 +372,16 @@ static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
/* Clear the whole display */
void lcd_clear_display(void)
{
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
- memset(lcd_framebuffer, fg_pattern, FRAMEBUFFER_SIZE);
+ memset(FBADDR(0,0), fg_pattern, FRAMEBUFFER_SIZE);
}
else
{
if (lcd_backdrop)
- memcpy(lcd_framebuffer, lcd_backdrop, FRAMEBUFFER_SIZE);
+ memcpy(FBADDR(0,0), lcd_backdrop, FRAMEBUFFER_SIZE);
else
- memset(lcd_framebuffer, bg_pattern, FRAMEBUFFER_SIZE);
+ memset(FBADDR(0,0), bg_pattern, FRAMEBUFFER_SIZE);
}
lcd_scroll_info.lines = 0;
@@ -369,37 +392,39 @@ void lcd_clear_viewport(void)
{
int lastmode;
- if (current_vp == &default_vp)
+ if (lcd_current_viewport == &default_vp &&
+ default_vp.buffer == &lcd_framebuffer_default)
{
lcd_clear_display();
}
else
{
- lastmode = current_vp->drawmode;
+ lastmode = lcd_current_viewport->drawmode;
/* Invert the INVERSEVID bit and set basic mode to SOLID */
- current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) |
+ lcd_current_viewport->drawmode = (~lastmode & DRMODE_INVERSEVID) |
DRMODE_SOLID;
- lcd_fillrect(0, 0, current_vp->width, current_vp->height);
+ lcd_fillrect(0, 0, lcd_current_viewport->width, lcd_current_viewport->height);
- current_vp->drawmode = lastmode;
+ lcd_current_viewport->drawmode = lastmode;
- lcd_scroll_stop_viewport(current_vp);
+ lcd_scroll_stop_viewport(lcd_current_viewport);
}
+ lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN);
}
/* Set a single pixel */
void lcd_drawpixel(int x, int y)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
+ && ((unsigned)y < (unsigned)lcd_current_viewport->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCD_WIDTH)
&& ((unsigned)y < (unsigned)LCD_HEIGHT)
#endif
)
- lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y);
+ lcd_pixelfuncs[lcd_current_viewport->drawmode](lcd_current_viewport->x + x, lcd_current_viewport->y + y);
}
/* Draw a line */
@@ -411,7 +436,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
int d, dinc1, dinc2;
int x, xinc1, xinc2;
int y, yinc1, yinc2;
- lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode];
+ lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode];
deltay = abs(y2 - y1);
if (deltay == 0)
@@ -467,14 +492,14 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
for (i = 0; i < numpixels; i++)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
+ && ((unsigned)y < (unsigned)lcd_current_viewport->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCD_WIDTH)
&& ((unsigned)y < (unsigned)LCD_HEIGHT)
#endif
)
- pfunc(current_vp->x + x, current_vp->y + y);
+ pfunc(lcd_current_viewport->x + x, lcd_current_viewport->y + y);
if (d < 0)
{
@@ -509,19 +534,19 @@ void lcd_hline(int x1, int x2, int y)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
+ if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || (x1 >= lcd_current_viewport->width)
|| (x2 < 0))
return;
if (x1 < 0)
x1 = 0;
- if (x2 >= current_vp->width)
- x2 = current_vp->width-1;
+ if (x2 >= lcd_current_viewport->width)
+ x2 = lcd_current_viewport->width-1;
/* adjust to viewport */
- x1 += current_vp->x;
- x2 += current_vp->x;
- y += current_vp->y;
+ x1 += lcd_current_viewport->x;
+ x2 += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -537,7 +562,7 @@ void lcd_hline(int x1, int x2, int y)
x2 = LCD_WIDTH-1;
#endif
- bfunc = lcd_blockfuncs[current_vp->drawmode];
+ bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
dst = FBADDR(x1>>2,y);
nx = x2 - (x1 & ~3);
mask = 0xFFu >> (2 * (x1 & 3));
@@ -557,6 +582,7 @@ void lcd_vline(int x, int y1, int y2)
{
int y;
unsigned char *dst, *dst_end;
+ int stride_dst;
unsigned mask;
lcd_blockfunc_type *bfunc;
@@ -570,19 +596,19 @@ void lcd_vline(int x, int y1, int y2)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
+ if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || (y1 >= lcd_current_viewport->height)
|| (y2 < 0))
return;
if (y1 < 0)
y1 = 0;
- if (y2 >= current_vp->height)
- y2 = current_vp->height-1;
+ if (y2 >= lcd_current_viewport->height)
+ y2 = lcd_current_viewport->height-1;
/* adjust for viewport */
- y1 += current_vp->y;
- y2 += current_vp->y;
- x += current_vp->x;
+ y1 += lcd_current_viewport->y;
+ y2 += lcd_current_viewport->y;
+ x += lcd_current_viewport->x;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -598,15 +624,16 @@ void lcd_vline(int x, int y1, int y2)
y2 = LCD_HEIGHT-1;
#endif
- bfunc = lcd_blockfuncs[current_vp->drawmode];
+ bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
dst = FBADDR(x>>2,y1);
+ stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
mask = pixmask[x & 3];
- dst_end = dst + (y2 - y1) * LCD_FBWIDTH;
+ dst_end = dst + (y2 - y1) * stride_dst;
do
{
bfunc(dst, mask, 0xFFu);
- dst += LCD_FBWIDTH;
+ dst += stride_dst;
}
while (dst <= dst_end);
}
@@ -631,12 +658,13 @@ void lcd_fillrect(int x, int y, int width, int height)
{
int nx;
unsigned char *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_right;
lcd_blockfunc_type *bfunc;
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || (y >= current_vp->height)
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || (y >= lcd_current_viewport->height)
|| (x + width <= 0) || (y + height <= 0))
return;
@@ -650,14 +678,14 @@ void lcd_fillrect(int x, int y, int width, int height)
height += y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -683,21 +711,22 @@ void lcd_fillrect(int x, int y, int width, int height)
height = LCD_HEIGHT - y;
#endif
- bfunc = lcd_blockfuncs[current_vp->drawmode];
- dst = FBADDR(x>>2,y);
- nx = width - 1 + (x & 3);
- mask = 0xFFu >> (2 * (x & 3));
+ bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
+ dst = FBADDR(x>>2,y);
+ stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
+ nx = width - 1 + (x & 3);
+ mask = 0xFFu >> (2 * (x & 3));
mask_right = 0xFFu << (2 * (~nx & 3));
for (; nx >= 4; nx -= 4)
{
unsigned char *dst_col = dst;
- dst_end = dst_col + height * LCD_FBWIDTH;
+ dst_end = dst_col + height * stride_dst;
do
{
bfunc(dst_col, mask, 0xFFu);
- dst_col += LCD_FBWIDTH;
+ dst_col += stride_dst;
}
while (dst_col < dst_end);
@@ -706,11 +735,11 @@ void lcd_fillrect(int x, int y, int width, int height)
}
mask &= mask_right;
- dst_end = dst + height * LCD_FBWIDTH;
+ dst_end = dst + height * stride_dst;
do
{
bfunc(dst, mask, 0xFFu);
- dst += LCD_FBWIDTH;
+ dst += stride_dst;
}
while (dst < dst_end);
}
@@ -731,14 +760,15 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
{
const unsigned char *src_end;
fb_data *dst, *dst_end;
+ int stride_dst;
unsigned dmask = 0x100; /* bit 8 == sentinel */
unsigned dst_mask;
- int drmode = current_vp->drawmode;
+ int drmode = lcd_current_viewport->drawmode;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -753,13 +783,13 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
- x += current_vp->x; /* adjust for viewport */
- y += current_vp->y; /* adjust for viewport */
+ x += lcd_current_viewport->x; /* adjust for viewport */
+ y += lcd_current_viewport->y; /* adjust for viewport */
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -792,7 +822,8 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
src_end = src + width;
dst = FBADDR(x >> 2,y);
- dst_end = dst + height * LCD_FBWIDTH;
+ stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
+ dst_end = dst + height * stride_dst;
dst_mask = pixmask[x & 3];
if (drmode & DRMODE_INVERSEVID)
@@ -825,7 +856,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
if (data & 0x01)
*dst_col ^= dst_mask;
- dst_col += LCD_FBWIDTH;
+ dst_col += stride_dst;
UPDATE_SRC;
}
while (dst_col < dst_end);
@@ -843,7 +874,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
*dst_col = block
^ ((block ^ *(dst_col + bo)) & dst_mask);
}
- dst_col += LCD_FBWIDTH;
+ dst_col += stride_dst;
UPDATE_SRC;
}
while (dst_col < dst_end);
@@ -858,7 +889,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
unsigned block = *dst_col;
*dst_col = block ^ ((block ^ bg) & dst_mask);
}
- dst_col += LCD_FBWIDTH;
+ dst_col += stride_dst;
UPDATE_SRC;
}
while (dst_col < dst_end);
@@ -874,7 +905,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
unsigned block = *dst_col;
*dst_col = block ^ ((block ^ fg) & dst_mask);
}
- dst_col += LCD_FBWIDTH;
+ dst_col += stride_dst;
UPDATE_SRC;
}
while (dst_col < dst_end);
@@ -891,7 +922,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
*dst_col = block ^ ((block ^ ((data & 0x01) ?
fg : *(dst_col + bo))) & dst_mask);
- dst_col += LCD_FBWIDTH;
+ dst_col += stride_dst;
UPDATE_SRC;
}
while (dst_col < dst_end);
@@ -905,7 +936,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
*dst_col = block ^ ((block ^ ((data & 0x01) ?
fg : bg)) & dst_mask);
- dst_col += LCD_FBWIDTH;
+ dst_col += stride_dst;
UPDATE_SRC;
}
while (dst_col < dst_end);
@@ -945,12 +976,13 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
{
int shift, nx;
unsigned char *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_right;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -965,14 +997,14 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -1000,12 +1032,13 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
height = LCD_HEIGHT - y;
#endif
- stride = (stride + 3) >> 2; /* convert to no. of bytes */
+ stride = LCD_FBSTRIDE(stride, 0); /* convert to no. of bytes */
src += stride * src_y + (src_x >> 2); /* move starting point */
src_x &= 3;
x -= src_x;
dst = FBADDR(x>>2,y);
+ stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
shift = x & 3;
nx = width - 1 + shift + src_x;
@@ -1013,7 +1046,7 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
mask_right = 0xFFu << (2 * (~nx & 3));
shift *= 2;
- dst_end = dst + height * LCD_FBWIDTH;
+ dst_end = dst + height * stride_dst;
do
{
const unsigned char *src_row = src;
@@ -1039,7 +1072,7 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
setblock(dst_row, mask_row & mask_right, data >> shift);
src += stride;
- dst += LCD_FBWIDTH;
+ dst += stride_dst;
}
while (dst < dst_end);
}
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c
index 501e568a69..a099c45e98 100644
--- a/firmware/drivers/lcd-2bit-vert.c
+++ b/firmware/drivers/lcd-2bit-vert.c
@@ -36,8 +36,8 @@
/*** globals ***/
-fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER;
-fb_data *lcd_framebuffer = &lcd_static_framebuffer[0][0];
+static fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER;
+static void *lcd_frameaddress_default(int x, int y);
const unsigned char lcd_dibits[16] ICONST_ATTR = {
0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F,
@@ -51,6 +51,15 @@ static const unsigned char pixmask[4] ICONST_ATTR = {
static fb_data* lcd_backdrop = NULL;
static long lcd_backdrop_offset IDATA_ATTR = 0;
+/* shouldn't be changed unless you want system-wide framebuffer changes! */
+struct frame_buffer_t lcd_framebuffer_default =
+{
+ .fb_ptr = &lcd_static_framebuffer[0][0],
+ .get_address_fn = &lcd_frameaddress_default,
+ .stride = STRIDE_MAIN(LCD_WIDTH, LCD_HEIGHT),
+ .elems = (LCD_FBWIDTH*LCD_FBHEIGHT),
+};
+
static struct viewport default_vp =
{
.x = 0,
@@ -59,18 +68,32 @@ static struct viewport default_vp =
.height = LCD_HEIGHT,
.font = FONT_SYSFIXED,
.drawmode = DRMODE_SOLID,
+ .buffer = NULL,
.fg_pattern = LCD_DEFAULT_FG,
.bg_pattern = LCD_DEFAULT_BG
};
-static struct viewport* current_vp IBSS_ATTR;
+struct viewport* lcd_current_viewport IBSS_ATTR;
static unsigned fg_pattern IBSS_ATTR;
static unsigned bg_pattern IBSS_ATTR;
+static void *lcd_frameaddress_default(int x, int y)
+{
+ /* the default expects a buffer the same size as the screen */
+ struct frame_buffer_t *fb = lcd_current_viewport->buffer;
+
+#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
+ return fb->fb_ptr + element; /*(element % fb->elems);*/
+}
+
/* LCD init */
void lcd_init(void)
{
- /* Initialise the viewport */
+ /* Initialize the viewport */
lcd_set_viewport(NULL);
lcd_clear_display();
@@ -83,34 +106,34 @@ void lcd_init(void)
void lcd_set_drawmode(int mode)
{
- current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
+ lcd_current_viewport->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
}
int lcd_get_drawmode(void)
{
- return current_vp->drawmode;
+ return lcd_current_viewport->drawmode;
}
void lcd_set_foreground(unsigned brightness)
{
- current_vp->fg_pattern = brightness;
+ lcd_current_viewport->fg_pattern = brightness;
fg_pattern = 0x55 * (~brightness & 3);
}
unsigned lcd_get_foreground(void)
{
- return current_vp->fg_pattern;
+ return lcd_current_viewport->fg_pattern;
}
void lcd_set_background(unsigned brightness)
{
- current_vp->bg_pattern = brightness;
+ lcd_current_viewport->bg_pattern = brightness;
bg_pattern = 0x55 * (~brightness & 3);
}
unsigned lcd_get_background(void)
{
- return current_vp->bg_pattern;
+ return lcd_current_viewport->bg_pattern;
}
void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
@@ -122,27 +145,27 @@ void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
int lcd_getwidth(void)
{
- return current_vp->width;
+ return lcd_current_viewport->width;
}
int lcd_getheight(void)
{
- return current_vp->height;
+ return lcd_current_viewport->height;
}
void lcd_setfont(int newfont)
{
- current_vp->font = newfont;
+ lcd_current_viewport->font = newfont;
}
int lcd_getfont(void)
{
- return current_vp->font;
+ return lcd_current_viewport->font;
}
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
{
- return font_getstringsize(str, w, h, current_vp->font);
+ return font_getstringsize(str, w, h, lcd_current_viewport->font);
}
/*** low-level drawing functions ***/
@@ -320,7 +343,7 @@ void lcd_set_backdrop(fb_data* backdrop)
lcd_backdrop = backdrop;
if (backdrop)
{
- lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer;
+ lcd_backdrop_offset = (long)backdrop - (long)FBADDR(0,0);
lcd_pixelfuncs = lcd_pixelfuncs_backdrop;
lcd_blockfuncs = lcd_blockfuncs_backdrop;
}
@@ -351,16 +374,16 @@ static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
/* Clear the whole display */
void lcd_clear_display(void)
{
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
- memset(lcd_framebuffer, fg_pattern, FRAMEBUFFER_SIZE);
+ memset(FBADDR(0,0), fg_pattern, FRAMEBUFFER_SIZE);
}
else
{
if (lcd_backdrop)
- memcpy(lcd_framebuffer, lcd_backdrop, FRAMEBUFFER_SIZE);
+ memcpy(FBADDR(0,0), lcd_backdrop, FRAMEBUFFER_SIZE);
else
- memset(lcd_framebuffer, bg_pattern, FRAMEBUFFER_SIZE);
+ memset(FBADDR(0,0), bg_pattern, FRAMEBUFFER_SIZE);
}
lcd_scroll_info.lines = 0;
@@ -371,37 +394,39 @@ void lcd_clear_viewport(void)
{
int lastmode;
- if (current_vp == &default_vp)
+ if (lcd_current_viewport == &default_vp &&
+ default_vp.buffer == &lcd_framebuffer_default)
{
lcd_clear_display();
}
else
{
- lastmode = current_vp->drawmode;
+ lastmode = lcd_current_viewport->drawmode;
/* Invert the INVERSEVID bit and set basic mode to SOLID */
- current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) |
+ lcd_current_viewport->drawmode = (~lastmode & DRMODE_INVERSEVID) |
DRMODE_SOLID;
- lcd_fillrect(0, 0, current_vp->width, current_vp->height);
+ lcd_fillrect(0, 0, lcd_current_viewport->width, lcd_current_viewport->height);
- current_vp->drawmode = lastmode;
+ lcd_current_viewport->drawmode = lastmode;
- lcd_scroll_stop_viewport(current_vp);
+ lcd_scroll_stop_viewport(lcd_current_viewport);
}
+ lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN);
}
/* Set a single pixel */
void lcd_drawpixel(int x, int y)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
+ && ((unsigned)y < (unsigned)lcd_current_viewport->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCD_WIDTH)
&& ((unsigned)y < (unsigned)LCD_HEIGHT)
#endif
)
- lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y);
+ lcd_pixelfuncs[lcd_current_viewport->drawmode](lcd_current_viewport->x + x, lcd_current_viewport->y + y);
}
/* Draw a line */
@@ -413,7 +438,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
int d, dinc1, dinc2;
int x, xinc1, xinc2;
int y, yinc1, yinc2;
- lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode];
+ lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode];
deltax = abs(x2 - x1);
if (deltax == 0)
@@ -469,14 +494,14 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
for (i = 0; i < numpixels; i++)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
+ && ((unsigned)y < (unsigned)lcd_current_viewport->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCD_WIDTH)
&& ((unsigned)y < (unsigned)LCD_HEIGHT)
#endif
)
- pfunc(current_vp->x + x, current_vp->y + y);
+ pfunc(lcd_current_viewport->x + x, lcd_current_viewport->y + y);
if (d < 0)
{
@@ -512,19 +537,19 @@ void lcd_hline(int x1, int x2, int y)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
+ if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || (x1 >= lcd_current_viewport->width)
|| (x2 < 0))
return;
if (x1 < 0)
x1 = 0;
- if (x2 >= current_vp->width)
- x2 = current_vp->width-1;
+ if (x2 >= lcd_current_viewport->width)
+ x2 = lcd_current_viewport->width-1;
/* adjust x1 and y to viewport */
- x1 += current_vp->x;
- x2 += current_vp->x;
- y += current_vp->y;
+ x1 += lcd_current_viewport->x;
+ x2 += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -542,7 +567,7 @@ void lcd_hline(int x1, int x2, int y)
width = x2 - x1 + 1;
- bfunc = lcd_blockfuncs[current_vp->drawmode];
+ bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
dst = FBADDR(x1,y>>2);
mask = pixmask[y & 3];
@@ -557,6 +582,7 @@ void lcd_vline(int x, int y1, int y2)
{
int ny;
fb_data *dst;
+ int stride_dst;
unsigned mask, mask_bottom;
lcd_blockfunc_type *bfunc;
@@ -570,19 +596,19 @@ void lcd_vline(int x, int y1, int y2)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
+ if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || (y1 >= lcd_current_viewport->height)
|| (y2 < 0))
return;
if (y1 < 0)
y1 = 0;
- if (y2 >= current_vp->height)
- y2 = current_vp->height-1;
+ if (y2 >= lcd_current_viewport->height)
+ y2 = lcd_current_viewport->height-1;
/* adjust for viewport */
- y1 += current_vp->y;
- y2 += current_vp->y;
- x += current_vp->x;
+ y1 += lcd_current_viewport->y;
+ y2 += lcd_current_viewport->y;
+ x += lcd_current_viewport->x;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -598,8 +624,9 @@ void lcd_vline(int x, int y1, int y2)
y2 = LCD_HEIGHT-1;
#endif
- bfunc = lcd_blockfuncs[current_vp->drawmode];
+ bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
dst = FBADDR(x,y1>>2);
+ stride_dst = lcd_current_viewport->buffer->stride;
ny = y2 - (y1 & ~3);
mask = 0xFFu << (2 * (y1 & 3));
mask_bottom = 0xFFu >> (2 * (~ny & 3));
@@ -607,7 +634,7 @@ void lcd_vline(int x, int y1, int y2)
for (; ny >= 4; ny -= 4)
{
bfunc(dst, mask, 0xFFu);
- dst += LCD_WIDTH;
+ dst += stride_dst;
mask = 0xFFu;
}
mask &= mask_bottom;
@@ -634,6 +661,7 @@ void lcd_fillrect(int x, int y, int width, int height)
{
int ny;
fb_data *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_bottom;
unsigned bits = 0;
lcd_blockfunc_type *bfunc;
@@ -641,8 +669,8 @@ void lcd_fillrect(int x, int y, int width, int height)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
- || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width)
+ || (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -655,14 +683,14 @@ void lcd_fillrect(int x, int y, int width, int height)
height += y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -688,9 +716,9 @@ void lcd_fillrect(int x, int y, int width, int height)
height = LCD_HEIGHT - y;
#endif
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
{
- if ((current_vp->drawmode & DRMODE_BG) && !lcd_backdrop)
+ if ((lcd_current_viewport->drawmode & DRMODE_BG) && !lcd_backdrop)
{
fillopt = true;
bits = bg_pattern;
@@ -698,14 +726,15 @@ void lcd_fillrect(int x, int y, int width, int height)
}
else
{
- if (current_vp->drawmode & DRMODE_FG)
+ if (lcd_current_viewport->drawmode & DRMODE_FG)
{
fillopt = true;
bits = fg_pattern;
}
}
- bfunc = lcd_blockfuncs[current_vp->drawmode];
+ bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
dst = FBADDR(x,y>>2);
+ stride_dst = lcd_current_viewport->buffer->stride;
ny = height - 1 + (y & 3);
mask = 0xFFu << (2 * (y & 3));
mask_bottom = 0xFFu >> (2 * (~ny & 3));
@@ -724,7 +753,7 @@ void lcd_fillrect(int x, int y, int width, int height)
while (dst_row < dst_end);
}
- dst += LCD_WIDTH;
+ dst += stride_dst;
mask = 0xFFu;
}
mask &= mask_bottom;
@@ -758,13 +787,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
{
int shift, ny;
fb_data *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_bottom;
lcd_blockfunc_type *bfunc;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
+ (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -779,14 +809,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -818,13 +848,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
src_y &= 7;
y -= src_y;
dst = FBADDR(x,y>>2);
+ stride_dst = lcd_current_viewport->buffer->stride;
shift = y & 3;
ny = height - 1 + shift + src_y;
mask = 0xFFFFu << (2 * (shift + src_y));
/* Overflowing bits aren't important. */
mask_bottom = 0xFFFFu >> (2 * (~ny & 7));
- bfunc = lcd_blockfuncs[current_vp->drawmode];
+ bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
if (shift == 0)
{
@@ -836,7 +867,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
for (; ny >= 8; ny -= 8)
{
const unsigned char *src_row = src;
- fb_data *dst_row = dst + LCD_WIDTH;
+ fb_data *dst_row = dst + stride_dst;
dst_end = dst_row + width;
@@ -845,7 +876,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
do
{
data = *src_row++;
- bfunc(dst_row - LCD_WIDTH, dmask1, lcd_dibits[data&0x0F]);
+ bfunc(dst_row - stride_dst, dmask1, lcd_dibits[data&0x0F]);
bfunc(dst_row++, dmask2, lcd_dibits[(data>>4)&0x0F]);
}
while (dst_row < dst_end);
@@ -857,7 +888,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
while (dst_row < dst_end);
}
src += stride;
- dst += 2*LCD_WIDTH;
+ dst += 2*stride_dst;
dmask1 = dmask2 = 0xFFu;
}
dmask1 &= mask_bottom;
@@ -873,7 +904,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
{
data = *src++;
bfunc(dst, dmask1, lcd_dibits[data&0x0F]);
- bfunc((dst++) + LCD_WIDTH, dmask2, lcd_dibits[(data>>4)&0x0F]);
+ bfunc((dst++) + stride_dst, dmask2, lcd_dibits[(data>>4)&0x0F]);
}
while (dst < dst_end);
}
@@ -887,7 +918,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
else
{
do
- bfunc((dst++) + LCD_WIDTH, dmask2, lcd_dibits[((*src++)>>4)&0x0F]);
+ bfunc((dst++) + stride_dst, dmask2, lcd_dibits[((*src++)>>4)&0x0F]);
while (dst < dst_end);
}
}
@@ -909,7 +940,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
{
if (mask_col & 0xFFu)
bfunc(dst_col, mask_col, lcd_dibits[data&0x0F]);
- bfunc(dst_col + LCD_WIDTH, mask_col >> 8,
+ bfunc(dst_col + stride_dst, mask_col >> 8,
lcd_dibits[(data>>4)&0x0F]);
mask_col = 0xFFFFu;
}
@@ -917,7 +948,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
mask_col >>= 16;
src_col += stride;
- dst_col += 2*LCD_WIDTH;
+ dst_col += 2*stride_dst;
data >>= 8;
}
data |= *src_col << shift;
@@ -925,7 +956,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
if (mask_col & 0xFFu)
bfunc(dst_col, mask_col, lcd_dibits[data&0x0F]);
if (mask_col & 0xFF00u)
- bfunc(dst_col + LCD_WIDTH, mask_col >> 8,
+ bfunc(dst_col + stride_dst, mask_col >> 8,
lcd_dibits[(data>>4)&0x0F]);
}
while (dst < dst_end);
@@ -956,12 +987,13 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
{
int shift, ny;
fb_data *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_bottom;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
- || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width)
+ || (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -976,14 +1008,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > lcd_current_viewport->width)
+ width = lcd_current_viewport->width - x;
+ if (y + height > lcd_current_viewport->height)
+ height = lcd_current_viewport->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += lcd_current_viewport->x;
+ y += lcd_current_viewport->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -1010,11 +1042,11 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
if (y + height > LCD_HEIGHT)
height = LCD_HEIGHT - y;
#endif
-
src += stride * (src_y >> 2) + src_x; /* move starting point */
src_y &= 3;
y -= src_y;
dst = FBADDR(x,y>>2);
+ stride_dst = lcd_current_viewport->buffer->stride;
shift = y & 3;
ny = height - 1 + shift + src_y;
@@ -1038,7 +1070,7 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
while (dst_row < dst_end);
}
src += stride;
- dst += LCD_WIDTH;
+ dst += stride_dst;
mask = 0xFFu;
}
mask &= mask_bottom;
@@ -1077,7 +1109,7 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
mask_col >>= 8;
src_col += stride;
- dst_col += LCD_WIDTH;
+ dst_col += stride_dst;
data >>= 8;
}
data |= *src_col << shift;
diff --git a/firmware/drivers/lcd-2bit-vi.c b/firmware/drivers/lcd-2bit-vi.c
index 0608dfaa46..035e8b6d0d 100644
--- a/firmware/drivers/lcd-2bit-vi.c
+++ b/firmware/drivers/lcd-2bit-vi.c
@@ -46,17 +46,32 @@
#define MAIN_LCD
#endif
-/*** globals ***/
+#ifdef MAIN_LCD
+#define THIS_STRIDE STRIDE_MAIN
+#else
+#define THIS_STRIDE STRIDE_REMOTE
+#endif
-FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER;
-FBFN(data) *LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0];
+#define CURRENT_VP LCDFN(current_viewport)
+/*** globals ***/
+static FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER;
+static void *LCDFN(frameaddress_default)(int x, int y);
static const FBFN(data) patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
static FBFN(data) *backdrop = NULL;
static long backdrop_offset IDATA_ATTR = 0;
+/* shouldn't be changed unless you want system-wide framebuffer changes! */
+struct frame_buffer_t LCDFN(framebuffer_default) =
+{
+ .FBFN(ptr) = &LCDFN(static_framebuffer)[0][0],
+ .get_address_fn = &LCDFN(frameaddress_default),
+ .stride = THIS_STRIDE(LCDM(WIDTH), LCDM(HEIGHT)),
+ .elems = (LCDM(FBWIDTH)*LCDM(FBHEIGHT)),
+};
+
static struct viewport default_vp =
{
.x = 0,
@@ -65,19 +80,34 @@ static struct viewport default_vp =
.height = LCDM(HEIGHT),
.font = FONT_SYSFIXED,
.drawmode = DRMODE_SOLID,
+ .buffer = NULL,
.fg_pattern = LCDM(DEFAULT_FG),
.bg_pattern = LCDM(DEFAULT_BG)
};
-static struct viewport * current_vp IBSS_ATTR;
+struct viewport * CURRENT_VP IBSS_ATTR;
static unsigned fg_pattern IBSS_ATTR;
static unsigned bg_pattern IBSS_ATTR;
+static void *LCDFN(frameaddress_default)(int x, int y)
+{
+ /* the default expects a buffer the same size as the screen */
+ struct frame_buffer_t *fb = CURRENT_VP->buffer;
+#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
+ size_t element = (x * LCDM(NATIVE_STRIDE)(fb->stride)) + y;
+#else
+ size_t element = (y * LCDM(NATIVE_STRIDE)(fb->stride)) + x;
+#endif
+ return fb->FBFN(ptr) + element;/*(element % fb->elems);*/
+}
+
/* LCD init */
void LCDFN(init)(void)
{
+ /* Initialize the viewport */
LCDFN(set_viewport)(NULL);
+
LCDFN(clear_display)();
LCDFN(init_device)();
#ifdef MAIN_LCD
@@ -105,34 +135,34 @@ unsigned lcd_remote_color_to_native(unsigned color)
void LCDFN(set_drawmode)(int mode)
{
- current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
+ CURRENT_VP->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
}
int LCDFN(get_drawmode)(void)
{
- return current_vp->drawmode;
+ return CURRENT_VP->drawmode;
}
void LCDFN(set_foreground)(unsigned brightness)
{
- current_vp->fg_pattern = brightness;
+ CURRENT_VP->fg_pattern = brightness;
fg_pattern = patterns[brightness & 3];
}
unsigned LCDFN(get_foreground)(void)
{
- return current_vp->fg_pattern;
+ return CURRENT_VP->fg_pattern;
}
void LCDFN(set_background)(unsigned brightness)
{
- current_vp->bg_pattern = brightness;
+ CURRENT_VP->bg_pattern = brightness;
bg_pattern = patterns[brightness & 3];
}
unsigned LCDFN(get_background)(void)
{
- return current_vp->bg_pattern;
+ return CURRENT_VP->bg_pattern;
}
void LCDFN(set_drawinfo)(int mode, unsigned fg_brightness,
@@ -145,26 +175,26 @@ void LCDFN(set_drawinfo)(int mode, unsigned fg_brightness,
int LCDFN(getwidth)(void)
{
- return current_vp->width;
+ return CURRENT_VP->width;
}
int LCDFN(getheight)(void)
{
- return current_vp->height;
+ return CURRENT_VP->height;
}
void LCDFN(setfont)(int newfont)
{
- current_vp->font = newfont;
+ CURRENT_VP->font = newfont;
}
int LCDFN(getfont)(void)
{
- return current_vp->font;
+ return CURRENT_VP->font;
}
int LCDFN(getstringsize)(const unsigned char *str, int *w, int *h)
{
- return font_getstringsize(str, w, h, current_vp->font);
+ return font_getstringsize(str, w, h, CURRENT_VP->font);
}
/*** low-level drawing functions ***/
@@ -345,7 +375,7 @@ void LCDFN(set_backdrop)(FBFN(data) *bd)
backdrop = bd;
if (bd)
{
- backdrop_offset = (long)bd - (long)LCDFN(framebuffer);
+ backdrop_offset = (long)bd - (long)LCDFB(0, 0);
LCDFN(pixelfuncs) = LCDFN(pixelfuncs_backdrop);
LCDFN(blockfuncs) = LCDFN(blockfuncs_backdrop);
}
@@ -377,15 +407,15 @@ void LCDFN(clear_display)(void)
{
if (default_vp.drawmode & DRMODE_INVERSEVID)
{
- memset(LCDFN(framebuffer), patterns[default_vp.fg_pattern & 3],
+ memset(LCDFB(0, 0), patterns[default_vp.fg_pattern & 3],
FBSIZE);
}
else
{
if (backdrop)
- memcpy(LCDFN(framebuffer), backdrop, FBSIZE);
+ memcpy(LCDFB(0, 0), backdrop, FBSIZE);
else
- memset(LCDFN(framebuffer), patterns[default_vp.bg_pattern & 3],
+ memset(LCDFB(0, 0), patterns[default_vp.bg_pattern & 3],
FBSIZE);
}
@@ -397,37 +427,39 @@ void LCDFN(clear_viewport)(void)
{
int lastmode;
- if (current_vp == &default_vp)
+ if (CURRENT_VP == &default_vp &&
+ default_vp.buffer == &LCDFN(framebuffer_default))
{
LCDFN(clear_display)();
}
else
{
- lastmode = current_vp->drawmode;
+ lastmode = CURRENT_VP->drawmode;
/* Invert the INVERSEVID bit and set basic mode to SOLID */
- current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) |
+ CURRENT_VP->drawmode = (~lastmode & DRMODE_INVERSEVID) |
DRMODE_SOLID;
- LCDFN(fillrect)(0, 0, current_vp->width, current_vp->height);
+ LCDFN(fillrect)(0, 0, CURRENT_VP->width, CURRENT_VP->height);
- current_vp->drawmode = lastmode;
+ CURRENT_VP->drawmode = lastmode;
- LCDFN(scroll_stop_viewport)(current_vp);
+ LCDFN(scroll_stop_viewport)(CURRENT_VP);
}
+ CURRENT_VP->flags &= ~(VP_FLAG_VP_SET_CLEAN);
}
/* Set a single pixel */
void LCDFN(drawpixel)(int x, int y)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)CURRENT_VP->width)
+ && ((unsigned)y < (unsigned)CURRENT_VP->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCDM(WIDTH))
&& ((unsigned)y < (unsigned)LCDM(HEIGHT))
#endif
)
- LCDFN(pixelfuncs)[current_vp->drawmode](current_vp->x+x, current_vp->y+y);
+ LCDFN(pixelfuncs)[CURRENT_VP->drawmode](CURRENT_VP->x+x, CURRENT_VP->y+y);
}
/* Draw a line */
@@ -439,7 +471,7 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2)
int d, dinc1, dinc2;
int x, xinc1, xinc2;
int y, yinc1, yinc2;
- LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[current_vp->drawmode];
+ LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode];
deltax = abs(x2 - x1);
if (deltax == 0)
@@ -495,14 +527,14 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2)
for (i = 0; i < numpixels; i++)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)CURRENT_VP->width)
+ && ((unsigned)y < (unsigned)CURRENT_VP->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCDM(WIDTH))
&& ((unsigned)y < (unsigned)LCDM(HEIGHT))
#endif
)
- pfunc(current_vp->x + x, current_vp->y + y);
+ pfunc(CURRENT_VP->x + x, CURRENT_VP->y + y);
if (d < 0)
{
@@ -538,19 +570,19 @@ void LCDFN(hline)(int x1, int x2, int y)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
+ if (((unsigned)y >= (unsigned)CURRENT_VP->height) || (x1 >= CURRENT_VP->width)
|| (x2 < 0))
return;
if (x1 < 0)
x1 = 0;
- if (x2 >= current_vp->width)
- x2 = current_vp->width-1;
+ if (x2 >= CURRENT_VP->width)
+ x2 = CURRENT_VP->width-1;
/* adjust x1 and y to viewport */
- x1 += current_vp->x;
- x2 += current_vp->x;
- y += current_vp->y;
+ x1 += CURRENT_VP->x;
+ x2 += CURRENT_VP->x;
+ y += CURRENT_VP->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -568,7 +600,7 @@ void LCDFN(hline)(int x1, int x2, int y)
width = x2 - x1 + 1;
- bfunc = LCDFN(blockfuncs)[current_vp->drawmode];
+ bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
dst = LCDFB(x1,y>>3);
mask = 0x0101 << (y & 7);
@@ -583,6 +615,7 @@ void LCDFN(vline)(int x, int y1, int y2)
{
int ny;
FBFN(data) *dst;
+ int stride_dst;
unsigned mask, mask_bottom;
LCDFN(blockfunc_type) *bfunc;
@@ -596,19 +629,19 @@ void LCDFN(vline)(int x, int y1, int y2)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
+ if (((unsigned)x >= (unsigned)CURRENT_VP->width) || (y1 >= CURRENT_VP->height)
|| (y2 < 0))
return;
if (y1 < 0)
y1 = 0;
- if (y2 >= current_vp->height)
- y2 = current_vp->height-1;
+ if (y2 >= CURRENT_VP->height)
+ y2 = CURRENT_VP->height-1;
/* adjust for viewport */
- y1 += current_vp->y;
- y2 += current_vp->y;
- x += current_vp->x;
+ y1 += CURRENT_VP->y;
+ y2 += CURRENT_VP->y;
+ x += CURRENT_VP->x;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -624,8 +657,9 @@ void LCDFN(vline)(int x, int y1, int y2)
y2 = LCDM(HEIGHT)-1;
#endif
- bfunc = LCDFN(blockfuncs)[current_vp->drawmode];
+ bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
dst = LCDFB(x,y1>>3);
+ stride_dst = CURRENT_VP->buffer->stride;
ny = y2 - (y1 & ~7);
mask = (0xFFu << (y1 & 7)) & 0xFFu;
mask |= mask << 8;
@@ -635,7 +669,7 @@ void LCDFN(vline)(int x, int y1, int y2)
for (; ny >= 8; ny -= 8)
{
bfunc(dst, mask, 0xFFFFu);
- dst += LCDM(WIDTH);
+ dst += stride_dst;
mask = 0xFFFFu;
}
mask &= mask_bottom;
@@ -662,6 +696,7 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
{
int ny;
FBFN(data) *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_bottom;
unsigned bits = 0;
LCDFN(blockfunc_type) *bfunc;
@@ -669,8 +704,8 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
/******************** In viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
- || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width)
+ || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -683,14 +718,14 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
height += y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > CURRENT_VP->width)
+ width = CURRENT_VP->width - x;
+ if (y + height > CURRENT_VP->height)
+ height = CURRENT_VP->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += CURRENT_VP->x;
+ y += CURRENT_VP->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -717,9 +752,9 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
#endif
- if (current_vp->drawmode & DRMODE_INVERSEVID)
+ if (CURRENT_VP->drawmode & DRMODE_INVERSEVID)
{
- if ((current_vp->drawmode & DRMODE_BG) && !backdrop)
+ if ((CURRENT_VP->drawmode & DRMODE_BG) && !backdrop)
{
fillopt = true;
bits = bg_pattern;
@@ -727,14 +762,15 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
}
else
{
- if (current_vp->drawmode & DRMODE_FG)
+ if (CURRENT_VP->drawmode & DRMODE_FG)
{
fillopt = true;
bits = fg_pattern;
}
}
- bfunc = LCDFN(blockfuncs)[current_vp->drawmode];
+ bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
dst = LCDFB(x,y>>3);
+ stride_dst = CURRENT_VP->buffer->stride;
ny = height - 1 + (y & 7);
mask = (0xFFu << (y & 7)) & 0xFFu;
mask |= mask << 8;
@@ -755,7 +791,7 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
while (dst_row < dst_end);
}
- dst += LCDM(WIDTH);
+ dst += stride_dst;
mask = 0xFFFFu;
}
mask &= mask_bottom;
@@ -789,13 +825,14 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
{
int shift, ny;
FBFN(data) *dst, *dst_end;
+ int stride_dst;
unsigned data, mask, mask_bottom;
LCDFN(blockfunc_type) *bfunc;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
- (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) ||
+ (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -810,14 +847,14 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > CURRENT_VP->width)
+ width = CURRENT_VP->width - x;
+ if (y + height > CURRENT_VP->height)
+ height = CURRENT_VP->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += CURRENT_VP->x;
+ y += CURRENT_VP->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -849,10 +886,11 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
src_y &= 7;
y -= src_y;
dst = LCDFB(x,y>>3);
+ stride_dst = CURRENT_VP->buffer->stride;
shift = y & 7;
ny = height - 1 + shift + src_y;
- bfunc = LCDFN(blockfuncs)[current_vp->drawmode];
+ bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
mask = 0xFFu << (shift + src_y);
/* not byte-doubled here because shift+src_y can be > 7 */
mask_bottom = 0xFFu >> (~ny & 7);
@@ -877,7 +915,7 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
while (dst_row < dst_end);
src += stride;
- dst += LCDM(WIDTH);
+ dst += stride_dst;
mask = 0xFFFFu;
}
mask &= mask_bottom;
@@ -921,7 +959,7 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
}
src_col += stride;
- dst_col += LCDM(WIDTH);
+ dst_col += stride_dst;
data >>= 8;
}
data |= *src_col << shift;
@@ -958,12 +996,13 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
{
int shift, ny;
FBFN(data) *dst, *dst_end;
+ int stride_dst;
unsigned mask, mask_bottom;
/******************** Image in viewport clipping **********************/
/* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= current_vp->width)
- || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
+ if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width)
+ || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0))
return;
if (x < 0)
@@ -978,14 +1017,14 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
src_y -= y;
y = 0;
}
- if (x + width > current_vp->width)
- width = current_vp->width - x;
- if (y + height > current_vp->height)
- height = current_vp->height - y;
+ if (x + width > CURRENT_VP->width)
+ width = CURRENT_VP->width - x;
+ if (y + height > CURRENT_VP->height)
+ height = CURRENT_VP->height - y;
/* adjust for viewport */
- x += current_vp->x;
- y += current_vp->y;
+ x += CURRENT_VP->x;
+ y += CURRENT_VP->y;
#if defined(HAVE_VIEWPORT_CLIP)
/********************* Viewport on screen clipping ********************/
@@ -1017,6 +1056,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
src_y &= 7;
y -= src_y;
dst = LCDFB(x,y>>3);
+ stride_dst = CURRENT_VP->buffer->stride;
shift = y & 7;
ny = height - 1 + shift + src_y;
@@ -1045,7 +1085,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
while (dst_row < dst_end);
}
src += stride;
- dst += LCDM(WIDTH);
+ dst += stride_dst;
mask = 0xFFFFu;
}
mask &= mask_bottom;
@@ -1092,7 +1132,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
mask_col |= mask_col << 8;
}
src_col += stride;
- dst_col += LCDM(WIDTH);
+ dst_col += stride_dst;
olddata = data >> 8;
}
data = *src_col << shift;
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index 8c38e513c6..94829b5d0c 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -40,43 +40,70 @@
#define MAIN_LCD
#endif
-void LCDFN(set_framebuffer)(FBFN(data) *fb)
-{
- if (fb)
- LCDFN(framebuffer) = fb;
- else
- LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0];
-}
+#ifdef MAIN_LCD
+#define THIS_STRIDE STRIDE_MAIN
+#else
+#define THIS_STRIDE STRIDE_REMOTE
+#endif
+extern void viewport_set_buffer(struct viewport *vp,
+ struct frame_buffer_t *buffer,
+ const enum screen_type screen); /* viewport.c */
/*
* draws the borders of the current viewport
**/
void LCDFN(draw_border_viewport)(void)
{
- LCDFN(drawrect)(0, 0, current_vp->width, current_vp->height);
+ LCDFN(drawrect)(0, 0, LCDFN(current_viewport)->width, LCDFN(current_viewport)->height);
}
/*
- * fills the rectangle formed by current_vp
+ * fills the rectangle formed by LCDFN(current_viewport)
**/
void LCDFN(fill_viewport)(void)
{
- LCDFN(fillrect)(0, 0, current_vp->width, current_vp->height);
+ LCDFN(fillrect)(0, 0, LCDFN(current_viewport)->width, LCDFN(current_viewport)->height);
}
/*** Viewports ***/
-
-void LCDFN(set_viewport)(struct viewport* vp)
+/* init_viewport Notes: When a viewport is initialized
+ * if vp->buffer is NULL the default frame_buffer is assigned
+ * likewise the actual buffer, stride, get_address_fn
+ * are all filled with values from the default buffer if they are not set
+ * RETURNS either the viewport you passed or the default viewport if vp == NULL
+ */
+struct viewport* LCDFN(init_viewport)(struct viewport* vp)
{
- if (vp == NULL)
- current_vp = &default_vp;
+ struct frame_buffer_t *fb_default = &LCDFN(framebuffer_default);
+ if (!vp) /* NULL vp grabs default viewport */
+ vp = &default_vp;
+
+ /* use defaults if no buffer is provided */
+ if (vp->buffer == NULL || vp->buffer->elems == 0)
+ vp->buffer = fb_default;
else
- current_vp = vp;
+ {
+ if (vp->buffer->stride == 0)
+ vp->buffer->stride = fb_default->stride;
+
+ if (vp->buffer->data == NULL)
+ vp->buffer->data = fb_default->data;
+
+ if (vp->buffer->get_address_fn == NULL)
+ vp->buffer->get_address_fn = fb_default->get_address_fn;
+ }
+ return vp;
+}
+struct viewport* LCDFN(set_viewport_ex)(struct viewport* vp, int flags)
+{
+ vp = LCDFN(init_viewport)(vp);
+ struct viewport* last_vp = LCDFN(current_viewport);
+ LCDFN(current_viewport) = vp;
#if LCDM(DEPTH) > 1
- LCDFN(set_foreground)(current_vp->fg_pattern);
- LCDFN(set_background)(current_vp->bg_pattern);
+ LCDFN(set_foreground)(vp->fg_pattern);
+ LCDFN(set_background)(vp->bg_pattern);
#endif
#if defined(SIMULATOR)
@@ -84,10 +111,11 @@ void LCDFN(set_viewport)(struct viewport* vp)
* be considered an error - the viewport will not draw as it might be
* expected.
*/
- if((unsigned) current_vp->x > (unsigned) LCDM(WIDTH)
- || (unsigned) current_vp->y > (unsigned) LCDM(HEIGHT)
- || current_vp->x + current_vp->width > LCDM(WIDTH)
- || current_vp->y + current_vp->height > LCDM(HEIGHT))
+
+ if((unsigned) vp->x > (unsigned) LCDM(WIDTH)
+ || (unsigned) vp->y > (unsigned) LCDM(HEIGHT)
+ || vp->x + vp->width > LCDM(WIDTH)
+ || vp->y + vp->height > LCDM(HEIGHT))
{
#if !defined(HAVE_VIEWPORT_CLIP)
DEBUGF("ERROR: "
@@ -95,27 +123,68 @@ void LCDFN(set_viewport)(struct viewport* vp)
DEBUGF("NOTE: "
#endif
"set_viewport out of bounds: x: %d y: %d width: %d height:%d\n",
- current_vp->x, current_vp->y,
- current_vp->width, current_vp->height);
+ vp->x, vp->y, vp->width, vp->height);
}
#endif
+ if(last_vp)
+ {
+ if ((flags & VP_FLAG_CLEAR_FLAG) == VP_FLAG_CLEAR_FLAG)
+ last_vp->flags &= ~flags;
+ else
+ last_vp->flags |= flags;
+ }
+
+ return last_vp;
+}
+
+struct viewport* LCDFN(set_viewport)(struct viewport* vp)
+{
+ return LCDFN(set_viewport_ex)(vp, VP_FLAG_VP_DIRTY);
}
struct viewport *LCDFN(get_viewport)(bool *is_default)
{
- *is_default = (current_vp == &default_vp);
- return current_vp;
+#if 0
+ *is_default = memcmp(LCDFN(current_viewport),
+ &default_vp, sizeof(struct viewport)) == 0;
+#else
+ *is_default = LCDFN(current_viewport) == &default_vp;
+#endif
+
+ return LCDFN(current_viewport);
}
void LCDFN(update_viewport)(void)
{
- LCDFN(update_rect)(current_vp->x, current_vp->y,
- current_vp->width, current_vp->height);
+ struct viewport* vp = LCDFN(current_viewport);
+ if (vp->buffer->stride != LCDFN(framebuffer_default.stride))
+ {
+ LCDFN(update_viewport_rect)(0,0, vp->width, vp->height);
+ return;
+ }
+ LCDFN(update_rect)(vp->x, vp->y, vp->width, vp->height);
}
void LCDFN(update_viewport_rect)(int x, int y, int width, int height)
{
- LCDFN(update_rect)(current_vp->x + x, current_vp->y + y, width, height);
+ struct viewport* vp = LCDFN(current_viewport);
+
+ /* handle the case of viewport with differing stride from main screen */
+ if (vp->buffer->stride != LCDFN(framebuffer_default.stride))
+ {
+ struct frame_buffer_t *fb = vp->buffer;
+ viewport_set_buffer(vp, NULL, 0);
+
+ LCDFN(bitmap_part)
+ (fb->FBFN(ptr), vp->x, vp->y, fb->stride,
+ vp->x + x, vp->y + y, width, height);
+
+ LCDFN(update_rect)(vp->x + x, vp->y + y, width, height);
+ viewport_set_buffer(vp, fb, 0);
+ return;
+ }
+
+ LCDFN(update_rect)(vp->x + x, vp->y + y, width, height);
}
#ifndef BOOTLOADER
@@ -123,9 +192,9 @@ void LCDFN(update_viewport_rect)(int x, int y, int width, int height)
static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
{
unsigned short *ucs;
- font_lock(current_vp->font, true);
- struct font* pf = font_get(current_vp->font);
- int vp_flags = current_vp->flags;
+ font_lock(LCDFN(current_viewport)->font, true);
+ struct font* pf = font_get(LCDFN(current_viewport)->font);
+ int vp_flags = LCDFN(current_viewport)->flags;
int rtl_next_non_diac_width, last_non_diacritic_width;
if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0)
@@ -136,13 +205,13 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
/* center takes precedence */
if (vp_flags & VP_FLAG_ALIGN_CENTER)
{
- x = ((current_vp->width - w)/ 2) + x;
+ x = ((LCDFN(current_viewport)->width - w)/ 2) + x;
if (x < 0)
x = 0;
}
else
{
- x = current_vp->width - w - x;
+ x = LCDFN(current_viewport)->width - w - x;
x += ofs;
ofs = 0;
}
@@ -158,7 +227,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
int width, base_width, drawmode = 0, base_ofs = 0;
const unsigned short next_ch = ucs[1];
- if (x >= current_vp->width)
+ if (x >= LCDFN(current_viewport)->width)
break;
is_diac = is_diacritic(*ucs, &is_rtl);
@@ -219,8 +288,8 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
* buffer using OR, and then draw the final bitmap instead of the
* chars, without touching the drawmode
**/
- drawmode = current_vp->drawmode;
- current_vp->drawmode = DRMODE_FG;
+ drawmode = LCDFN(current_viewport)->drawmode;
+ LCDFN(current_viewport)->drawmode = DRMODE_FG;
base_ofs = (base_width - width) / 2;
}
@@ -237,7 +306,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
y, width - ofs, pf->height);
if (is_diac)
{
- current_vp->drawmode = drawmode;
+ LCDFN(current_viewport)->drawmode = drawmode;
}
if (next_ch)
@@ -256,7 +325,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
}
}
}
- font_lock(current_vp->font, false);
+ font_lock(LCDFN(current_viewport)->font, false);
}
#else /* BOOTLOADER */
/* put a string at a given pixel position, skipping first ofs pixel columns */
@@ -375,7 +444,7 @@ static struct scrollinfo* find_scrolling_line(int x, int y)
for(i=0; i<LCDFN(scroll_info).lines; i++)
{
s = &LCDFN(scroll_info).scroll[i];
- if (s->x == x && s->y == y && s->vp == current_vp)
+ if (s->x == x && s->y == y && s->vp == LCDFN(current_viewport))
return s;
}
return NULL;
@@ -411,13 +480,13 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
/* prepare rectangle for scrolling. x and y must be calculated early
* for find_scrolling_line() to work */
- cwidth = font_get(current_vp->font)->maxwidth;
- height = font_get(current_vp->font)->height;
+ cwidth = font_get(LCDFN(current_viewport)->font)->maxwidth;
+ height = font_get(LCDFN(current_viewport)->font)->height;
y = y * (linebased ? height : 1);
x = x * (linebased ? cwidth : 1);
- width = current_vp->width - x;
+ width = LCDFN(current_viewport)->width - x;
- if (y >= current_vp->height)
+ if (y >= LCDFN(current_viewport)->height)
return false;
s = find_scrolling_line(x, y);
@@ -430,7 +499,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
* the string width is too small to scroll the scrolling line is
* cleared as well */
if (w < width || restart) {
- LCDFN(scroll_stop_viewport_rect)(current_vp, x, y, width, height);
+ LCDFN(scroll_stop_viewport_rect)(LCDFN(current_viewport), x, y, width, height);
LCDFN(putsxyofs)(x, y, x_offset, string);
/* nothing to scroll, or out of scrolling lines. Either way, get out */
if (w < width || LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES))
@@ -443,7 +512,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
strlcpy(s->linebuffer, string, sizeof(s->linebuffer));
/* scroll bidirectional or forward only depending on the string width */
if ( LCDFN(scroll_info).bidir_limit ) {
- s->bidir = w < (current_vp->width) *
+ s->bidir = w < (LCDFN(current_viewport)->width) *
(100 + LCDFN(scroll_info).bidir_limit) / 100;
}
else
@@ -457,7 +526,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
s->y = y;
s->width = width;
s->height = height;
- s->vp = current_vp;
+ s->vp = LCDFN(current_viewport);
s->start_tick = current_tick + LCDFN(scroll_info).delay;
LCDFN(scroll_info).lines++;
} else {
@@ -497,11 +566,6 @@ bool LCDFN(puts_scroll)(int x, int y, const unsigned char *string)
#if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD)
/* see lcd-16bit-common.c for others */
-#ifdef MAIN_LCD
-#define THIS_STRIDE STRIDE_MAIN
-#else
-#define THIS_STRIDE STRIDE_REMOTE
-#endif
void LCDFN(bmp_part)(const struct bitmap* bm, int src_x, int src_y,
int x, int y, int width, int height)
diff --git a/firmware/drivers/lcd-color-common.c b/firmware/drivers/lcd-color-common.c
index c8bfd2d6b3..60e95a25ca 100644
--- a/firmware/drivers/lcd-color-common.c
+++ b/firmware/drivers/lcd-color-common.c
@@ -36,13 +36,23 @@ enum fill_opt {
};
/*** globals ***/
-fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
+static fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16);
-fb_data *lcd_framebuffer = &lcd_static_framebuffer[0][0];
+
+static void *lcd_frameaddress_default(int x, int y);
static fb_data* lcd_backdrop = NULL;
static long lcd_backdrop_offset IDATA_ATTR = 0;
+/* shouldn't be changed unless you want system-wide framebuffer changes! */
+struct frame_buffer_t lcd_framebuffer_default =
+{
+ .fb_ptr = &lcd_static_framebuffer[0][0],
+ .get_address_fn = &lcd_frameaddress_default,
+ .stride = STRIDE_MAIN(LCD_WIDTH, LCD_HEIGHT),
+ .elems = (LCD_FBWIDTH*LCD_FBHEIGHT),
+};
+
static struct viewport default_vp =
{
.x = 0,
@@ -51,15 +61,32 @@ static struct viewport default_vp =
.height = LCD_HEIGHT,
.font = FONT_SYSFIXED,
.drawmode = DRMODE_SOLID,
- .fg_pattern = LCD_DEFAULT_FG,
- .bg_pattern = LCD_DEFAULT_BG,
+ .buffer = NULL,
+ .fg_pattern = LCD_DEFAULT_FG,
+ .bg_pattern = LCD_DEFAULT_BG,
};
-static struct viewport* current_vp IDATA_ATTR = &default_vp;
+struct viewport* lcd_current_viewport IDATA_ATTR;
+
+static void *lcd_frameaddress_default(int x, int y)
+{
+ /* the default expects a buffer the same size as the screen */
+ struct frame_buffer_t *fb = lcd_current_viewport->buffer;
+
+#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
+ return fb->fb_ptr + element;/*(element % fb->elems);*/
+}
/* LCD init */
void lcd_init(void)
{
+ /* Initialize the viewport */
+ lcd_set_viewport(NULL);
+
lcd_clear_display();
/* Call device specific init */
@@ -70,77 +97,77 @@ void lcd_init(void)
/* Clear the whole display */
void lcd_clear_display(void)
{
- struct viewport* old_vp = current_vp;
+ struct viewport* old_vp = lcd_current_viewport;
- current_vp = &default_vp;
+ lcd_current_viewport = &default_vp;
lcd_clear_viewport();
- current_vp = old_vp;
+ lcd_current_viewport = old_vp;
}
/*** parameter handling ***/
void lcd_set_drawmode(int mode)
{
- current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
+ lcd_current_viewport->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
}
int lcd_get_drawmode(void)
{
- return current_vp->drawmode;
+ return lcd_current_viewport->drawmode;
}
void lcd_set_foreground(unsigned color)
{
- current_vp->fg_pattern = color;
+ lcd_current_viewport->fg_pattern = color;
}
unsigned lcd_get_foreground(void)
{
- return current_vp->fg_pattern;
+ return lcd_current_viewport->fg_pattern;
}
void lcd_set_background(unsigned color)
{
- current_vp->bg_pattern = color;
+ lcd_current_viewport->bg_pattern = color;
}
unsigned lcd_get_background(void)
{
- return current_vp->bg_pattern;
+ return lcd_current_viewport->bg_pattern;
}
void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color)
{
lcd_set_drawmode(mode);
- current_vp->fg_pattern = fg_color;
- current_vp->bg_pattern = bg_color;
+ lcd_current_viewport->fg_pattern = fg_color;
+ lcd_current_viewport->bg_pattern = bg_color;
}
int lcd_getwidth(void)
{
- return current_vp->width;
+ return lcd_current_viewport->width;
}
int lcd_getheight(void)
{
- return current_vp->height;
+ return lcd_current_viewport->height;
}
void lcd_setfont(int newfont)
{
- current_vp->font = newfont;
+ lcd_current_viewport->font = newfont;
}
int lcd_getfont(void)
{
- return current_vp->font;
+ return lcd_current_viewport->font;
}
int lcd_getstringsize(const unsigned char *str, int *w, int *h)
{
- return font_getstringsize(str, w, h, current_vp->font);
+ return font_getstringsize(str, w, h, lcd_current_viewport->font);
}
void lcd_set_backdrop(fb_data* backdrop)
@@ -148,7 +175,7 @@ void lcd_set_backdrop(fb_data* backdrop)
lcd_backdrop = backdrop;
if (backdrop)
{
- lcd_backdrop_offset = (intptr_t)backdrop - (intptr_t)lcd_framebuffer;
+ lcd_backdrop_offset = (intptr_t)backdrop - (intptr_t)FBADDR(0,0);
lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop;
}
else
@@ -166,14 +193,14 @@ fb_data* lcd_get_backdrop(void)
/* Set a single pixel */
void lcd_drawpixel(int x, int y)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
+ && ((unsigned)y < (unsigned)lcd_current_viewport->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCD_WIDTH)
&& ((unsigned)y < (unsigned)LCD_HEIGHT)
#endif
)
- lcd_fastpixelfuncs[current_vp->drawmode](FBADDR(current_vp->x+x, current_vp->y+y));
+ lcd_fastpixelfuncs[lcd_current_viewport->drawmode](FBADDR(lcd_current_viewport->x+x, lcd_current_viewport->y+y));
}
/* Draw a line */
@@ -185,7 +212,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
int d, dinc1, dinc2;
int x, xinc1, xinc2;
int y, yinc1, yinc2;
- lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
+ lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode];
deltay = abs(y2 - y1);
if (deltay == 0)
@@ -241,14 +268,14 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
for (i = 0; i < numpixels; i++)
{
- if ( ((unsigned)x < (unsigned)current_vp->width)
- && ((unsigned)y < (unsigned)current_vp->height)
+ if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
+ && ((unsigned)y < (unsigned)lcd_current_viewport->height)
#if defined(HAVE_VIEWPORT_CLIP)
&& ((unsigned)x < (unsigned)LCD_WIDTH)
&& ((unsigned)y < (unsigned)LCD_HEIGHT)
#endif
)
- pfunc(FBADDR(x + current_vp->x, y + current_vp->y));
+ pfunc(FBADDR(x + lcd_current_viewport->x, y + lcd_current_viewport->y));
if (d < 0)
{
@@ -307,9 +334,9 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y,
int x, int y, int width, int height)
{
- int bitmap_stride = STRIDE_MAIN(bm->width, bm->height);
+ int bitmap_stride = LCD_FBSTRIDE(bm->width, bm->height);
if (bm->format == FORMAT_MONO)
- lcd_mono_bitmap_part(bm->data, src_x, src_y, bitmap_stride, x, y, width, height);
+ lcd_mono_bitmap_part(bm->data, src_x, src_y, bm->width, x, y, width, height);
else if (bm->alpha_offset > 0)
lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset,
src_x, src_y, x, y, width, height,
@@ -554,7 +581,7 @@ void lcd_blit_yuv(unsigned char * const src[3],
void lcd_gradient_fillrect_part(int x, int y, int width, int height,
unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip)
{
- int old_pattern = current_vp->fg_pattern;
+ int old_pattern = lcd_current_viewport->fg_pattern;
int step_mul, i;
int x1, x2;
x1 = x;
@@ -581,14 +608,14 @@ void lcd_gradient_fillrect_part(int x, int y, int width, int height,
}
for(i = y; i < y + height; i++) {
- current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
+ lcd_current_viewport->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
lcd_hline(x1, x2, i);
h_r -= rstep;
h_g -= gstep;
h_b -= bstep;
}
- current_vp->fg_pattern = old_pattern;
+ lcd_current_viewport->fg_pattern = old_pattern;
}
/* Fill a rectangle with a gradient. The gradient's color will fade from
diff --git a/firmware/drivers/lcd-scroll.c b/firmware/drivers/lcd-scroll.c
index 5d66788093..d8bfd72dde 100644
--- a/firmware/drivers/lcd-scroll.c
+++ b/firmware/drivers/lcd-scroll.c
@@ -156,8 +156,9 @@ bool LCDFN(scroll_now)(struct scrollinfo *s)
}
}
- /* Stash and restore these three, so that the scroll_func
+ /* Stash and restore these four, so that the scroll_func
* can do whatever it likes without destroying the state */
+ struct frame_buffer_t *framebuf = s->vp->buffer;
unsigned drawmode;
#if LCD_DEPTH > 1
unsigned fg_pattern, bg_pattern;
@@ -174,6 +175,7 @@ bool LCDFN(scroll_now)(struct scrollinfo *s)
s->vp->bg_pattern = bg_pattern;
#endif
s->vp->drawmode = drawmode;
+ s->vp->buffer = framebuf;
return ended;
}
@@ -205,7 +207,7 @@ static void LCDFN(scroll_worker)(void)
* be switched early so that lcd_getstringsize() picks the
* correct font */
vp = LCDFN(get_viewport)(&is_default);
- LCDFN(set_viewport)(s->vp);
+ LCDFN(set_viewport_ex)(s->vp, 0); /* don't mark the last vp as dirty */
makedelay = false;
step = si->step;
@@ -218,7 +220,7 @@ static void LCDFN(scroll_worker)(void)
/* put the line onto the display now */
makedelay = LCDFN(scroll_now(s));
- LCDFN(set_viewport)(vp);
+ LCDFN(set_viewport_ex)(vp, 0); /* don't mark the last vp as dirty */
if (makedelay)
s->start_tick += si->delay + si->ticks;
diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h
index 1819a4de72..030b01c736 100644
--- a/firmware/export/lcd-remote.h
+++ b/firmware/export/lcd-remote.h
@@ -34,29 +34,12 @@
#define REMOTETYPE_H100_LCD 1
#define REMOTETYPE_H300_LCD 2
#define REMOTETYPE_H300_NONLCD 3
-int remote_type(void);
-#endif
-
-#if LCD_REMOTE_DEPTH <= 8
-#if (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED) \
- || (LCD_REMOTE_PIXELFORMAT == HORIZONTAL_INTERLEAVED)
-typedef unsigned short fb_remote_data;
-#define FB_RDATA_SZ 2
-#else
-typedef unsigned char fb_remote_data;
-#define FB_RDATA_SZ 1
-#endif
-#elif LCD_DEPTH <= 16
-typedef unsigned short fb_remote_data;
-#define FB_RDATA_SZ 2
-#else
-typedef unsigned long fb_remote_data;
-#define FB_RDATA_SZ 4
+ int remote_type(void);
#endif
#if LCD_REMOTE_DEPTH > 1 /* greyscale - 8 bit max */
#ifdef HAVE_LCD_COLOR
-extern unsigned lcd_remote_color_to_native(unsigned color);
+ extern unsigned lcd_remote_color_to_native(unsigned color);
#endif
#define LCD_REMOTE_MAX_LEVEL ((1 << LCD_REMOTE_DEPTH) - 1)
@@ -77,12 +60,19 @@ extern unsigned lcd_remote_color_to_native(unsigned color);
/* Frame buffer dimensions (format checks only cover existing targets!) */
#if LCD_REMOTE_DEPTH == 1
-#define LCD_REMOTE_FBHEIGHT ((LCD_REMOTE_HEIGHT+7)/8)
+#define LCD_REMOTE_STRIDE(w, h) (h)
+#define LCD_REMOTE_FBSTRIDE(w, h) ((h+7)/8)
+#define LCD_REMOTE_FBHEIGHT LCD_REMOTE_FBSTRIDE(LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT)
+#define LCD_REMOTE_NBELEMS(w, h) (((w*LCD_REMOTE_FBSTRIDE(w, h)) + h) / sizeof(fb_remote_data))
#elif LCD_REMOTE_DEPTH == 2
#if LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED
-#define LCD_REMOTE_FBHEIGHT ((LCD_REMOTE_HEIGHT+7)/8)
+#define LCD_REMOTE_STRIDE(w, h) (h)
+#define LCD_REMOTE_FBSTRIDE(w, h) ((h+7)/8)
+#define LCD_REMOTE_FBHEIGHT LCD_REMOTE_FBSTRIDE(LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT)
+#define LCD_REMOTE_NBELEMS(w, h) (((w*LCD_REMOTE_FBSTRIDE(w, h)) + h) / sizeof(fb_remote_data))
#endif
#endif /* LCD_REMOTE_DEPTH */
+
/* Set defaults if not defined different yet. The defaults apply to both
* dimensions for LCD_REMOTE_DEPTH >= 8 */
#ifndef LCD_REMOTE_FBWIDTH
@@ -92,11 +82,20 @@ extern unsigned lcd_remote_color_to_native(unsigned color);
#define LCD_REMOTE_FBHEIGHT LCD_REMOTE_HEIGHT
#endif
-/* The actual framebuffer */
-extern fb_remote_data *lcd_remote_framebuffer;
-extern fb_remote_data lcd_remote_static_framebuffer[LCD_REMOTE_FBHEIGHT][LCD_REMOTE_FBWIDTH];
-#define FBREMOTEADDR(x, y) (lcd_remote_framebuffer + ((y) * LCD_REMOTE_FBWIDTH) + (x))
-#define FRAMEBUFFER_REMOTE_SIZE (sizeof(lcd_remote_static_framebuffer))
+#ifndef LCD_REMOTE_NBELEMS
+/* At this time (2020) known remote screens only have vertical stride */
+#define LCD_REMOTE_NBELEMS(w, h) ((w*STRIDE_REMOTE(w, h)) + h) / sizeof(fb_remote_data))
+#define LCD_REMOTE_STRIDE(w, h) STRIDE_REMOTE(w, h)
+#define LCD_REMOTE_FBSTRIDE(w, h) STRIDE_REMOTE(w, h)
+#endif
+
+#ifndef LCD_REMOTE_NATIVE_STRIDE
+#define LCD_REMOTE_NATIVE_STRIDE(s) (s)
+#endif
+
+extern struct viewport* lcd_remote_current_viewport;
+#define FBREMOTEADDR(x,y) (fb_remote_data *)(lcd_remote_current_viewport->buffer->get_address_fn(x, y))
+#define FRAMEBUFFER_REMOTE_SIZE (sizeof(fb_remote_data)*LCD_REMOTE_FBWIDTH*LCD_REMOTE_FBHEIGHT)
#if LCD_REMOTE_DEPTH > 1
extern void lcd_remote_set_foreground(unsigned foreground);
@@ -112,13 +111,13 @@ extern void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x,
int src_y, int stride, int x, int y,
int width, int height);
extern void lcd_remote_mono_bitmap(const unsigned char *src, int x, int y,
- int width, int height);
+ int width, int height);
extern void lcd_remote_bitmap_transparent_part(const fb_remote_data *src,
int src_x, int src_y,
int stride, int x, int y,
int width, int height);
extern void lcd_bitmap_remote_transparent(const fb_remote_data *src, int x,
- int y, int width, int height);
+ int y, int width, int height);
#else /* LCD_REMOTE_DEPTH == 1 */
#define lcd_remote_mono_bitmap lcd_remote_bitmap
#define lcd_remote_mono_bitmap_part lcd_remote_bitmap_part
@@ -137,7 +136,7 @@ extern void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x,
extern void lcd_remote_bitmap(const fb_remote_data *src, int x, int y,
int width, int height);
extern void lcd_remote_nine_segment_bmp(const struct bitmap* bm, int x, int y,
- int width, int height);
+ int width, int height);
/* Low-level drawing function types */
typedef void lcd_remote_pixelfunc_type(int x, int y);
@@ -146,17 +145,17 @@ typedef void lcd_remote_blockfunc_type(fb_remote_data *address, unsigned mask,
/* low level drawing function pointer arrays */
#if LCD_REMOTE_DEPTH > 1
-extern lcd_remote_pixelfunc_type* const *lcd_remote_pixelfuncs;
-extern lcd_remote_blockfunc_type* const *lcd_remote_blockfuncs;
+ extern lcd_remote_pixelfunc_type* const *lcd_remote_pixelfuncs;
+ extern lcd_remote_blockfunc_type* const *lcd_remote_blockfuncs;
#else
-extern lcd_remote_pixelfunc_type* const lcd_remote_pixelfuncs[8];
-extern lcd_remote_blockfunc_type* const lcd_remote_blockfuncs[8];
+ extern lcd_remote_pixelfunc_type* const lcd_remote_pixelfuncs[8];
+ extern lcd_remote_blockfunc_type* const lcd_remote_blockfuncs[8];
#endif
#endif /* HAVE_LCD_REMOTE */
#ifdef HAVE_REMOTE_LCD_TICKING
-void lcd_remote_emireduce(bool state);
+ void lcd_remote_emireduce(bool state);
#endif
void lcd_remote_init_device(void);
@@ -170,7 +169,10 @@ extern void lcd_remote_init(void);
extern int lcd_remote_default_contrast(void);
extern void lcd_remote_set_contrast(int val);
-extern void lcd_remote_set_viewport(struct viewport* vp);
+extern struct viewport* lcd_remote_init_viewport(struct viewport* vp);
+extern struct viewport* lcd_remote_set_viewport(struct viewport* vp);
+extern struct viewport* lcd_remote_set_viewport_ex(struct viewport* vp, int flags);
+
extern void lcd_remote_clear_display(void);
extern void lcd_remote_clear_viewport(void);
extern void lcd_remote_puts(int x, int y, const unsigned char *str);
@@ -212,7 +214,7 @@ extern void lcd_remote_bidir_scroll(int threshold);
extern void lcd_remote_scroll_step(int pixels);
extern void lcd_remote_bmp_part(const struct bitmap* bm, int src_x, int src_y,
- int x, int y, int width, int height);
+ int x, int y, int width, int height);
extern void lcd_remote_bmp(const struct bitmap* bm, int x, int y);
#endif /* __LCD_REMOTE_H__ */
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index ae06307dca..af734da913 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -23,30 +23,11 @@
#define __LCD_H__
#include <stdbool.h>
+#include <stddef.h>
#include "cpu.h"
#include "config.h"
#include "events.h"
-#define VP_FLAG_ALIGN_RIGHT 0x01
-#define VP_FLAG_ALIGN_CENTER 0x02
-
-#define VP_FLAG_ALIGNMENT_MASK \
- (VP_FLAG_ALIGN_RIGHT|VP_FLAG_ALIGN_CENTER)
-
-#define VP_IS_RTL(vp) (((vp)->flags & VP_FLAG_ALIGNMENT_MASK) == VP_FLAG_ALIGN_RIGHT)
-
-struct viewport {
- int x;
- int y;
- int width;
- int height;
- int flags;
- int font;
- int drawmode;
- /* needed for even for mono displays to support greylib */
- unsigned fg_pattern;
- unsigned bg_pattern;
-};
/* Frame buffer stride
*
@@ -101,7 +82,7 @@ enum screen_type {
struct scrollinfo;
-#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
+#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
#define STRIDE_MAIN(w, h) (h)
#else
#define STRIDE_MAIN(w, h) (w)
@@ -115,46 +96,105 @@ struct scrollinfo;
#if LCD_DEPTH <=8
#if (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) \
|| (LCD_PIXELFORMAT == HORIZONTAL_INTERLEAVED)
-typedef unsigned short fb_data;
+ typedef unsigned short fb_data;
#define FB_DATA_SZ 2
#else
-typedef unsigned char fb_data;
+ typedef unsigned char fb_data;
#define FB_DATA_SZ 1
#endif
#elif LCD_DEPTH <= 16
-typedef unsigned short fb_data;
+ typedef unsigned short fb_data;
#define FB_DATA_SZ 2
#elif LCD_DEPTH <= 24
-struct _fb_pixel {
- unsigned char b, g, r;
-};
-typedef struct _fb_pixel fb_data;
+ struct _fb_pixel {
+ unsigned char b, g, r;
+ };
+ typedef struct _fb_pixel fb_data;
#define FB_DATA_SZ 3
#else /* LCD_DEPTH > 24 */
#if (LCD_PIXELFORMAT == XRGB8888)
-struct _fb_pixel {
- unsigned char b, g, r, x;
-};
-typedef struct _fb_pixel fb_data;
+ struct _fb_pixel {
+ unsigned char b, g, r, x;
+ };
+ typedef struct _fb_pixel fb_data;
#else
-typedef unsigned long fb_data;
+ typedef unsigned long fb_data;
#endif
#define FB_DATA_SZ 4
#endif /* LCD_DEPTH */
+#ifdef HAVE_REMOTE_LCD
+#if LCD_REMOTE_DEPTH <= 8
+#if (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED) \
+ || (LCD_REMOTE_PIXELFORMAT == HORIZONTAL_INTERLEAVED)
+ typedef unsigned short fb_remote_data;
+#define FB_RDATA_SZ 2
+#else
+ typedef unsigned char fb_remote_data;
+#define FB_RDATA_SZ 1
+#endif
+#elif LCD_DEPTH <= 16
+ typedef unsigned short fb_remote_data;
+#define FB_RDATA_SZ 2
+#else
+ typedef unsigned long fb_remote_data;
+#define FB_RDATA_SZ 4
+#endif
+#endif
+
#if defined(HAVE_LCD_MODES)
-void lcd_set_mode(int mode);
+ void lcd_set_mode(int mode);
#define LCD_MODE_RGB565 0x00000001
#define LCD_MODE_YUV 0x00000002
#define LCD_MODE_PAL256 0x00000004
#if HAVE_LCD_MODES & LCD_MODE_PAL256
- void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
+ void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
int width, int height);
- void lcd_pal256_update_pal(fb_data *palette);
+ void lcd_pal256_update_pal(fb_data *palette);
#endif
#endif
+struct frame_buffer_t {
+ union
+ {
+ void *data;
+ char *ch_ptr;
+ fb_data *fb_ptr;
+#ifdef HAVE_REMOTE_LCD
+ fb_remote_data *fb_remote_ptr;
+#endif
+ };
+ void *(*get_address_fn)(int x, int y);
+ ptrdiff_t stride;
+ size_t elems;
+};
+
+#define VP_FLAG_ALIGN_RIGHT 0x01
+#define VP_FLAG_ALIGN_CENTER 0x02
+
+#define VP_FLAG_ALIGNMENT_MASK \
+ (VP_FLAG_ALIGN_RIGHT|VP_FLAG_ALIGN_CENTER)
+
+#define VP_IS_RTL(vp) (((vp)->flags & VP_FLAG_ALIGNMENT_MASK) == VP_FLAG_ALIGN_RIGHT)
+
+#define VP_FLAG_VP_DIRTY 0x4000
+#define VP_FLAG_CLEAR_FLAG 0x8000
+#define VP_FLAG_VP_SET_CLEAN (VP_FLAG_CLEAR_FLAG | VP_FLAG_VP_DIRTY)
+
+struct viewport {
+ int x;
+ int y;
+ int width;
+ int height;
+ int flags;
+ int font;
+ int drawmode;
+ struct frame_buffer_t *buffer;
+ /* needed for even for mono displays to support greylib */
+ unsigned fg_pattern;
+ unsigned bg_pattern;
+};
/* common functions */
extern void lcd_write_command(int byte);
@@ -171,7 +211,10 @@ extern int lcd_getwidth(void);
extern int lcd_getheight(void);
extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
-extern void lcd_set_viewport(struct viewport* vp);
+extern struct viewport* lcd_init_viewport(struct viewport* vp);
+extern struct viewport* lcd_set_viewport(struct viewport* vp);
+extern struct viewport* lcd_set_viewport_ex(struct viewport* vp, int flags);
+
extern void lcd_update(void);
extern void lcd_update_viewport(void);
extern void lcd_update_viewport_rect(int x, int y, int width, int height);
@@ -193,15 +236,15 @@ extern bool lcd_putsxy_scroll_func(int x, int y, const unsigned char *string,
#if defined(HAVE_LCD_COLOR)
#if MEMORYSIZE > 2
#define LCD_YUV_DITHER 0x1
-extern void lcd_yuv_set_options(unsigned options);
-extern void lcd_blit_yuv(unsigned char * const src[3],
+ extern void lcd_yuv_set_options(unsigned options);
+ extern void lcd_blit_yuv(unsigned char * const src[3],
int src_x, int src_y, int stride,
int x, int y, int width, int height);
#endif /* MEMORYSIZE > 2 */
#else
-extern void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
+ extern void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
int bheight, int stride);
-extern void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
+ extern void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
int bx, int by, int bwidth, int bheight,
int stride);
#endif
@@ -211,9 +254,9 @@ extern void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
extern void lcd_update_rect(int x, int y, int width, int height);
#ifdef HAVE_REMOTE_LCD
-extern void lcd_remote_update(void);
-/* update a fraction of the screen */
-extern void lcd_remote_update_rect(int x, int y, int width, int height);
+ extern void lcd_remote_update(void);
+ /* update a fraction of the screen */
+ extern void lcd_remote_update_rect(int x, int y, int width, int height);
#endif /* HAVE_REMOTE_LCD */
/* Bitmap formats */
@@ -239,13 +282,13 @@ enum
typedef void lcd_pixelfunc_type(int x, int y);
typedef void lcd_blockfunc_type(fb_data *address, unsigned mask, unsigned bits);
#if LCD_DEPTH >= 8
-typedef void lcd_fastpixelfunc_type(fb_data *address);
+ typedef void lcd_fastpixelfunc_type(fb_data *address);
#endif
#if defined(HAVE_LCD_COLOR) && defined(LCD_REMOTE_DEPTH) && \
LCD_REMOTE_DEPTH > 1
/* Just return color for screens use */
-static inline unsigned lcd_color_to_native(unsigned color)
+ static inline unsigned lcd_color_to_native(unsigned color)
{ return color; }
#define SCREEN_COLOR_TO_NATIVE(screen, color) (screen)->color_to_native(color)
#else
@@ -286,7 +329,7 @@ static inline unsigned lcd_color_to_native(unsigned color)
(((b) >> 3) << 8) )
/* swap color once - not currenly used in static inits */
#define _SWAPUNPACK(x, _unp_) \
- ({ typeof (x) _x_ = swap16(x); _unp_(_x_); })
+ ({ typeof (x) _x_ = swap16(x); _unp_(_x_); })
#define RGB_UNPACK_RED(x) _SWAPUNPACK((x), _RGB_UNPACK_RED)
#define RGB_UNPACK_GREEN(x) _SWAPUNPACK((x), _RGB_UNPACK_GREEN)
#define RGB_UNPACK_BLUE(x) _SWAPUNPACK((x), _RGB_UNPACK_BLUE)
@@ -374,16 +417,16 @@ static inline unsigned lcd_color_to_native(unsigned color)
* format, so it's the reverse of FB_SCALARPACK_LCD
*/
#if LCD_DEPTH >= 24
-static inline fb_data scalar_to_fb(unsigned p)
-{
- union { fb_data st; unsigned sc; } convert;
- convert.sc = p; return convert.st;
-}
-static inline unsigned fb_to_scalar(fb_data p)
-{
- union { fb_data st; unsigned sc; } convert;
- convert.st = p; return convert.sc;
-}
+ static inline fb_data scalar_to_fb(unsigned p)
+ {
+ union { fb_data st; unsigned sc; } convert;
+ convert.sc = p; return convert.st;
+ }
+ static inline unsigned fb_to_scalar(fb_data p)
+ {
+ union { fb_data st; unsigned sc; } convert;
+ convert.st = p; return convert.sc;
+ }
#define FB_RGBPACK(r_, g_, b_) ((fb_data){.r = r_, .g = g_, .b = b_})
#define FB_RGBPACK_LCD(r_, g_, b_) FB_RGBPACK(r_, g_, b_)
#define FB_UNPACK_RED(fb) ((fb).r)
@@ -411,17 +454,28 @@ static inline unsigned fb_to_scalar(fb_data p)
/* Frame buffer dimensions */
#if LCD_DEPTH == 1
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
-#define LCD_FBWIDTH ((LCD_WIDTH+7)/8)
+#define LCD_FBSTRIDE(w, h) ((w+7)/8)
+#define LCD_FBWIDTH LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((h*LCD_FBSTRIDE(w, h)) + w) / sizeof(fb_data))
#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
-#define LCD_FBHEIGHT ((LCD_HEIGHT+7)/8)
+#define LCD_FBSTRIDE(w, h) ((h+7)/8)
+#define LCD_FBHEIGHT LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((w*LCD_FBSTRIDE(w, h)) + h) / sizeof(fb_data))
#endif /* LCD_PIXELFORMAT */
#elif LCD_DEPTH == 2
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
-#define LCD_FBWIDTH ((LCD_WIDTH+3)/4)
+#define LCD_FBSTRIDE(w, h) ((w+3)>>2)
+#define LCD_NATIVE_STRIDE(s) LCD_FBSTRIDE(s, s)
+#define LCD_FBWIDTH LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((h*LCD_FBSTRIDE(w, h)) + w) / sizeof(fb_data))
#elif LCD_PIXELFORMAT == VERTICAL_PACKING
-#define LCD_FBHEIGHT ((LCD_HEIGHT+3)/4)
+#define LCD_FBSTRIDE(w, h) ((h+3)/4)
+#define LCD_FBHEIGHT LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((w*LCD_FBSTRIDE(w, h)) + h) / sizeof(fb_data))
#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
-#define LCD_FBHEIGHT ((LCD_HEIGHT+7)/8)
+#define LCD_FBSTRIDE(w, h) ((h+7)/8)
+#define LCD_FBHEIGHT LCD_FBSTRIDE(LCD_WIDTH, LCD_HEIGHT)
+#define LCD_NBELEMS(w, h) (((w*LCD_FBSTRIDE(w, h)) + h) / sizeof(fb_data))
#endif /* LCD_PIXELFORMAT */
#endif /* LCD_DEPTH */
/* Set defaults if not defined different yet. The defaults apply to both
@@ -432,13 +486,29 @@ static inline unsigned fb_to_scalar(fb_data p)
#ifndef LCD_FBHEIGHT
#define LCD_FBHEIGHT LCD_HEIGHT
#endif
-/* The actual framebuffer */
-extern fb_data *lcd_framebuffer;
+
+#ifndef LCD_NATIVE_STRIDE
+/* 2-bit Horz is the only display that actually defines this */
+#define LCD_NATIVE_STRIDE(s) (s)
+#endif
+
+#ifndef LCD_NBELEMS
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
-#define FBADDR(x, y) (lcd_framebuffer + ((x) * LCD_FBHEIGHT) + (y))
+#define LCD_NBELEMS(w, h) ((w*STRIDE_MAIN(w, h)) + h)
#else
-#define FBADDR(x, y) (lcd_framebuffer + ((y) * LCD_FBWIDTH) + (x))
+#define LCD_NBELEMS(w, h) ((h*STRIDE_MAIN(w, h)) + w)
#endif
+#define LCD_FBSTRIDE(w, h) STRIDE_MAIN(w, h)
+#endif
+
+#ifndef LCD_STRIDE
+ #define LCD_STRIDE(w, h) STRIDE_MAIN(w, h)
+#endif
+
+extern struct viewport* lcd_current_viewport;
+
+#define FBADDR(x,y) ((fb_data*) lcd_current_viewport->buffer->get_address_fn(x, y))
+
#define FRAMEBUFFER_SIZE (sizeof(fb_data)*LCD_FBWIDTH*LCD_FBHEIGHT)
/** Port-specific functions. Enable in port config file. **/
@@ -499,7 +569,7 @@ struct bitmap {
extern void lcd_set_invert_display(bool yesno);
#ifdef HAVE_BACKLIGHT_INVERSION
-extern void lcd_set_backlight_inversion(bool yesno);
+ extern void lcd_set_backlight_inversion(bool yesno);
#endif /* HAVE_BACKLIGHT_INVERSION */
extern void lcd_set_flip(bool yesno);
@@ -510,13 +580,13 @@ extern int lcd_getfont(void);
/* low level drawing function pointer arrays */
#if LCD_DEPTH >= 8
-extern lcd_fastpixelfunc_type* const *lcd_fastpixelfuncs;
+ extern lcd_fastpixelfunc_type* const *lcd_fastpixelfuncs;
#elif LCD_DEPTH > 1
-extern lcd_pixelfunc_type* const *lcd_pixelfuncs;
-extern lcd_blockfunc_type* const *lcd_blockfuncs;
+ extern lcd_pixelfunc_type* const *lcd_pixelfuncs;
+ extern lcd_blockfunc_type* const *lcd_blockfuncs;
#else /* LCD_DEPTH == 1*/
-extern lcd_pixelfunc_type* const lcd_pixelfuncs[8];
-extern lcd_blockfunc_type* const lcd_blockfuncs[8];
+ extern lcd_pixelfunc_type* const lcd_pixelfuncs[8];
+ extern lcd_blockfunc_type* const lcd_blockfuncs[8];
#endif /* LCD_DEPTH */
extern void lcd_drawpixel(int x, int y);
@@ -526,45 +596,44 @@ extern void lcd_vline(int x, int y1, int y2);
extern void lcd_drawrect(int x, int y, int width, int height);
extern void lcd_fillrect(int x, int y, int width, int height);
extern void lcd_gradient_fillrect(int x, int y, int width, int height,
- unsigned start_rgb, unsigned end_rgb);
+ unsigned start_rgb, unsigned end_rgb);
extern void lcd_gradient_fillrect_part(int x, int y, int width, int height,
- unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip);
+ unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip);
extern void lcd_draw_border_viewport(void);
extern void lcd_fill_viewport(void);
extern void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
int stride, int x, int y, int width, int height);
extern void lcd_bitmap(const fb_data *src, int x, int y, int width,
int height);
-extern void lcd_set_framebuffer(fb_data *fb);
extern void lcd_scroll_step(int pixels);
#if LCD_DEPTH > 1
-extern void lcd_set_foreground(unsigned foreground);
-extern unsigned lcd_get_foreground(void);
-extern void lcd_set_background(unsigned background);
-extern unsigned lcd_get_background(void);
+ extern void lcd_set_foreground(unsigned foreground);
+ extern unsigned lcd_get_foreground(void);
+ extern void lcd_set_background(unsigned background);
+ extern unsigned lcd_get_background(void);
#ifdef HAVE_LCD_COLOR
-extern void lcd_set_selector_start(unsigned selector);
-extern void lcd_set_selector_end(unsigned selector);
-extern void lcd_set_selector_text(unsigned selector_text);
+ extern void lcd_set_selector_start(unsigned selector);
+ extern void lcd_set_selector_end(unsigned selector);
+ extern void lcd_set_selector_text(unsigned selector_text);
#endif
-extern void lcd_set_drawinfo(int mode, unsigned foreground,
- unsigned background);
-void lcd_set_backdrop(fb_data* backdrop);
-
-fb_data* lcd_get_backdrop(void);
-
-extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
- int stride, int x, int y, int width, int height);
-extern void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width,
- int height);
-extern void lcd_bitmap_transparent_part(const fb_data *src,
- int src_x, int src_y,
- int stride, int x, int y, int width,
- int height);
-extern void lcd_bitmap_transparent(const fb_data *src, int x, int y,
- int width, int height);
+ extern void lcd_set_drawinfo(int mode, unsigned foreground,
+ unsigned background);
+ void lcd_set_backdrop(fb_data* backdrop);
+
+ fb_data* lcd_get_backdrop(void);
+
+ extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
+ int stride, int x, int y, int width, int height);
+ extern void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width,
+ int height);
+ extern void lcd_bitmap_transparent_part(const fb_data *src,
+ int src_x, int src_y,
+ int stride, int x, int y, int width,
+ int height);
+ extern void lcd_bitmap_transparent(const fb_data *src, int x, int y,
+ int width, int height);
#else /* LCD_DEPTH == 1 */
#define lcd_mono_bitmap lcd_bitmap
#define lcd_mono_bitmap_part lcd_bitmap_part
@@ -577,10 +646,10 @@ extern void lcd_nine_segment_bmp(const struct bitmap* bm, int x, int y,
/* TODO: Impement this for remote displays if ever needed */
#if defined(LCD_DPI) && (LCD_DPI > 0)
-/* returns the pixel density of the display */
-static inline int lcd_get_dpi(void) { return LCD_DPI; }
+ /* returns the pixel density of the display */
+ static inline int lcd_get_dpi(void) { return LCD_DPI; }
#else
-extern int lcd_get_dpi(void);
+ extern int lcd_get_dpi(void);
#endif /* LCD_DPI */
#endif /* __LCD_H__ */
diff --git a/firmware/target/arm/as3525/lcd-fuze.c b/firmware/target/arm/as3525/lcd-fuze.c
index df4d668ab0..a1ccea348d 100644
--- a/firmware/target/arm/as3525/lcd-fuze.c
+++ b/firmware/target/arm/as3525/lcd-fuze.c
@@ -291,7 +291,7 @@ void lcd_update(void)
lcd_write_cmd(R_WRITE_DATA_2_GRAM);
- dbop_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
+ dbop_write_data(FBADDR(0,0), LCD_WIDTH*LCD_HEIGHT);
}
/* Update a fraction of the display. */
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c
index 5f623dc239..9621b532fe 100644
--- a/firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c
+++ b/firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c
@@ -251,7 +251,7 @@ void lcd_set_direct_fb(bool yes)
unsigned int addr;
direct_fb_access = yes;
if(yes)
- addr = ((unsigned int)&lcd_framebuffer-CONFIG_SDRAM_START) / 32;
+ addr = ((unsigned int)FBADDR(0,0)-CONFIG_SDRAM_START) / 32;
else
addr = ((unsigned int)FRAME-CONFIG_SDRAM_START) / 32;
IO_OSD_OSDWINADH = addr >> 16;
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
index c3a96a3efd..d952d3d40d 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
@@ -489,7 +489,7 @@ void lcd_update_rect(int x, int y, int width, int height)
#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
#if defined(LCD_USE_DMA)
- dma_start_transfer16( (char *)lcd_framebuffer, x, y, LCD_WIDTH,
+ dma_start_transfer16( (char *)FBADDR(0,0), x, y, LCD_WIDTH,
x, y, width, height, 2);
#else
register fb_data *dst;
@@ -514,7 +514,7 @@ void lcd_update_rect(int x, int y, int width, int height)
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
#if defined(LCD_USE_DMA)
- dma_start_transfer16( (char *)lcd_framebuffer, x, y, LCD_HEIGHT,
+ dma_start_transfer16( (char *)FBADDR(0,0), x, y, LCD_HEIGHT,
x, y, width, height, 2);
#else
fb_data *src;
diff --git a/firmware/target/coldfire/iriver/h300/lcd-h300.c b/firmware/target/coldfire/iriver/h300/lcd-h300.c
index 191c769c97..312bd70ccc 100644
--- a/firmware/target/coldfire/iriver/h300/lcd-h300.c
+++ b/firmware/target/coldfire/iriver/h300/lcd-h300.c
@@ -408,7 +408,7 @@ void lcd_update(void)
lcd_begin_write_gram();
dma_count = 1;
- SAR3 = (unsigned long)lcd_framebuffer;
+ SAR3 = (unsigned long)FBADDR(0,0);
BCR3 = LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data);
DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
| DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
diff --git a/firmware/target/coldfire/mpio/hd200/lcd-hd200.c b/firmware/target/coldfire/mpio/hd200/lcd-hd200.c
index 3c00959745..967618fce1 100644
--- a/firmware/target/coldfire/mpio/hd200/lcd-hd200.c
+++ b/firmware/target/coldfire/mpio/hd200/lcd-hd200.c
@@ -218,7 +218,7 @@ void lcd_update(void)
dma_len = LCD_WIDTH*2;
/* Initialize DMA transfer */
- SAR3 = (unsigned long)lcd_framebuffer;
+ SAR3 = (unsigned long)FBADDR(0,0);
BCR3 = LCD_WIDTH*2;
DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
| DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c
index a161406cc0..12df52c95e 100644
--- a/firmware/target/hosted/android/lcd-android.c
+++ b/firmware/target/hosted/android/lcd-android.c
@@ -83,7 +83,7 @@ void lcd_update(void)
if (display_on)
{
JNIEnv e = *env_ptr;
- jobject buffer = e->NewDirectByteBuffer(env_ptr, lcd_framebuffer,
+ jobject buffer = e->NewDirectByteBuffer(env_ptr, FBADDR(0,0),
(jlong) FRAMEBUFFER_SIZE);
e->CallVoidMethod(env_ptr, RockboxFramebuffer_instance,
@@ -97,7 +97,7 @@ void lcd_update_rect(int x, int y, int width, int height)
if (display_on)
{
JNIEnv e = *env_ptr;
- jobject buffer = e->NewDirectByteBuffer(env_ptr, lcd_framebuffer,
+ jobject buffer = e->NewDirectByteBuffer(env_ptr, FBADDR(0,0),
(jlong) FRAMEBUFFER_SIZE);
jobject rect = e->NewObject(env_ptr, AndroidRect_class, AndroidRect_constructor,
x, y, x + width, y + height);
diff --git a/firmware/target/hosted/sdl/lcd-sdl.c b/firmware/target/hosted/sdl/lcd-sdl.c
index 40ba94072b..de19de365a 100644
--- a/firmware/target/hosted/sdl/lcd-sdl.c
+++ b/firmware/target/hosted/sdl/lcd-sdl.c
@@ -39,7 +39,7 @@ void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width,
(void)max_y;
(void)getpixel;
/* Update complete screen via one blit operation (fast) */
- SDL_Surface *lcd = SDL_CreateRGBSurfaceFrom(lcd_framebuffer, LCD_FBWIDTH,
+ SDL_Surface *lcd = SDL_CreateRGBSurfaceFrom(FBADDR(0, 0), LCD_FBWIDTH,
LCD_FBHEIGHT, LCD_DEPTH,
LCD_FBWIDTH * LCD_DEPTH/8,
0, 0, 0, 0);