summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/alarm_menu.c5
-rw-r--r--apps/gui/bitmap/list.c4
-rw-r--r--apps/gui/color_picker.c8
-rw-r--r--apps/gui/pitchscreen.c5
-rw-r--r--apps/gui/quickscreen.c4
-rw-r--r--apps/gui/skin_engine/skin_backdrops.c25
-rw-r--r--apps/gui/skin_engine/skin_engine.c6
-rw-r--r--apps/gui/skin_engine/skin_engine.h2
-rw-r--r--apps/gui/skin_engine/skin_parser.c8
-rw-r--r--apps/gui/skin_engine/skin_render.c45
-rw-r--r--apps/gui/skin_engine/wps_internals.h1
-rw-r--r--apps/gui/splash.c4
-rw-r--r--apps/gui/statusbar.c5
-rw-r--r--apps/gui/usb_screen.c5
-rw-r--r--apps/gui/viewport.c26
-rw-r--r--apps/gui/viewport.h3
-rw-r--r--apps/gui/yesno.c9
-rw-r--r--apps/menus/time_menu.c4
-rw-r--r--apps/misc.c4
-rw-r--r--apps/onplay.c11
-rw-r--r--apps/plugin.c12
-rw-r--r--apps/plugin.h7
-rw-r--r--apps/plugins/doom/i_video.c10
-rw-r--r--apps/plugins/fire.c5
-rw-r--r--apps/plugins/imageviewer/imageviewer.c11
-rw-r--r--apps/plugins/imageviewer/jpeg/yuv2rgb.c12
-rw-r--r--apps/plugins/invadrox.c12
-rw-r--r--apps/plugins/lib/grey.h2
-rw-r--r--apps/plugins/lib/grey_core.c13
-rw-r--r--apps/plugins/lib/grey_parm.c4
-rw-r--r--apps/plugins/lib/osd.c27
-rw-r--r--apps/plugins/lib/xlcd.h2
-rw-r--r--apps/plugins/lib/xlcd_core.c9
-rw-r--r--apps/plugins/lib/xlcd_draw.c14
-rw-r--r--apps/plugins/lib/xlcd_scroll.c107
-rw-r--r--apps/plugins/lua/rocklib_img.c8
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c12
-rw-r--r--apps/plugins/oscilloscope.c4
-rwxr-xr-xapps/plugins/pacbox/pacbox.c6
-rw-r--r--apps/plugins/pictureflow/pictureflow.c6
-rw-r--r--apps/plugins/plasma.c11
-rw-r--r--apps/plugins/puzzles/rockbox.c17
-rw-r--r--apps/plugins/rockboy/lcd.c15
-rw-r--r--apps/plugins/rockboy/sys_rockbox.c10
-rw-r--r--apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c11
-rw-r--r--apps/plugins/test_resize.c4
-rw-r--r--apps/plugins/test_viewports.c27
-rw-r--r--apps/plugins/xworld/sys.c21
-rw-r--r--apps/plugins/zxbox/zxvid_16bpp.c11
-rw-r--r--apps/plugins/zxbox/zxvid_2bpp.c13
-rw-r--r--apps/recorder/keyboard.c4
-rw-r--r--apps/screen_access.c21
-rw-r--r--apps/screen_access.h7
-rw-r--r--apps/screens.c5
-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
74 files changed, 1595 insertions, 967 deletions
diff --git a/apps/alarm_menu.c b/apps/alarm_menu.c
index 497747bd7b..62b54a84bb 100644
--- a/apps/alarm_menu.c
+++ b/apps/alarm_menu.c
@@ -60,6 +60,7 @@ int alarm_screen(void)
bool update = true;
bool hour_wrapped = false;
struct viewport vp[NB_SCREENS];
+ struct viewport * last_vp;
rtc_get_alarm(&h, &m);
@@ -91,11 +92,11 @@ int alarm_screen(void)
FOR_NB_SCREENS(i)
{
- screens[i].set_viewport(&vp[i]);
+ last_vp = screens[i].set_viewport(&vp[i]);
screens[i].putsf(0, 1, str(LANG_ALARM_MOD_TIME));
screens[i].putsf(0, 2, "%02d:%02d", h, m);
screens[i].update_viewport();
- screens[i].set_viewport(NULL);
+ screens[i].set_viewport(last_vp);
}
button = get_action(CONTEXT_SETTINGS,HZ);
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 2d3141b8cc..27121eac56 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -146,7 +146,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
struct viewport *list_text_vp = &list_text[screen];
int indent = 0;
- display->set_viewport(parent);
+ struct viewport * last_vp = display->set_viewport(parent);
display->clear_viewport();
display->scroll_stop_viewport(list_text_vp);
*list_text_vp = *parent;
@@ -332,7 +332,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
}
display->set_viewport(parent);
display->update_viewport();
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
}
#if defined(HAVE_TOUCHSCREEN)
diff --git a/apps/gui/color_picker.c b/apps/gui/color_picker.c
index 03096e5589..a32f1ee179 100644
--- a/apps/gui/color_picker.c
+++ b/apps/gui/color_picker.c
@@ -164,7 +164,7 @@ static void draw_screen(struct screen *display, char *title,
struct viewport vp;
viewport_set_defaults(&vp, display->screen_type);
- display->set_viewport(&vp);
+ struct viewport * last_vp = display->set_viewport(&vp);
display->clear_viewport();
@@ -323,7 +323,7 @@ static void draw_screen(struct screen *display, char *title,
}
display->update_viewport();
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
}
#ifdef HAVE_TOUCHSCREEN
@@ -341,7 +341,7 @@ static int touchscreen_slider(struct screen *display,
struct viewport vp;
viewport_set_defaults(&vp, display->screen_type);
- display->set_viewport(&vp);
+ struct viewport *last_vp = display->set_viewport(&vp);
button = action_get_touchscreen_press_in_vp(&x, &y, &vp);
if (button == ACTION_UNKNOWN || button == BUTTON_NONE)
@@ -373,7 +373,7 @@ static int touchscreen_slider(struct screen *display,
char_height*2 + /* + margins for bottom */
MARGIN_BOTTOM; /* colored rectangle */
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
if (y < text_top)
{
diff --git a/apps/gui/pitchscreen.c b/apps/gui/pitchscreen.c
index 0d31193fa6..b5b719ef02 100644
--- a/apps/gui/pitchscreen.c
+++ b/apps/gui/pitchscreen.c
@@ -239,6 +239,7 @@ static void pitchscreen_draw(struct screen *display, int max_lines,
char buf[32];
int w, h;
bool show_lang_pitch;
+ struct viewport *last_vp = NULL;
/* "Pitch up/Pitch down" - hide for a small screen,
* the text is drawn centered automatically
@@ -249,7 +250,7 @@ static void pitchscreen_draw(struct screen *display, int max_lines,
{
int w, h;
struct viewport *vp = &pitch_viewports[PITCH_TOP];
- display->set_viewport(vp);
+ last_vp = display->set_viewport(vp);
display->clear_viewport();
#ifdef HAVE_TOUCHSCREEN
/* two arrows in the top row, left and right column */
@@ -405,7 +406,7 @@ static void pitchscreen_draw(struct screen *display, int max_lines,
rightlabel);
}
display->update_viewport();
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
}
static int32_t pitch_increase(int32_t pitch, int32_t pitch_delta, bool allow_cutoff
diff --git a/apps/gui/quickscreen.c b/apps/gui/quickscreen.c
index 704133c1c4..421cc267ca 100644
--- a/apps/gui/quickscreen.c
+++ b/apps/gui/quickscreen.c
@@ -172,7 +172,7 @@ static void gui_quickscreen_draw(const struct gui_quickscreen *qs,
char buf[MAX_PATH];
unsigned const char *title, *value;
int temp;
- display->set_viewport(parent);
+ struct viewport *last_vp = display->set_viewport(parent);
display->clear_viewport();
for (i = 0; i < QUICKSCREEN_ITEM_COUNT; i++)
@@ -225,7 +225,7 @@ static void gui_quickscreen_draw(const struct gui_quickscreen *qs,
display->set_viewport(parent);
display->update_viewport();
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
}
static void talk_qs_option(const struct settings_list *opt, bool enqueue)
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 243fc30a3a..caf705af54 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -204,11 +204,28 @@ bool skin_backdrops_preload(void)
return retval;
}
-void* skin_backdrop_get_buffer(int backdrop_id)
+void skin_backdrop_set_buffer(int backdrop_id, struct skin_viewport *svp)
{
- if (backdrop_id < 0)
- return NULL;
- return backdrops[backdrop_id].buffer;
+ if (UNLIKELY(!svp))
+ return;
+ else if (backdrop_id < 0)
+ {
+ svp->vp.buffer = NULL; /*Default*/
+ return;
+ }
+
+ enum screen_type screen = backdrops[backdrop_id].screen;
+ svp->framebuf.ch_ptr = backdrops[backdrop_id].buffer;
+#if defined(HAVE_REMOTE_LCD)
+ if (screen == SCREEN_REMOTE)
+ svp->framebuf.elems = REMOTE_LCD_BACKDROP_BYTES / sizeof(fb_remote_data);
+ else
+#endif
+ {
+ svp->framebuf.elems = LCD_BACKDROP_BYTES / sizeof(fb_data);
+ }
+ svp->framebuf.get_address_fn = NULL; /*Default iterator*/
+ screens[screen].viewport_set_buffer(&svp->vp, &svp->framebuf);
}
void skin_backdrop_show(int backdrop_id)
diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c
index cd763def1c..049629b181 100644
--- a/apps/gui/skin_engine/skin_engine.c
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -312,7 +312,11 @@ struct wps_state *skin_get_global_state(void)
bool skin_do_full_update(enum skinnable_screens skin,
enum screen_type screen)
{
- bool ret = skins[skin][screen].needs_full_update;
+ struct viewport *vp = *(screens[screen].current_viewport);
+
+ bool vp_is_dirty = ((vp->flags & VP_FLAG_VP_SET_CLEAN) == VP_FLAG_VP_DIRTY);
+
+ bool ret = (skins[skin][screen].needs_full_update || vp_is_dirty);
skins[skin][screen].needs_full_update = false;
return ret;
}
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h
index 55839608be..3b757a5f8b 100644
--- a/apps/gui/skin_engine/skin_engine.h
+++ b/apps/gui/skin_engine/skin_engine.h
@@ -70,7 +70,7 @@ void skin_backdrop_show(int backdrop_id);
void skin_backdrop_load_setting(void);
void skin_backdrop_unload(int backdrop_id);
#define BACKDROP_BUFFERNAME "#backdrop_buffer#"
-void* skin_backdrop_get_buffer(int backdrop_id);
+void skin_backdrop_set_buffer(int backdrop_id, struct skin_viewport *svp);
/* do the button loop as often as required for the peak meters to update
* with a good refresh rate.
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index f3a23377ef..e1a8118190 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -259,7 +259,7 @@ static int parse_statusbar_tags(struct skin_element* element,
}
else
{
- struct skin_viewport *default_vp = SKINOFFSETTOPTR(skin_buffer, first_viewport->data);
+ struct skin_viewport *skin_default = SKINOFFSETTOPTR(skin_buffer, first_viewport->data);
if (first_viewport->params_count == 0)
{
wps_data->wps_sb_tag = true;
@@ -267,11 +267,11 @@ static int parse_statusbar_tags(struct skin_element* element,
}
if (wps_data->show_sb_on_wps)
{
- viewport_set_defaults(&default_vp->vp, curr_screen);
+ viewport_set_defaults(&skin_default->vp, curr_screen);
}
else
{
- viewport_set_fullscreen(&default_vp->vp, curr_screen);
+ viewport_set_fullscreen(&skin_default->vp, curr_screen);
}
#ifdef HAVE_REMOTE_LCD
/* This parser requires viewports which will use the settings font to
@@ -279,7 +279,7 @@ static int parse_statusbar_tags(struct skin_element* element,
* the current real font id. So force 1 here it will be set correctly
* at the end
*/
- default_vp->vp.font = 1;
+ skin_default->vp.font = 1;
#endif
}
return 0;
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 51c58fc196..00981f5b67 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -349,6 +349,8 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
{
struct gui_wps *gwps = info->gwps;
struct wps_data *data = gwps->data;
+ struct viewport *last_vp;
+
/* Tags here are ones which need to be "turned off" or cleared
* if they are in a conditional branch which isnt being used */
if (branch->type == LINE_ALTERNATOR)
@@ -420,22 +422,23 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
if (skin_viewport->output_to_backdrop_buffer)
{
- void *backdrop = skin_backdrop_get_buffer(data->backdrop_id);
- gwps->display->set_framebuffer(backdrop);
+ skin_backdrop_set_buffer(data->backdrop_id, skin_viewport);
skin_backdrop_show(-1);
}
#endif
- gwps->display->set_viewport(&skin_viewport->vp);
+ last_vp = gwps->display->set_viewport(&skin_viewport->vp);
gwps->display->clear_viewport();
- gwps->display->set_viewport(&info->skin_vp->vp);
+ gwps->display->set_viewport_ex(&info->skin_vp->vp, 0);
skin_viewport->hidden_flags |= VP_DRAW_HIDDEN;
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
if (skin_viewport->output_to_backdrop_buffer)
{
- gwps->display->set_framebuffer(NULL);
+ gwps->display->set_viewport_ex(last_vp, 0);
skin_backdrop_show(data->backdrop_id);
}
+#else
+ (void)last_vp;
#endif
}
}
@@ -792,6 +795,7 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
{
+ const int vp_is_appearing = (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE);
struct wps_data *data = gwps->data;
struct screen *display = gwps->display;
@@ -801,7 +805,20 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
int old_refresh_mode = refresh_mode;
skin_buffer = get_skin_buffer(gwps->data);
-
+
+ struct viewport* first_vp;
+ /* should already be the default buffer */
+ first_vp = display->set_viewport(NULL);
+
+ /* Framebuffer is likely dirty */
+ if ((refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL)
+ {
+ if ((first_vp->flags & VP_FLAG_VP_SET_CLEAN) == VP_FLAG_VP_DIRTY &&
+ get_current_activity() == ACTIVITY_WPS) /* only clear if in WPS */
+ {
+ display->clear_viewport();
+ }
+ }
viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
@@ -822,12 +839,12 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
if (skin_viewport->output_to_backdrop_buffer)
{
- display->set_framebuffer(skin_backdrop_get_buffer(data->backdrop_id));
+ skin_backdrop_set_buffer(data->backdrop_id, skin_viewport);
skin_backdrop_show(-1);
}
else
{
- display->set_framebuffer(NULL);
+ skin_backdrop_set_buffer(-1, skin_viewport);
skin_backdrop_show(data->backdrop_id);
}
#endif
@@ -842,15 +859,14 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN;
continue;
}
- else if (((skin_viewport->hidden_flags&
- (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE))
- == (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE)))
+ else if ((skin_viewport->hidden_flags & vp_is_appearing) == vp_is_appearing)
{
vp_refresh_mode = SKIN_REFRESH_ALL;
skin_viewport->hidden_flags = VP_DRAW_HIDEABLE;
}
- display->set_viewport(&skin_viewport->vp);
+ display->set_viewport_ex(&skin_viewport->vp, VP_FLAG_VP_SET_CLEAN);
+
if ((vp_refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL)
{
display->clear_viewport();
@@ -862,7 +878,6 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
refresh_mode = old_refresh_mode;
}
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
- display->set_framebuffer(NULL);
skin_backdrop_show(data->backdrop_id);
#endif
@@ -872,8 +887,8 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
* to redraw itself */
send_event(GUI_EVENT_NEED_UI_UPDATE, NULL);
}
- /* Restore the default viewport */
- display->set_viewport(NULL);
+ /* Restore the first viewport */
+ display->set_viewport_ex(first_vp, VP_FLAG_VP_SET_CLEAN);
display->update();
}
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index b7d7ff35d0..bf7f52bdbf 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -175,6 +175,7 @@ struct gradient_config {
#define VP_DEFAULT_LABEL_STRING "|"
struct skin_viewport {
struct viewport vp; /* The LCD viewport struct */
+ struct frame_buffer_t framebuf;
char hidden_flags;
bool is_infovp;
OFFSETTYPE(char*) label;
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
index 5bcac80169..1415d47a70 100644
--- a/apps/gui/splash.c
+++ b/apps/gui/splash.c
@@ -53,7 +53,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
int maxw = 0;
viewport_set_defaults(&vp, screen->screen_type);
- screen->set_viewport(&vp);
+ struct viewport *last_vp = screen->set_viewport(&vp);
screen->getstringsize(" ", &space_w, &h);
y = h;
@@ -157,7 +157,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
}
screen->update_viewport();
end:
- screen->set_viewport(NULL);
+ screen->set_viewport(last_vp);
}
void splashf(int ticks, const char *fmt, ...)
diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c
index cf70b7bb39..708624b23e 100644
--- a/apps/gui/statusbar.c
+++ b/apps/gui/statusbar.c
@@ -183,6 +183,7 @@ static void gui_statusbar_init(struct gui_statusbar * bar)
void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw, struct viewport *vp)
{
struct screen * display = bar->display;
+ struct viewport *last_vp = NULL;
if (!display)
return;
@@ -267,7 +268,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw, struct vi
#endif
memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
{
- display->set_viewport(vp);
+ last_vp = display->set_viewport(vp);
display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
display->fill_viewport();
display->set_drawmode(DRMODE_SOLID);
@@ -343,7 +344,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw, struct vi
gui_statusbar_led(display);
#endif
display->update_viewport();
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
bar->lastinfo = bar->info;
}
}
diff --git a/apps/gui/usb_screen.c b/apps/gui/usb_screen.c
index 3169831322..31321ec005 100644
--- a/apps/gui/usb_screen.c
+++ b/apps/gui/usb_screen.c
@@ -179,6 +179,7 @@ static void usb_screen_fix_viewports(struct screen *screen,
static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
{
+ struct viewport *last_vp;
static const struct bitmap* logos[NB_SCREENS] = {
&bm_usblogo,
#ifdef HAVE_REMOTE_LCD
@@ -194,7 +195,7 @@ static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
struct viewport *parent = &usb_screen_vps->parent;
struct viewport *logo = &usb_screen_vps->logo;
- screen->set_viewport(parent);
+ last_vp = screen->set_viewport(parent);
screen->clear_viewport();
screen->backlight_on();
@@ -217,7 +218,7 @@ static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
}
screen->set_viewport(parent);
- screen->set_viewport(NULL);
+ screen->set_viewport(last_vp);
screen->update_viewport();
}
}
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index db58b5d72d..9fdf88e8f0 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -31,6 +31,7 @@
#include "settings.h"
#include "misc.h"
#include "list.h"
+
/*some short cuts for fg/bg/line selector handling */
#ifdef HAVE_LCD_COLOR
#define FG_FALLBACK global_settings.fg_color
@@ -44,7 +45,6 @@
#define REMOTE_BG_FALLBACK LCD_REMOTE_DEFAULT_BG
#endif
-
/* all below isn't needed for pc tools (i.e. checkwps/wps editor)
* only viewport_parse_viewport() is */
#ifndef __PCTOOL__
@@ -101,6 +101,7 @@ static void toggle_theme(enum screen_type screen, bool force)
bool enable_event = false;
static bool was_enabled[NB_SCREENS] = {false};
static bool after_boot[NB_SCREENS] = {false};
+ struct viewport *last_vp;
FOR_NB_SCREENS(i)
{
@@ -111,6 +112,7 @@ static void toggle_theme(enum screen_type screen, bool force)
if (is_theme_enabled(screen))
{
+ last_vp = screens[screen].set_viewport(NULL);
bool first_boot = theme_stack_top[screen] == 0;
/* remove the left overs from the previous screen.
* could cause a tiny flicker. Redo your screen code if that happens */
@@ -162,7 +164,7 @@ static void toggle_theme(enum screen_type screen, bool force)
screens[screen].clear_viewport();
screens[screen].update_viewport();
}
- screens[screen].set_viewport(NULL);
+ screens[screen].set_viewport(last_vp);
}
intptr_t force = first_boot?0:1;
@@ -282,11 +284,11 @@ static void set_default_align_flags(struct viewport *vp)
void viewport_set_fullscreen(struct viewport *vp,
const enum screen_type screen)
{
+ screens[screen].init_viewport(vp);
vp->x = 0;
vp->y = 0;
vp->width = screens[screen].lcdwidth;
vp->height = screens[screen].lcdheight;
-
#ifndef __PCTOOL__
set_default_align_flags(vp);
#endif
@@ -312,9 +314,25 @@ void viewport_set_fullscreen(struct viewport *vp,
#endif
}
+void viewport_set_buffer(struct viewport *vp, struct frame_buffer_t *buffer,
+ const enum screen_type screen)
+{
+ if (!vp) /* NULL vp grabs current framebuffer */
+ vp = *(screens[screen].current_viewport);
+
+ /* NULL sets default buffer */
+ if (buffer && buffer->elems == 0)
+ vp->buffer = NULL;
+ else
+ vp->buffer = buffer;
+ screens[screen].init_viewport(vp);
+}
+
void viewport_set_defaults(struct viewport *vp,
const enum screen_type screen)
{
+ vp->buffer = NULL; /* use default frame_buffer */
+
#if !defined(__PCTOOL__)
struct viewport *sbs_area = NULL;
if (!is_theme_enabled(screen))
@@ -323,7 +341,7 @@ void viewport_set_defaults(struct viewport *vp,
return;
}
sbs_area = sb_skin_get_info_vp(screen);
-
+
if (sbs_area)
*vp = *sbs_area;
else
diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h
index 683c36fe76..be80e44721 100644
--- a/apps/gui/viewport.h
+++ b/apps/gui/viewport.h
@@ -63,6 +63,9 @@ void viewportmanager_theme_undo(enum screen_type screen, bool force_redraw);
/* call this when a theme changed */
void viewportmanager_theme_changed(const int);
+void viewport_set_buffer(struct viewport *vp, struct frame_buffer_t *buffer,
+ const enum screen_type screen);
+
#ifdef HAVE_TOUCHSCREEN
bool viewport_point_within_vp(const struct viewport *vp,
const int x, const int y);
diff --git a/apps/gui/yesno.c b/apps/gui/yesno.c
index 1a1645047a..d70b66f230 100644
--- a/apps/gui/yesno.c
+++ b/apps/gui/yesno.c
@@ -78,8 +78,9 @@ static void gui_yesno_draw(struct gui_yesno * yn)
struct screen * display=yn->display;
struct viewport *vp = yn->vp;
int nb_lines, vp_lines, line_shift=0;
+ struct viewport *last_vp;
- display->set_viewport(vp);
+ last_vp = display->set_viewport(vp);
display->clear_viewport();
nb_lines = yn->main_message->nb_lines;
vp_lines = viewport_get_nb_lines(vp);
@@ -116,7 +117,7 @@ static void gui_yesno_draw(struct gui_yesno * yn)
}
#endif
display->update_viewport();
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
}
/*
@@ -133,11 +134,11 @@ static bool gui_yesno_draw_result(struct gui_yesno * yn, enum yesno_res result)
struct screen * display=yn->display;
if(message==NULL)
return false;
- display->set_viewport(vp);
+ struct viewport *last_vp = display->set_viewport(vp);
display->clear_viewport();
put_message(yn->display, message, 0, viewport_get_nb_lines(vp));
display->update_viewport();
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
return(true);
}
diff --git a/apps/menus/time_menu.c b/apps/menus/time_menu.c
index 6ebf005ffd..edd2e19a2b 100644
--- a/apps/menus/time_menu.c
+++ b/apps/menus/time_menu.c
@@ -169,7 +169,7 @@ static void draw_timedate(struct viewport *vp, struct screen *display)
const char *t = time, *d = date;
if (vp->height == 0)
return;
- display->set_viewport(vp);
+ struct viewport *last_vp = display->set_viewport(vp);
display->clear_viewport();
if (viewport_get_nb_lines(vp) >= 4)
line = 1;
@@ -200,7 +200,7 @@ static void draw_timedate(struct viewport *vp, struct screen *display)
display->puts(0, line, d);
display->update_viewport();
- display->set_viewport(NULL);
+ display->set_viewport(last_vp);
}
diff --git a/apps/misc.c b/apps/misc.c
index 7d4ca97ff8..3a8798fec0 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -769,7 +769,9 @@ int show_logo( void )
lcd_remote_setfont(FONT_UI);
lcd_remote_update();
#endif
-
+#ifdef SIMULATOR
+ sleep(HZ); /* sim is too fast to see logo */
+#endif
return 0;
}
diff --git a/apps/onplay.c b/apps/onplay.c
index f2ebd47630..ded2994c97 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -795,33 +795,34 @@ static int cat_playlist_callback(int action,
static void draw_slider(void)
{
+ struct viewport *last_vp;
FOR_NB_SCREENS(i)
{
struct viewport vp;
int slider_height = 2*screens[i].getcharheight();
viewport_set_defaults(&vp, i);
- screens[i].set_viewport(&vp);
+ last_vp = screens[i].set_viewport(&vp);
show_busy_slider(&screens[i], 1, vp.height - slider_height,
vp.width-2, slider_height-1);
screens[i].update_viewport();
- screens[i].set_viewport(NULL);
+ screens[i].set_viewport(last_vp);
}
}
static void clear_display(bool update)
{
struct viewport vp;
-
+ struct viewport *last_vp;
FOR_NB_SCREENS(i)
{
struct screen * screen = &screens[i];
viewport_set_defaults(&vp, screen->screen_type);
- screen->set_viewport(&vp);
+ last_vp = screen->set_viewport(&vp);
screen->clear_viewport();
if (update) {
screen->update_viewport();
}
- screen->set_viewport(NULL);
+ screen->set_viewport(last_vp);
}
}
diff --git a/apps/plugin.c b/apps/plugin.c
index 48f9dac487..4a50c2b3a3 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -194,9 +194,7 @@ static const struct plugin_api rockbox_api = {
lcd_putsf,
lcd_puts_scroll,
lcd_scroll_stop,
- &lcd_framebuffer,
lcd_set_viewport,
- lcd_set_framebuffer,
lcd_bmp_part,
lcd_update_rect,
lcd_set_drawmode,
@@ -281,7 +279,6 @@ static const struct plugin_api rockbox_api = {
lcd_remote_mono_bitmap_part,
lcd_remote_mono_bitmap,
lcd_remote_putsxy,
- &lcd_remote_framebuffer;
lcd_remote_update,
lcd_remote_update_rect,
#if (LCD_REMOTE_DEPTH > 1)
@@ -303,6 +300,7 @@ static const struct plugin_api rockbox_api = {
viewportmanager_theme_enable,
viewportmanager_theme_undo,
viewport_set_fullscreen,
+ viewport_set_buffer,
#ifdef HAVE_BACKLIGHT
/* lcd backlight */
@@ -869,11 +867,12 @@ int plugin_load(const char* plugin, const void* parameter)
#endif
*(p_hdr->api) = &rockbox_api;
-
+ lcd_set_viewport(NULL);
lcd_clear_display();
lcd_update();
#ifdef HAVE_REMOTE_LCD
+ lcd_remote_set_viewport(NULL);
lcd_remote_clear_display();
lcd_remote_update();
#endif
@@ -914,7 +913,8 @@ int plugin_load(const char* plugin, const void* parameter)
#ifdef HAVE_TOUCHSCREEN
touchscreen_set_mode(global_settings.touch_mode);
#endif
-
+ /* restore default vp */
+ lcd_set_viewport(NULL);
screen_helper_setfont(FONT_UI);
#if LCD_DEPTH > 1
#ifdef HAVE_LCD_COLOR
@@ -928,6 +928,8 @@ int plugin_load(const char* plugin, const void* parameter)
#endif /* LCD_DEPTH */
#ifdef HAVE_REMOTE_LCD
+ lcd_remote_set_viewport(NULL);
+
#if LCD_REMOTE_DEPTH > 1
lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
LCD_REMOTE_DEFAULT_BG);
diff --git a/apps/plugin.h b/apps/plugin.h
index 12fc5424f1..395caaddc0 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -204,9 +204,7 @@ struct plugin_api {
void (*lcd_putsf)(int x, int y, const unsigned char *fmt, ...);
bool (*lcd_puts_scroll)(int x, int y, const unsigned char* string);
void (*lcd_scroll_stop)(void);
- fb_data** lcd_framebuffer;
- void (*lcd_set_viewport)(struct viewport* vp);
- void (*lcd_set_framebuffer)(fb_data *fb);
+ struct viewport* (*lcd_set_viewport)(struct viewport* vp);
void (*lcd_bmp_part)(const struct bitmap *bm, int src_x, int src_y,
int x, int y, int width, int height);
void (*lcd_update_rect)(int x, int y, int width, int height);
@@ -314,7 +312,6 @@ struct plugin_api {
void (*lcd_remote_mono_bitmap)(const unsigned char *src, int x, int y,
int width, int height);
void (*lcd_remote_putsxy)(int x, int y, const unsigned char *string);
- fb_remote_data** lcd_remote_framebuffer;
void (*lcd_remote_update)(void);
void (*lcd_remote_update_rect)(int x, int y, int width, int height);
#if (LCD_REMOTE_DEPTH > 1)
@@ -338,6 +335,8 @@ struct plugin_api {
void (*viewportmanager_theme_undo)(enum screen_type screen, bool force_redraw);
void (*viewport_set_fullscreen)(struct viewport *vp,
const enum screen_type screen);
+ void (*viewport_set_buffer)(struct viewport *vp, struct frame_buffer_t *buffer,
+ const enum screen_type screen);
#ifdef HAVE_BACKLIGHT
/* lcd backlight */
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c
index 3186fac16d..99b4de827d 100644
--- a/apps/plugins/doom/i_video.c
+++ b/apps/plugins/doom/i_video.c
@@ -1052,6 +1052,12 @@ void I_FinishUpdate (void)
rb->lcd_blit_pal256(src, 0, 0, 0, 0, LCD_WIDTH, LCD_HEIGHT);
#endif
#elif defined(HAVE_LCD_COLOR)
+ static fb_data *lcd_fb = NULL;
+ if (!lcd_fb)
+ {
+ struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
+ lcd_fb = vp_main->buffer->fb_ptr;
+ }
#if(LCD_HEIGHT>LCD_WIDTH)
if(rotate_screen)
{
@@ -1059,7 +1065,7 @@ void I_FinishUpdate (void)
for (y = 1; y <= SCREENHEIGHT; y++)
{
- fb_data *dst = *rb->lcd_framebuffer + LCD_WIDTH - y;
+ fb_data *dst = lcd_fb + LCD_WIDTH - y;
count = SCREENWIDTH;
do
@@ -1073,7 +1079,7 @@ void I_FinishUpdate (void)
else
#endif
{
- fb_data *dst = *rb->lcd_framebuffer;
+ fb_data *dst = lcd_fb;
count = SCREENWIDTH*SCREENHEIGHT;
do
diff --git a/apps/plugins/fire.c b/apps/plugins/fire.c
index 95edbf37c4..f3e6fb35e4 100644
--- a/apps/plugins/fire.c
+++ b/apps/plugins/fire.c
@@ -30,6 +30,7 @@
#ifndef HAVE_LCD_COLOR
#include "lib/grey.h"
#endif
+static fb_data *lcd_fb = NULL;
#if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
/* Archos has not enough plugin RAM for full-width fire :( */
@@ -251,7 +252,7 @@ static inline void fire_draw(struct fire* fire)
#ifndef HAVE_LCD_COLOR
dest = draw_buffer;
#else
- dest = *rb->lcd_framebuffer + LCD_WIDTH * y + FIRE_XPOS;
+ dest = lcd_fb + LCD_WIDTH * y + FIRE_XPOS;
#endif
end = dest + FIRE_WIDTH;
@@ -379,6 +380,8 @@ enum plugin_status plugin_start(const void* parameter)
rb->lcd_set_mode(LCD_MODE_PAL256);
#endif
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
ret = main();
#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
diff --git a/apps/plugins/imageviewer/imageviewer.c b/apps/plugins/imageviewer/imageviewer.c
index 37c5838d73..4b1a982438 100644
--- a/apps/plugins/imageviewer/imageviewer.c
+++ b/apps/plugins/imageviewer/imageviewer.c
@@ -509,6 +509,13 @@ static void pan_view_up(struct image_info *info)
the bottom */
static void pan_view_down(struct image_info *info)
{
+ static fb_data *lcd_fb = NULL;
+ if (!lcd_fb)
+ {
+ struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
+ lcd_fb = vp_main->buffer->fb_ptr;
+ }
+
int move;
move = MIN(VSCROLL, info->height - info->y - LCD_HEIGHT);
@@ -526,7 +533,7 @@ static void pan_view_down(struct image_info *info)
*/
move++, info->y--;
rb->memcpy(rgb_linebuf,
- *rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
+ lcd_fb + (LCD_HEIGHT - move)*LCD_WIDTH,
LCD_WIDTH*sizeof (fb_data));
}
#endif
@@ -539,7 +546,7 @@ static void pan_view_down(struct image_info *info)
&& settings.jpeg_dither_mode == DITHER_DIFFUSION)
{
/* Cover the first row drawn with previous image data. */
- rb->memcpy(*rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
+ rb->memcpy(lcd_fb + (LCD_HEIGHT - move)*LCD_WIDTH,
rgb_linebuf, LCD_WIDTH*sizeof (fb_data));
info->y++;
}
diff --git a/apps/plugins/imageviewer/jpeg/yuv2rgb.c b/apps/plugins/imageviewer/jpeg/yuv2rgb.c
index 5504e425e6..d0d5cb683b 100644
--- a/apps/plugins/imageviewer/jpeg/yuv2rgb.c
+++ b/apps/plugins/imageviewer/jpeg/yuv2rgb.c
@@ -236,15 +236,15 @@ static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
[DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
},
};
-
+static fb_data *lcd_fb = NULL;
/* These defines are used fornormal horizontal strides and vertical strides. */
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
-#define LCDADDR(x, y) (*rb->lcd_framebuffer + LCD_HEIGHT*(x) + (y))
+#define LCDADDR(x, y) (lcd_fb + LCD_HEIGHT*(x) + (y))
#define ROWENDOFFSET (width*LCD_HEIGHT)
#define ROWOFFSET (1)
#define COLOFFSET (LCD_HEIGHT)
#else
-#define LCDADDR(x, y) (*rb->lcd_framebuffer + LCD_WIDTH*(y) + (x))
+#define LCDADDR(x, y) (lcd_fb + LCD_WIDTH*(y) + (x))
#define ROWENDOFFSET (width)
#define ROWOFFSET (LCD_WIDTH)
#define COLOFFSET (1)
@@ -261,6 +261,12 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
int x, int y, int width, int height,
int colour_mode, int dither_mode)
{
+ if (!lcd_fb)
+ {
+ struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
+ lcd_fb = vp_main->buffer->fb_ptr;
+ }
+
fb_data *dst, *dst_end;
fb_data (*pixel_func)(void);
struct rgb_pixel px;
diff --git a/apps/plugins/invadrox.c b/apps/plugins/invadrox.c
index 0b26581b30..1c39a01c87 100644
--- a/apps/plugins/invadrox.c
+++ b/apps/plugins/invadrox.c
@@ -768,7 +768,7 @@ int curr_alien, aliens_paralyzed, gamespeed;
int ufo_state, ufo_x;
bool level_finished;
bool aliens_down, aliens_right, hit_left_border, hit_right_border;
-
+static fb_data *lcd_fb;
/* No standard get_pixel function yet, use this hack instead */
#if (LCD_DEPTH >= 8)
@@ -776,12 +776,12 @@ bool aliens_down, aliens_right, hit_left_border, hit_right_border;
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
static inline fb_data get_pixel(int x, int y)
{
- return *rb->lcd_framebuffer[x*LCD_HEIGHT+y];
+ return lcd_fb[x*LCD_HEIGHT+y];
}
#else
static inline fb_data get_pixel(int x, int y)
{
- return *rb->lcd_framebuffer[ytab[y] + x];
+ return lcd_fb[ytab[y] + x];
}
#endif
@@ -794,7 +794,7 @@ static const unsigned char shifts[4] = {
/* Horizontal packing */
static inline fb_data get_pixel(int x, int y)
{
- return (*rb->lcd_framebuffer[ytab[y] + (x >> 2)] >> shifts[x & 3]) & 3;
+ return (lcd_fb[ytab[y] + (x >> 2)] >> shifts[x & 3]) & 3;
}
#else
/* Vertical packing */
@@ -803,7 +803,7 @@ static const unsigned char shifts[4] = {
};
static inline fb_data get_pixel(int x, int y)
{
- return (*rb->lcd_framebuffer[ytab[y] + x] >> shifts[y & 3]) & 3;
+ return (lcd_fb[ytab[y] + x] >> shifts[y & 3]) & 3;
}
#endif /* Horizontal/Vertical packing */
@@ -1902,6 +1902,8 @@ enum plugin_status plugin_start(UNUSED const void* parameter)
#ifdef HAVE_BACKLIGHT
backlight_ignore_timeout();
#endif
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
/* now go ahead and have fun! */
game_loop();
diff --git a/apps/plugins/lib/grey.h b/apps/plugins/lib/grey.h
index 0e064f46b2..5cafc6a83e 100644
--- a/apps/plugins/lib/grey.h
+++ b/apps/plugins/lib/grey.h
@@ -62,7 +62,7 @@ void grey_deferred_lcd_update(void);
/* Viewports and framebuffers */
void grey_clear_viewport(void);
-void grey_set_viewport(struct viewport *vp);
+struct viewport *grey_set_viewport(struct viewport *vp);
void grey_viewport_set_fullscreen(struct viewport *vp,
const enum screen_type screen);
void grey_viewport_set_pos(struct viewport *vp,
diff --git a/apps/plugins/lib/grey_core.c b/apps/plugins/lib/grey_core.c
index 9686f1d021..e3543aeba2 100644
--- a/apps/plugins/lib/grey_core.c
+++ b/apps/plugins/lib/grey_core.c
@@ -765,6 +765,11 @@ static const unsigned char colorindex[4] = {128, 85, 43, 0};
content (b&w and greyscale overlay) to an 8-bit BMP file. */
static void grey_screendump_hook(int fd)
{
+ fb_data *lcd_fb;
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ rb->viewport_set_fullscreen(vp_main, SCREEN_MAIN);
+ lcd_fb = vp_main->buffer->fb_ptr;
+
int i;
int y, gx, gy;
#if LCD_PIXELFORMAT == VERTICAL_PACKING
@@ -845,7 +850,7 @@ static void grey_screendump_hook(int fd)
gsrc = _grey_info.values + _GREY_MULUQ(_grey_info.width, gy);
#if LCD_DEPTH == 2
- src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_FBWIDTH, y);
+ src = lcd_fb + _GREY_MULUQ(LCD_FBWIDTH, y);
do
{
@@ -876,7 +881,7 @@ static void grey_screendump_hook(int fd)
#if LCD_DEPTH == 1
mask = BIT_N(y & 7);
- src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3);
+ src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 3);
do
{
@@ -908,7 +913,7 @@ static void grey_screendump_hook(int fd)
#elif LCD_DEPTH == 2
shift = 2 * (y & 3);
- src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 2);
+ src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 2);
do
{
@@ -933,7 +938,7 @@ static void grey_screendump_hook(int fd)
#if LCD_DEPTH == 2
shift = y & 7;
- src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3);
+ src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 3);
do
{
diff --git a/apps/plugins/lib/grey_parm.c b/apps/plugins/lib/grey_parm.c
index d2dfde42f1..700b6f0026 100644
--- a/apps/plugins/lib/grey_parm.c
+++ b/apps/plugins/lib/grey_parm.c
@@ -154,8 +154,9 @@ static void grey_update_clip_rect(void)
}
/* Set current grey viewport for draw routines */
-void grey_set_viewport(struct viewport *vp)
+struct viewport *grey_set_viewport(struct viewport *vp)
{
+ struct viewport *last_vp = _grey_info.vp;
if (vp == NULL)
vp = &_grey_default_vp;
@@ -164,6 +165,7 @@ void grey_set_viewport(struct viewport *vp)
_grey_info.vp = vp;
grey_update_clip_rect();
}
+ return last_vp;
}
/* Set viewport to default settings */
diff --git a/apps/plugins/lib/osd.c b/apps/plugins/lib/osd.c
index 97db09cc1e..7d6e10a410 100644
--- a/apps/plugins/lib/osd.c
+++ b/apps/plugins/lib/osd.c
@@ -52,6 +52,7 @@ struct osd
OSD_ERASED, /* Erased in preparation for regular drawing */
} status; /* View status */
struct viewport vp; /* Clipping viewport */
+ struct frame_buffer_t framebuf; /* Holds framebuffer reference */
int lcd_bitmap_stride; /* Stride of LCD bitmap */
void *lcd_bitmap_data; /* Backbuffer framebuffer data */
int back_bitmap_stride; /* Stride of backbuffer bitmap */
@@ -68,7 +69,7 @@ struct osd
int height);
void (*lcd_update)(void);
void (*lcd_update_rect)(int x, int y, int width, int height);
- void (*lcd_set_viewport)(struct viewport *vp);
+ struct viewport *(*lcd_set_viewport)(struct viewport *vp);
void (*lcd_set_framebuffer)(void *buf);
void (*lcd_framebuffer_set_pos)(int x, int y, int width, int height);
void (*lcd_bitmap_part)(const void *src, int src_x, int src_y,
@@ -227,7 +228,8 @@ static void * _osd_lcd_init_buffers(struct osd *osd, unsigned flags,
osd->back_bitmap_stride = w;
#endif /* end stride type selection */
- osd->lcd_bitmap_data = (void *)*rb->lcd_framebuffer;
+ /* vp is currently initialized to the default framebuffer */
+ osd->lcd_bitmap_data = osd->vp.buffer->data;
osd->back_bitmap_data = buf;
osd->maxwidth = w;
@@ -686,6 +688,25 @@ static void _osd_lcd_update_rect(struct osd *osd,
osd->lcd_update_rect(x, y, width, height);
}
+static void _osd_lcd_viewport_set_buffer(void *buffer)
+{
+ if (buffer)
+ {
+ native_osd.framebuf.data = buffer;
+ native_osd.framebuf.elems = native_osd.maxheight * native_osd.maxwidth;
+ native_osd.framebuf.get_address_fn = NULL; /*Default iterator*/
+
+ if (buffer == native_osd.back_bitmap_data)
+ native_osd.framebuf.stride = (native_osd.back_bitmap_stride);
+ else
+ native_osd.framebuf.stride = (native_osd.lcd_bitmap_stride);
+
+ rb->viewport_set_buffer(NULL, &native_osd.framebuf, SCREEN_MAIN);
+ }
+ else
+ rb->viewport_set_buffer(NULL, NULL, SCREEN_MAIN);
+}
+
/* Native LCD, public */
bool osd_init(unsigned flags, void *backbuf, size_t backbuf_size,
osd_draw_cb_fn_t draw_cb, int *width, int *height,
@@ -696,7 +717,7 @@ bool osd_init(unsigned flags, void *backbuf, size_t backbuf_size,
native_osd.lcd_update = rb->lcd_update;
native_osd.lcd_update_rect = rb->lcd_update_rect;
native_osd.lcd_set_viewport = rb->lcd_set_viewport;
- native_osd.lcd_set_framebuffer = (void *)rb->lcd_set_framebuffer;
+ native_osd.lcd_set_framebuffer = (void *)_osd_lcd_viewport_set_buffer;
#if LCD_DEPTH < 4
native_osd.lcd_framebuffer_set_pos = NULL;
#endif /* LCD_DEPTH < 4 */
diff --git a/apps/plugins/lib/xlcd.h b/apps/plugins/lib/xlcd.h
index 963c7c4831..069cc00508 100644
--- a/apps/plugins/lib/xlcd.h
+++ b/apps/plugins/lib/xlcd.h
@@ -34,6 +34,8 @@ void xlcd_fillcircle_screen(struct screen* display, int cx, int cy, int radius);
void xlcd_drawcircle(int cx, int cy, int radius);
void xlcd_drawcircle_screen(struct screen* display, int cx, int cy, int radius);
+fb_data* get_framebuffer(struct viewport *vp, size_t *stride); /*CORE*/
+
#if LCD_DEPTH >= 8
void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height);
diff --git a/apps/plugins/lib/xlcd_core.c b/apps/plugins/lib/xlcd_core.c
index 47875a51a9..9a274cb48d 100644
--- a/apps/plugins/lib/xlcd_core.c
+++ b/apps/plugins/lib/xlcd_core.c
@@ -26,3 +26,12 @@
#include "xlcd.h"
+fb_data* get_framebuffer(struct viewport *vp, size_t *stride)
+{
+ struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
+ if (vp)
+ *vp = *vp_main;
+ if (stride)
+ *stride = vp_main->buffer->stride;
+ return vp_main->buffer->fb_ptr;
+}
diff --git a/apps/plugins/lib/xlcd_draw.c b/apps/plugins/lib/xlcd_draw.c
index b6ed403353..0bd1c7a9e2 100644
--- a/apps/plugins/lib/xlcd_draw.c
+++ b/apps/plugins/lib/xlcd_draw.c
@@ -349,6 +349,9 @@ static const fb_data graylut[256] = {
void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
+ size_t dst_stride;
+ fb_data *lcd_fb = get_framebuffer(NULL, &dst_stride);
+
const unsigned char *src_end;
fb_data *dst;
@@ -377,7 +380,7 @@ void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
src += stride * src_y + src_x; /* move starting point */
src_end = src + stride * height;
- dst = *rb->lcd_framebuffer + LCD_WIDTH * y + x;
+ dst = lcd_fb + dst_stride * y + x;
do
{
@@ -398,7 +401,7 @@ void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
#endif
src += stride;
- dst += LCD_WIDTH;
+ dst += dst_stride;
}
while (src < src_end);
}
@@ -416,6 +419,9 @@ void xlcd_gray_bitmap(const unsigned char *src, int x, int y, int width,
void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
+ size_t dst_stride;
+ fb_data *lcd_fb = get_framebuffer(NULL, &dst_stride);
+
const unsigned char *src_end;
fb_data *dst;
@@ -444,7 +450,7 @@ void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
src += 3 * (stride * src_y + src_x); /* move starting point */
src_end = src + 3 * stride * height;
- dst = *rb->lcd_framebuffer + LCD_WIDTH * y + x;
+ dst = lcd_fb + dst_stride * y + x;
do
{
@@ -471,7 +477,7 @@ void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
while (src_row < row_end);
src += 3 * stride;
- dst += LCD_WIDTH;
+ dst += dst_stride;
}
while (src < src_end);
}
diff --git a/apps/plugins/lib/xlcd_scroll.c b/apps/plugins/lib/xlcd_scroll.c
index ab9ee1c4cb..89427b6118 100644
--- a/apps/plugins/lib/xlcd_scroll.c
+++ b/apps/plugins/lib/xlcd_scroll.c
@@ -33,6 +33,11 @@ static const unsigned short patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
void xlcd_scroll_left(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
+
int length, oldmode;
if ((unsigned)count >= LCD_WIDTH)
@@ -43,8 +48,7 @@ void xlcd_scroll_left(int count)
length = (LCD_WIDTH-count)*LCD_FBHEIGHT;
- rb->memmove(*rb->lcd_framebuffer, *rb->lcd_framebuffer + LCD_HEIGHT*count,
- length * sizeof(fb_data));
+ rb->memmove(lcd_fb, lcd_fb + LCD_HEIGHT*count, length * sizeof(fb_data));
oldmode = rb->lcd_get_drawmode();
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
@@ -55,6 +59,11 @@ void xlcd_scroll_left(int count)
/* Scroll right */
void xlcd_scroll_right(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
+
int length, oldmode;
if ((unsigned)count >= LCD_WIDTH)
@@ -65,8 +74,8 @@ void xlcd_scroll_right(int count)
length = (LCD_WIDTH-count)*LCD_FBHEIGHT;
- rb->memmove(*rb->lcd_framebuffer + LCD_HEIGHT*count,
- *rb->lcd_framebuffer, length * sizeof(fb_data));
+ rb->memmove(lcd_fb + LCD_HEIGHT*count,
+ lcd_fb, length * sizeof(fb_data));
oldmode = rb->lcd_get_drawmode();
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
@@ -77,6 +86,11 @@ void xlcd_scroll_right(int count)
/* Scroll up */
void xlcd_scroll_up(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
+
int width, length, oldmode;
fb_data *data;
@@ -90,7 +104,7 @@ void xlcd_scroll_up(int count)
length = LCD_HEIGHT - count;
width = LCD_WIDTH-1;
- data = *rb->lcd_framebuffer;
+ data = lcd_fb;
do {
rb->memmove(data,data + count,length * sizeof(fb_data));
@@ -106,6 +120,11 @@ void xlcd_scroll_up(int count)
/* Scroll down */
void xlcd_scroll_down(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
+
int width, length, oldmode;
fb_data *data;
@@ -119,7 +138,7 @@ void xlcd_scroll_down(int count)
length = LCD_HEIGHT - count;
width = LCD_WIDTH-1;
- data = *rb->lcd_framebuffer;
+ data = lcd_fb;
do {
rb->memmove(data + count, data, length * sizeof(fb_data));
@@ -138,6 +157,11 @@ void xlcd_scroll_down(int count)
/* Scroll left */
void xlcd_scroll_left(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
+
int bitcount=0, oldmode;
int blockcount=0, blocklen;
@@ -155,7 +179,7 @@ void xlcd_scroll_left(int count)
if (blockcount)
{
- unsigned char *data = *rb->lcd_framebuffer;
+ unsigned char *data = lcd_fb;
unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT;
do
@@ -168,7 +192,7 @@ void xlcd_scroll_left(int count)
if (bitcount)
{
int bx, y;
- unsigned char *addr = *rb->lcd_framebuffer + blocklen;
+ unsigned char *addr = lcd_fb + blocklen;
#if LCD_DEPTH == 2
unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount;
#endif
@@ -196,6 +220,11 @@ void xlcd_scroll_left(int count)
/* Scroll right */
void xlcd_scroll_right(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
+
int bitcount=0, oldmode;
int blockcount=0, blocklen;
@@ -213,7 +242,7 @@ void xlcd_scroll_right(int count)
if (blockcount)
{
- unsigned char *data = *rb->lcd_framebuffer;
+ unsigned char *data = lcd_fb;
unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT;
do
@@ -226,7 +255,7 @@ void xlcd_scroll_right(int count)
if (bitcount)
{
int bx, y;
- unsigned char *addr = *rb->lcd_framebuffer + blockcount;
+ unsigned char *addr = lcd_fb + blockcount;
#if LCD_DEPTH == 2
unsigned fill = 0x55 * (~rb->lcd_get_background() & 3);
#endif
@@ -256,6 +285,11 @@ void xlcd_scroll_right(int count)
/* Scroll left */
void xlcd_scroll_left(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
+
fb_data *data, *data_end;
int length, oldmode;
@@ -265,7 +299,7 @@ void xlcd_scroll_left(int count)
return;
}
- data = *rb->lcd_framebuffer;
+ data = lcd_fb;
data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
length = LCD_WIDTH - count;
@@ -285,6 +319,11 @@ void xlcd_scroll_left(int count)
/* Scroll right */
void xlcd_scroll_right(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
+
fb_data *data, *data_end;
int length, oldmode;
@@ -294,7 +333,7 @@ void xlcd_scroll_right(int count)
return;
}
- data = *rb->lcd_framebuffer;
+ data = lcd_fb;
data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
length = LCD_WIDTH - count;
@@ -318,6 +357,10 @@ void xlcd_scroll_right(int count)
/* Scroll up */
void xlcd_scroll_up(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
int length, oldmode;
if ((unsigned)count >= LCD_HEIGHT)
@@ -328,8 +371,8 @@ void xlcd_scroll_up(int count)
length = LCD_HEIGHT - count;
- rb->memmove(*rb->lcd_framebuffer,
- *rb->lcd_framebuffer + count * LCD_FBWIDTH,
+ rb->memmove(lcd_fb,
+ lcd_fb + count * LCD_FBWIDTH,
length * LCD_FBWIDTH * sizeof(fb_data));
oldmode = rb->lcd_get_drawmode();
@@ -341,6 +384,10 @@ void xlcd_scroll_up(int count)
/* Scroll down */
void xlcd_scroll_down(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
int length, oldmode;
if ((unsigned)count >= LCD_HEIGHT)
@@ -351,8 +398,8 @@ void xlcd_scroll_down(int count)
length = LCD_HEIGHT - count;
- rb->memmove(*rb->lcd_framebuffer + count * LCD_FBWIDTH,
- *rb->lcd_framebuffer,
+ rb->memmove(lcd_fb + count * LCD_FBWIDTH,
+ lcd_fb,
length * LCD_FBWIDTH * sizeof(fb_data));
oldmode = rb->lcd_get_drawmode();
@@ -367,6 +414,10 @@ void xlcd_scroll_down(int count)
/* Scroll up */
void xlcd_scroll_up(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
int bitcount=0, oldmode;
int blockcount=0, blocklen;
@@ -388,8 +439,8 @@ void xlcd_scroll_up(int count)
if (blockcount)
{
- rb->memmove(*rb->lcd_framebuffer,
- *rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
+ rb->memmove(lcd_fb,
+ lcd_fb + blockcount * LCD_FBWIDTH,
blocklen * LCD_FBWIDTH * sizeof(fb_data));
}
if (bitcount)
@@ -424,7 +475,7 @@ void xlcd_scroll_up(int count)
: /* inputs */
[wide]"r"(LCD_FBWIDTH),
[rows]"r"(blocklen),
- [addr]"a"(*rb->lcd_framebuffer + blocklen * LCD_FBWIDTH),
+ [addr]"a"(lcd_fb + blocklen * LCD_FBWIDTH),
[cnt] "d"(bitcount),
[bkg] "d"(0x55 * (~rb->lcd_get_background() & 3))
: /* clobbers */
@@ -432,7 +483,7 @@ void xlcd_scroll_up(int count)
);
#else /* C version */
int x, by;
- unsigned char *addr = *rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
+ unsigned char *addr = lcd_fb + blocklen * LCD_FBWIDTH;
#if LCD_DEPTH == 2
unsigned fill = 0x55 * (~rb->lcd_get_background() & 3);
#else
@@ -457,7 +508,7 @@ void xlcd_scroll_up(int count)
#if LCD_DEPTH == 2
int x, by;
- fb_data *addr = *rb->lcd_framebuffer + blocklen * LCD_FBWIDTH;
+ fb_data *addr = lcd_fb + blocklen * LCD_FBWIDTH;
unsigned fill, mask;
fill = patterns[rb->lcd_get_background() & 3] << 8;
@@ -491,6 +542,10 @@ void xlcd_scroll_up(int count)
/* Scroll up */
void xlcd_scroll_down(int count)
{
+ /*size_t dst_stride;*/
+ /*struct viewport *vp_main = NULL;*/
+ fb_data *lcd_fb = get_framebuffer(NULL, NULL);
+
int bitcount=0, oldmode;
int blockcount=0, blocklen;
@@ -512,8 +567,8 @@ void xlcd_scroll_down(int count)
if (blockcount)
{
- rb->memmove(*rb->lcd_framebuffer + blockcount * LCD_FBWIDTH,
- *rb->lcd_framebuffer,
+ rb->memmove(lcd_fb + blockcount * LCD_FBWIDTH,
+ lcd_fb,
blocklen * LCD_FBWIDTH * sizeof(fb_data));
}
if (bitcount)
@@ -548,7 +603,7 @@ void xlcd_scroll_down(int count)
: /* inputs */
[wide]"r"(LCD_WIDTH),
[rows]"r"(blocklen),
- [addr]"a"(*rb->lcd_framebuffer + blockcount * LCD_FBWIDTH),
+ [addr]"a"(lcd_fb + blockcount * LCD_FBWIDTH),
[cnt] "d"(bitcount),
[bkg] "d"((0x55 * (~rb->lcd_get_background() & 3)) << bitcount)
: /* clobbers */
@@ -556,7 +611,7 @@ void xlcd_scroll_down(int count)
);
#else /* C version */
int x, by;
- unsigned char *addr = *rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
+ unsigned char *addr = lcd_fb + blockcount * LCD_FBWIDTH;
#if LCD_DEPTH == 2
unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount;
#else
@@ -581,7 +636,7 @@ void xlcd_scroll_down(int count)
#if LCD_DEPTH == 2
int x, by;
- fb_data *addr = *rb->lcd_framebuffer + blockcount * LCD_FBWIDTH;
+ fb_data *addr = lcd_fb + blockcount * LCD_FBWIDTH;
unsigned fill, mask;
fill = patterns[rb->lcd_get_background() & 3] >> (8 - bitcount);
diff --git a/apps/plugins/lua/rocklib_img.c b/apps/plugins/lua/rocklib_img.c
index da3ef4b52c..887ef984d0 100644
--- a/apps/plugins/lua/rocklib_img.c
+++ b/apps/plugins/lua/rocklib_img.c
@@ -1242,6 +1242,7 @@ static int get_screen(lua_State *L, int narg)
return screen;
}
#else /* only SCREEN_MAIN exists */
+#define get_screen(a,b) (SCREEN_MAIN)
#define RB_SCREEN_STRUCT(luastate, narg) \
rb->screens[SCREEN_MAIN]
#define RB_SCREENS(luastate, narg, func, ...) \
@@ -1379,7 +1380,12 @@ RB_WRAP(font_getstringsize)
RB_WRAP(lcd_framebuffer)
{
- rli_wrap(L, *rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT);
+ int screen = get_screen(L, 1);
+ static struct viewport vp;
+ rb->viewport_set_fullscreen(&vp, screen);
+ rli_wrap(L, vp.buffer->data,
+ RB_SCREEN_STRUCT(L, 1)->lcdwidth,
+ RB_SCREEN_STRUCT(L, 1)->lcdheight);
return 1;
}
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
index e72d2828e3..619be8f1ef 100644
--- a/apps/plugins/mpegplayer/mpegplayer.c
+++ b/apps/plugins/mpegplayer/mpegplayer.c
@@ -620,6 +620,14 @@ struct fps
static struct osd osd;
static struct fps fps NOCACHEBSS_ATTR; /* Accessed on other processor */
+#ifdef LCD_PORTRAIT
+static fb_data* get_framebuffer(void)
+{
+ struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
+ return vp_main->buffer->fb_ptr;
+}
+#endif
+
static void osd_show(unsigned show);
#ifdef LCD_LANDSCAPE
@@ -821,7 +829,7 @@ static void draw_oriented_mono_bitmap_part(const unsigned char *src,
src_y &= 7;
src_end = src + width;
- dst = *rb->lcd_framebuffer + (LCD_WIDTH - y) + x*LCD_WIDTH;
+ dst = get_framebuffer() + (LCD_WIDTH - y) + x*LCD_WIDTH;
do
{
const unsigned char *src_col = src++;
@@ -953,7 +961,7 @@ static void draw_oriented_alpha_bitmap_part(const unsigned char *src,
fg_pattern = rb->lcd_get_foreground();
/*bg_pattern=*/ rb->lcd_get_background();
- dst_start = *rb->lcd_framebuffer + (LCD_WIDTH - y - 1) + x*LCD_WIDTH;
+ dst_start = get_framebuffer() + (LCD_WIDTH - y - 1) + x*LCD_WIDTH;
int col, row = height;
unsigned data, pixels;
unsigned skip_end = (stride - width);
diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c
index d8bef0ae7f..62c11b91c9 100644
--- a/apps/plugins/oscilloscope.c
+++ b/apps/plugins/oscilloscope.c
@@ -838,10 +838,10 @@ static void osc_osd_show_message(int id, int val)
int width, height;
int maxwidth, maxheight;
- rb->lcd_set_viewport(osd_get_viewport());
+ struct viewport *last_vp = rb->lcd_set_viewport(osd_get_viewport());
osd_get_max_dims(&maxwidth, &maxheight);
rb->lcd_getstringsize(osc_osd_message, &width, &height);
- rb->lcd_set_viewport(NULL); /* to regular viewport */
+ rb->lcd_set_viewport(last_vp); /* to regular viewport */
width += 2 + 2*OSC_OSD_MARGIN_SIZE;
if (width > maxwidth)
diff --git a/apps/plugins/pacbox/pacbox.c b/apps/plugins/pacbox/pacbox.c
index 262ab3e836..71c9751cad 100755
--- a/apps/plugins/pacbox/pacbox.c
+++ b/apps/plugins/pacbox/pacbox.c
@@ -35,6 +35,7 @@
#include "lib/configfile.h"
#include "lib/playback_control.h"
#include "lib/helper.h"
+static fb_data *lcd_fb;
/*Allows split screen jump and makes pacman invincible if you start at 18 credits (for testing purposes)*/
//#define CHEATS 1
@@ -704,7 +705,7 @@ static int gameProc( void )
rb->lcd_blit_pal256( video_buffer, 0, 0, XOFS, YOFS,
ScreenWidth, ScreenHeight);
#else
- blit_display(*rb->lcd_framebuffer,video_buffer);
+ blit_display(lcd_fb ,video_buffer);
#endif
if (settings.showfps) {
@@ -743,6 +744,9 @@ enum plugin_status plugin_start(const void* parameter)
rb->lcd_clear_display();
rb->lcd_update();
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
+
/* Set the default settings */
settings.difficulty = 0; /* Normal */
settings.numlives = 2; /* 3 lives */
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c
index eadf9c3d0a..5f700aac83 100644
--- a/apps/plugins/pictureflow/pictureflow.c
+++ b/apps/plugins/pictureflow/pictureflow.c
@@ -35,6 +35,7 @@
#include "lib/feature_wrappers.h"
/******************************* Globals ***********************************/
+static fb_data *lcd_fb;
/*
* Targets which use plugin_get_audio_buffer() can't have playback from
@@ -190,7 +191,7 @@ GREY_INFO_STRUCT
#define BUFFER_HEIGHT _grey_info.height
typedef unsigned char pix_t;
#else /* LCD_DEPTH >= 8 */
-#define LCD_BUF *rb->lcd_framebuffer
+#define LCD_BUF lcd_fb
#define G_PIX LCD_RGBPACK
#define N_PIX LCD_RGBPACK
#define G_BRIGHT(y) LCD_RGBPACK(y,y,y)
@@ -3847,6 +3848,9 @@ static int pictureflow_main(void)
enum plugin_status plugin_start(const void *parameter)
{
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
+
int ret;
(void) parameter;
diff --git a/apps/plugins/plasma.c b/apps/plugins/plasma.c
index 9e2e3832a3..f944d3d775 100644
--- a/apps/plugins/plasma.c
+++ b/apps/plugins/plasma.c
@@ -36,6 +36,8 @@
/******************************* Globals ***********************************/
+static fb_data *lcd_fb;
+
static unsigned char wave_array[256]; /* Pre calculated wave array */
#ifdef HAVE_LCD_COLOR
@@ -201,9 +203,9 @@ int main(void)
#ifdef HAVE_LCD_COLOR
shades_generate(time++); /* dynamically */
#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
- ptr = (unsigned char*)*rb->lcd_framebuffer;
+ ptr = (unsigned char*)lcd_fb;
#else
- ptr = *rb->lcd_framebuffer;
+ ptr = lcd_fb;
#endif
#else
@@ -237,7 +239,7 @@ int main(void)
p4-=sp4;
#ifdef HAVE_LCD_COLOR
#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
- rb->lcd_blit_pal256( (unsigned char*)*rb->lcd_framebuffer,
+ rb->lcd_blit_pal256( (unsigned char*)lcd_fb,
0,0,0,0,LCD_WIDTH,LCD_HEIGHT);
#else
rb->lcd_update();
@@ -326,5 +328,8 @@ enum plugin_status plugin_start(const void* parameter)
#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
rb->lcd_set_mode(LCD_MODE_PAL256);
#endif
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
+
return main();
}
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c
index ed58bd900a..08581db1c6 100644
--- a/apps/plugins/puzzles/rockbox.c
+++ b/apps/plugins/puzzles/rockbox.c
@@ -310,6 +310,7 @@ static int help_times = 0;
#endif
/* clipping stuff */
+static fb_data *lcd_fb;
static struct viewport clip_rect;
static bool clipped = false, zoom_enabled = false, view_mode = true, mouse_mode = false;
@@ -1016,7 +1017,7 @@ static void rb_draw_line(void *handle, int x1, int y1, int x2, int y2,
}
else
#endif
- draw_antialiased_line(*rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
+ draw_antialiased_line(lcd_fb, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
}
else
{
@@ -1294,7 +1295,7 @@ static void rb_draw_poly(void *handle, int *coords, int npoints,
x2, y2);
}
else
- draw_antialiased_line(*rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
+ draw_antialiased_line(lcd_fb, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
#ifdef DEBUG_MENU
if(debug_settings.polyanim)
@@ -1319,7 +1320,7 @@ static void rb_draw_poly(void *handle, int *coords, int npoints,
x2, y2);
}
else
- draw_antialiased_line(*rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
+ draw_antialiased_line(lcd_fb, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
}
else
{
@@ -1474,7 +1475,7 @@ static void rb_blitter_save(void *handle, blitter *bl, int x, int y)
trim_rect(&x, &y, &w, &h);
- fb_data *fb = zoom_enabled ? zoom_fb : *rb->lcd_framebuffer;
+ fb_data *fb = zoom_enabled ? zoom_fb : lcd_fb;
LOGF("rb_blitter_save(%d, %d, %d, %d)", x, y, w, h);
for(int i = 0; i < h; ++i)
{
@@ -1778,9 +1779,9 @@ static void timer_cb(void)
static bool what = false;
what = !what;
if(what)
- *rb->lcd_framebuffer[0] = LCD_BLACK;
+ lcd_fb[0] = LCD_BLACK;
else
- *rb->lcd_framebuffer[0] = LCD_WHITE;
+ lcd_fb[0] = LCD_WHITE;
rb->lcd_update();
}
#endif
@@ -2909,7 +2910,7 @@ static void bench_aa(void)
int i = 0;
while(*rb->current_tick < next)
{
- draw_antialiased_line(*rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT, 0, 0, 20, 31);
+ draw_antialiased_line(lcd_fb, LCD_WIDTH, LCD_HEIGHT, 0, 0, 20, 31);
++i;
}
rb->splashf(HZ, "%d AA lines/sec", i);
@@ -3843,6 +3844,8 @@ enum plugin_status plugin_start(const void *param)
giant_buffer = rb->plugin_get_buffer(&giant_buffer_len);
init_tlsf();
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
if(!strcmp(thegame.name, "Solo"))
{
diff --git a/apps/plugins/rockboy/lcd.c b/apps/plugins/rockboy/lcd.c
index 387a88c3df..92db851ee8 100644
--- a/apps/plugins/rockboy/lcd.c
+++ b/apps/plugins/rockboy/lcd.c
@@ -64,6 +64,12 @@ unsigned char *vdest;
fb_data *vdest;
#endif
+static fb_data* get_framebuffer(void)
+{
+ struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
+ return vp_main->buffer->fb_ptr;
+}
+
#ifndef ASM_UPDATEPATPIX
static void updatepatpix(void) ICODE_ATTR;
static void updatepatpix(void)
@@ -741,10 +747,11 @@ static void spr_scan(void)
void lcd_begin(void)
{
+ fb_data *lcd_fb = get_framebuffer();
#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
- vdest=(unsigned char*)*rb->lcd_framebuffer;
+ vdest=(unsigned char*)lcd_fb;
#else
- vdest=*rb->lcd_framebuffer;
+ vdest=lcd_fb;
#endif
#ifdef HAVE_LCD_COLOR
@@ -975,9 +982,9 @@ void lcd_refreshline(void)
#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
if(options.scaling==3) {
- rb->lcd_blit_pal256((unsigned char*)*rb->lcd_framebuffer,(LCD_WIDTH-160)/2, (LCD_HEIGHT-144)/2, (LCD_WIDTH-160)/2, (LCD_HEIGHT-144)/2, 160, 144);
+ rb->lcd_blit_pal256((unsigned char*)lcd_fb,(LCD_WIDTH-160)/2, (LCD_HEIGHT-144)/2, (LCD_WIDTH-160)/2, (LCD_HEIGHT-144)/2, 160, 144);
} else {
- rb->lcd_blit_pal256((unsigned char*)*rb->lcd_framebuffer,0,0,0,0,LCD_WIDTH,LCD_HEIGHT);
+ rb->lcd_blit_pal256((unsigned char*)lcd_fb,0,0,0,0,LCD_WIDTH,LCD_HEIGHT);
}
#else
if(options.scaling==3) {
diff --git a/apps/plugins/rockboy/sys_rockbox.c b/apps/plugins/rockboy/sys_rockbox.c
index 364176ce2d..64acd37563 100644
--- a/apps/plugins/rockboy/sys_rockbox.c
+++ b/apps/plugins/rockboy/sys_rockbox.c
@@ -282,6 +282,12 @@ fb_data *frameb;
void vid_update(int scanline)
{
register int cnt=0;
+ static fb_data *lcd_fb = NULL;
+ if (!lcd_fb)
+ {
+ struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
+ lcd_fb = vp_main->buffer->fb_ptr;
+ }
int scanline_remapped;
#if (LCD_HEIGHT == 64) && (LCD_DEPTH == 1) /* Archos, Clip, m200v4 */
int balance = 0;
@@ -290,7 +296,7 @@ void vid_update(int scanline)
else if (fb.mode==2)
scanline-=8;
scanline_remapped = scanline / 16;
- frameb = *rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
+ frameb = lcd_fb + scanline_remapped * LCD_WIDTH;
while (cnt < 160) {
balance += LCD_WIDTH;
if (balance > 0)
@@ -316,7 +322,7 @@ void vid_update(int scanline)
else if (fb.mode==2)
scanline-=8;
scanline_remapped = scanline / 4;
- frameb = *rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
+ frameb = lcd_fb + scanline_remapped * LCD_WIDTH;
while (cnt < 160) {
*(frameb++) = (scan.buf[0][cnt]&0x3) |
((scan.buf[1][cnt]&0x3)<<2) |
diff --git a/apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c b/apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c
index 5e0ccfb167..85c245ed9c 100644
--- a/apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c
+++ b/apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c
@@ -67,6 +67,7 @@
#define RBSDL_EXTRA0 SDLK_0
/* Initialization/Query functions */
+static fb_data *lcd_fb;
static int ROCKBOX_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **ROCKBOX_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *ROCKBOX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
@@ -447,6 +448,8 @@ static void rb_pixelformat(SDL_PixelFormat *vformat)
int ROCKBOX_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
+ struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
+ lcd_fb = vp_main->buffer->fb_ptr;
/* we change this during the SDL_SetVideoMode implementation... */
rb_pixelformat(vformat);
@@ -639,7 +642,7 @@ SDL_Surface *ROCKBOX_SetVideoMode(_THIS, SDL_Surface *current,
this->hidden->w = current->w = width;
this->hidden->h = current->h = height;
current->pitch = current->w * (bpp / 8);
- current->pixels = this->hidden->direct ? *rb->lcd_framebuffer : this->hidden->buffer;
+ current->pixels = this->hidden->direct ? lcd_fb : this->hidden->buffer;
/* We're done */
return(current);
@@ -674,7 +677,7 @@ static void flip_pixels(int x, int y, int w, int h)
for(int x_0 = x; x_0 < x + w; ++x_0)
{
/* swap pixels directly in the framebuffer */
- *rb->lcd_framebuffer[y_0 * LCD_WIDTH + x_0] = swap16(*rb->lcd_framebuffer[y_0 * LCD_WIDTH + x_0]);
+ lcd_fb[y_0 * LCD_WIDTH + x_0] = swap16(lcd_fb[y_0 * LCD_WIDTH + x_0]);
}
}
}
@@ -684,7 +687,7 @@ static void blit_rotated(fb_data *src, int x, int y, int w, int h)
{
for(int y_0 = y; y_0 < y + h; ++y_0)
for(int x_0 = x; x_0 < x + w; ++x_0)
- *rb->lcd_framebuffer[x_0 * LCD_WIDTH + y_0] = src[(LCD_WIDTH - y_0) * LCD_HEIGHT + x_0];
+ lcd_fb[x_0 * LCD_WIDTH + y_0] = src[(LCD_WIDTH - y_0) * LCD_HEIGHT + x_0];
}
static void ROCKBOX_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
@@ -720,7 +723,7 @@ static void ROCKBOX_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
out_bmp.width = LCD_WIDTH;
out_bmp.height = LCD_HEIGHT;
- out_bmp.data = (char*)*rb->lcd_framebuffer;
+ out_bmp.data = (char*)lcd_fb;
simple_resize_bitmap(&in_bmp, &out_bmp);
}
else
diff --git a/apps/plugins/test_resize.c b/apps/plugins/test_resize.c
index 3e50bdc8cc..443067c7e1 100644
--- a/apps/plugins/test_resize.c
+++ b/apps/plugins/test_resize.c
@@ -64,8 +64,8 @@ static fb_data output_bmp_data[MAX_OUTPUT_WIDTH*MAX_OUTPUT_HEIGHT];
enum plugin_status plugin_start(const void* parameter)
{
(void)parameter;
-
- b = *rb->lcd_framebuffer;
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ b = vp_main->buffer->fb_ptr;
rb->lcd_set_background(LCD_RGBPACK(0,0,0));
rb->lcd_clear_display(); // TODO: Optimizes this by e.g. invalidating rects
diff --git a/apps/plugins/test_viewports.c b/apps/plugins/test_viewports.c
index 465a832399..60c6672456 100644
--- a/apps/plugins/test_viewports.c
+++ b/apps/plugins/test_viewports.c
@@ -35,7 +35,7 @@ static struct viewport vp0 =
{
.x = 0,
.y = 0,
- .width = LCD_WIDTH,
+ .width = LCD_WIDTH/ 2 + LCD_WIDTH / 3,
.height = 20,
.font = FONT_UI,
.drawmode = DRMODE_SOLID,
@@ -120,15 +120,37 @@ static struct viewport rvp1 =
#endif
+static void *test_address_fn(int x, int y)
+{
+ struct frame_buffer_t *fb = vp0.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 % fb->elems);
+}
enum plugin_status plugin_start(const void* parameter)
{
(void)parameter;
char buf[80];
int i,y;
+ fb_data vp_buffer[LCD_NBELEMS(vp0.width, vp0.height)];
+ struct frame_buffer_t fb;
+
+ fb.stride = STRIDE_MAIN(vp0.width, vp0.height);
+
+ fb.fb_ptr = vp_buffer;
+ fb.elems = LCD_NBELEMS(vp0.width, vp0.height);
+ fb.get_address_fn = &test_address_fn;
+
+ rb->viewport_set_buffer(&vp0, &fb, SCREEN_MAIN);
rb->screens[SCREEN_MAIN]->set_viewport(&vp0);
rb->screens[SCREEN_MAIN]->clear_viewport();
+
rb->screens[SCREEN_MAIN]->puts_scroll(0,0,"Viewport testing plugin - this is a scrolling title");
rb->screens[SCREEN_MAIN]->set_viewport(&vp1);
@@ -192,6 +214,9 @@ enum plugin_status plugin_start(const void* parameter)
rb->screens[SCREEN_REMOTE]->update();
#endif
+ rb->button_clear_queue();
+ while(rb->button_get(true) <= BUTTON_NONE)
+ ;;
rb->button_get(true);
diff --git a/apps/plugins/xworld/sys.c b/apps/plugins/xworld/sys.c
index 0bd1e0dc08..c57da9456b 100644
--- a/apps/plugins/xworld/sys.c
+++ b/apps/plugins/xworld/sys.c
@@ -40,6 +40,7 @@
#include "engine.h"
static struct System* save_sys;
+static fb_data *lcd_fb = NULL;
static bool sys_save_settings(struct System* sys)
{
@@ -438,6 +439,8 @@ void sys_init(struct System* sys, const char* title)
{
sys_reset_settings(sys);
}
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
}
void sys_destroy(struct System* sys)
@@ -584,7 +587,7 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16
struct bitmap out_bmp;
out_bmp.width = LCD_WIDTH;
out_bmp.height = LCD_HEIGHT;
- out_bmp.data = (unsigned char*) *rb->lcd_framebuffer;
+ out_bmp.data = (unsigned char*) lcd_fb;
#ifdef HAVE_LCD_COLOR
if(sys->settings.scaling_quality == 1)
@@ -631,25 +634,25 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16
{
#ifdef HAVE_LCD_COLOR
int r, g, b;
- fb_data pix = *rb->lcd_framebuffer[y * LCD_WIDTH + x];
+ fb_data pix = lcd_fb[y * LCD_WIDTH + x];
#if (LCD_DEPTH > 24)
r = 0xff - pix.r;
g = 0xff - pix.g;
b = 0xff - pix.b;
- *rb->lcd_framebuffer[y * LCD_WIDTH + x] = (fb_data) { b, g, r, 255 };
+ lcd_fb[y * LCD_WIDTH + x] = (fb_data) { b, g, r, 255 };
#elif (LCD_DEPTH == 24)
r = 0xff - pix.r;
g = 0xff - pix.g;
b = 0xff - pix.b;
- *rb->lcd_framebuffer[y * LCD_WIDTH + x] = (fb_data) { b, g, r };
+ lcd_fb[y * LCD_WIDTH + x] = (fb_data) { b, g, r };
#else
r = RGB_UNPACK_RED (pix);
g = RGB_UNPACK_GREEN(pix);
b = RGB_UNPACK_BLUE (pix);
- *rb->lcd_framebuffer[y * LCD_WIDTH + x] = LCD_RGBPACK(0xff - r, 0xff - g, 0xff - b);
+ lcd_fb[y * LCD_WIDTH + x] = LCD_RGBPACK(0xff - r, 0xff - g, 0xff - b);
#endif
#else
- *rb->lcd_framebuffer[y * LCD_WIDTH + x] = LCD_BRIGHTNESS(0xff - *rb->lcd_framebuffer[y * LCD_WIDTH + x]);
+ lcd_fb[y * LCD_WIDTH + x] = LCD_BRIGHTNESS(0xff - lcd_fb[y * LCD_WIDTH + x]);
#endif
}
}
@@ -671,14 +674,14 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16
if(prev_frames && orig_fb)
{
- rb->memcpy(orig_fb, *rb->lcd_framebuffer, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT);
+ rb->memcpy(orig_fb, lcd_fb, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT);
/* fancy useless slow motion blur */
for(int y = 0; y < LCD_HEIGHT; ++y)
{
for(int x = 0; x < LCD_WIDTH; ++x)
{
int r, g, b;
- fb_data pix = *rb->lcd_framebuffer[y * LCD_WIDTH + x];
+ fb_data pix = lcd_fb[y * LCD_WIDTH + x];
r = RGB_UNPACK_RED (pix);
g = RGB_UNPACK_GREEN(pix);
b = RGB_UNPACK_BLUE (pix);
@@ -695,7 +698,7 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16
r /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1);
g /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1);
b /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1);
- *rb->lcd_framebuffer[y * LCD_WIDTH + x] = LCD_RGBPACK(r, g, b);
+ lcd_fb[y * LCD_WIDTH + x] = LCD_RGBPACK(r, g, b);
}
}
prev_baseidx -= LCD_WIDTH * LCD_HEIGHT;
diff --git a/apps/plugins/zxbox/zxvid_16bpp.c b/apps/plugins/zxbox/zxvid_16bpp.c
index f8482e3147..f0e2cee5ac 100644
--- a/apps/plugins/zxbox/zxvid_16bpp.c
+++ b/apps/plugins/zxbox/zxvid_16bpp.c
@@ -33,6 +33,8 @@ static const unsigned _16bpp_colors[32] = {
LCD_RGBPACK(IB1, IB1, IB0), LCD_RGBPACK(IB1, IB1, IB1),
};
+static fb_data *lcd_fb = NULL;
+
void init_spect_scr(void)
{
int i;
@@ -49,6 +51,11 @@ void init_spect_scr(void)
void update_screen(void)
{
+ if (!lcd_fb)
+ {
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
+ }
fb_data *frameb;
int y=0;
@@ -58,7 +65,7 @@ void update_screen(void)
byte *scrptr;
scrptr = (byte *) SPNM(image);
*/
- frameb = *rb->lcd_framebuffer;
+ frameb = lcd_fb;
for ( y = 0 ; y < HEIGHT*WIDTH; y++ ){
frameb[y] = FB_SCALARPACK(_16bpp_colors[(unsigned)sp_image[y]]);
}
@@ -68,7 +75,7 @@ void update_screen(void)
int srcx, srcy=0; /* x / y coordinates in source image */
unsigned char* image;
image = sp_image + ( (Y_OFF)*(WIDTH) ) + X_OFF;
- frameb = *rb->lcd_framebuffer;
+ frameb = lcd_fb;
for(y = 0; y < LCD_HEIGHT; y++)
{
srcx = 0; /* reset our x counter before each row... */
diff --git a/apps/plugins/zxbox/zxvid_2bpp.c b/apps/plugins/zxbox/zxvid_2bpp.c
index 9772625387..97e6a5de76 100644
--- a/apps/plugins/zxbox/zxvid_2bpp.c
+++ b/apps/plugins/zxbox/zxvid_2bpp.c
@@ -26,6 +26,8 @@ static const unsigned char graylevels[16] = {
0, 1, 1, 1, 2, 2, 3, 3
};
+static fb_data *lcd_fb = NULL;
+
void init_spect_scr(void)
{
int i;
@@ -41,6 +43,11 @@ void init_spect_scr(void)
}
void update_screen(void)
{
+ if (!lcd_fb)
+ {
+ struct viewport *vp_main = rb->lcd_set_viewport(NULL);
+ lcd_fb = vp_main->buffer->fb_ptr;
+ }
fb_data *frameb;
int y=0;
int x=0;
@@ -51,7 +58,7 @@ void update_screen(void)
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
for(y = 0; y < LCD_HEIGHT; y++)
{
- frameb = *rb->lcd_framebuffer + (y) * FB_WIDTH;
+ frameb = lcd_fb + (y) * FB_WIDTH;
srcx = 0; /* reset our x counter before each row... */
for(x = 0; x < LCD_WIDTH; x++)
{
@@ -67,7 +74,7 @@ void update_screen(void)
int shift;
for(y = 0; y < LCD_HEIGHT; y++)
{
- frameb = *rb->lcd_framebuffer + (y/4) * LCD_WIDTH;
+ frameb = lcd_fb + (y/4) * LCD_WIDTH;
srcx = 0; /* reset our x counter before each row... */
shift = ((y & 3 ) * 2 );
mask = ~pixmask[y & 3];
@@ -84,7 +91,7 @@ void update_screen(void)
int shift;
for(y = 0; y < LCD_HEIGHT; y++)
{
- frameb = *rb->lcd_framebuffer + (y/8) * LCD_WIDTH;
+ frameb = lcd_fb + (y/8) * LCD_WIDTH;
srcx = 0; /* reset our x counter before each row... */
shift = (y & 7);
mask = ~pixmask[y & 7];
diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c
index f735afe84d..b211fad331 100644
--- a/apps/recorder/keyboard.c
+++ b/apps/recorder/keyboard.c
@@ -1009,7 +1009,7 @@ static void kbd_draw_buttons(struct keyboard_parameters *pm, struct screen *sc)
int sc_w = sc->getwidth(), sc_h = sc->getheight();
viewport_set_defaults(&vp, sc->screen_type);
vp.flags |= VP_FLAG_ALIGN_CENTER;
- sc->set_viewport(&vp);
+ struct viewport *last_vp = sc->set_viewport(&vp);
text_h = sc->getcharheight();
button_h = GRID_SIZE(sc->screen_type, text_h);
text_y = (button_h - text_h) / 2 + 1;
@@ -1039,7 +1039,7 @@ static void kbd_draw_buttons(struct keyboard_parameters *pm, struct screen *sc)
vp.x += vp.width;
sc->vline(0, 0, button_h);
sc->putsxy(0, text_y, str(LANG_KBD_CANCEL));
- sc->set_viewport(NULL);
+ sc->set_viewport(last_vp);
}
static int keyboard_touchscreen(struct keyboard_parameters *pm,
diff --git a/apps/screen_access.c b/apps/screen_access.c
index 44e90742b0..390fb2ad4e 100644
--- a/apps/screen_access.c
+++ b/apps/screen_access.c
@@ -35,6 +35,7 @@
#include "backlight.h"
#include "screen_access.h"
#include "backdrop.h"
+#include "viewport.h"
/* some helper functions to calculate metrics on the fly */
static int screen_helper_getcharwidth(void)
@@ -87,7 +88,17 @@ static void screen_helper_put_line(int x, int y, struct line_desc *line,
va_end(ap);
}
+void screen_helper_lcd_viewport_set_buffer(struct viewport *vp, struct frame_buffer_t *buffer)
+{
+ viewport_set_buffer(vp, buffer, SCREEN_MAIN);
+}
+
#if NB_SCREENS == 2
+void screen_helper_lcd_remote_viewport_set_buffer(struct viewport *vp, struct frame_buffer_t *buffer)
+{
+ viewport_set_buffer(vp, buffer, SCREEN_REMOTE);
+}
+
static int screen_helper_remote_getcharwidth(void)
{
return font_get(lcd_remote_getfont())->maxwidth;
@@ -156,7 +167,11 @@ struct screen screens[NB_SCREENS] =
.has_disk_led=true,
#endif
.set_drawmode=&screen_helper_set_drawmode,
+ .init_viewport=&lcd_init_viewport,
.set_viewport=&lcd_set_viewport,
+ .set_viewport_ex=&lcd_set_viewport_ex,
+ .viewport_set_buffer = &screen_helper_lcd_viewport_set_buffer,
+ .current_viewport = &lcd_current_viewport,
.getwidth=&lcd_getwidth,
.getheight=&lcd_getheight,
.getstringsize=&lcd_getstringsize,
@@ -221,7 +236,6 @@ struct screen screens[NB_SCREENS] =
.backdrop_load=&backdrop_load,
.backdrop_show=&backdrop_show,
#endif
- .set_framebuffer = (void*)lcd_set_framebuffer,
#if defined(HAVE_LCD_COLOR)
.gradient_fillrect = lcd_gradient_fillrect,
.gradient_fillrect_part = lcd_gradient_fillrect_part,
@@ -241,7 +255,11 @@ struct screen screens[NB_SCREENS] =
.getcharheight=screen_helper_remote_getcharheight,
.has_disk_led=false,
.set_drawmode=&lcd_remote_set_drawmode,
+ .init_viewport=&lcd_remote_init_viewport,
.set_viewport=&lcd_remote_set_viewport,
+ .set_viewport_ex=&lcd_remote_set_viewport_ex,
+ .viewport_set_buffer = &screen_helper_lcd_remote_viewport_set_buffer,
+ .current_viewport = &lcd_remote_current_viewport,
.getwidth=&lcd_remote_getwidth,
.getheight=&lcd_remote_getheight,
.getstringsize=&lcd_remote_getstringsize,
@@ -307,7 +325,6 @@ struct screen screens[NB_SCREENS] =
.backdrop_load=&remote_backdrop_load,
.backdrop_show=&remote_backdrop_show,
#endif
- .set_framebuffer = (void*)lcd_remote_set_framebuffer,
.put_line = screen_helper_remote_put_line,
}
#endif /* NB_SCREENS == 2 */
diff --git a/apps/screen_access.h b/apps/screen_access.h
index 79ad79c153..81c7cb2a85 100644
--- a/apps/screen_access.h
+++ b/apps/screen_access.h
@@ -58,7 +58,11 @@ struct screen
bool has_disk_led;
#endif
void (*set_drawmode)(int mode);
- void (*set_viewport)(struct viewport* vp);
+ struct viewport* (*init_viewport)(struct viewport* vp);
+ struct viewport* (*set_viewport)(struct viewport* vp);
+ struct viewport* (*set_viewport_ex)(struct viewport* vp, int flags);
+ void (*viewport_set_buffer)(struct viewport *vp, struct frame_buffer_t *buffer);
+ struct viewport** current_viewport;
int (*getwidth)(void);
int (*getheight)(void);
int (*getstringsize)(const unsigned char *str, int *w, int *h);
@@ -126,7 +130,6 @@ struct screen
bool (*backdrop_load)(const char *filename, char* backdrop_buffer);
void (*backdrop_show)(char* backdrop_buffer);
#endif
- void (*set_framebuffer)(void *framebuffer);
#if defined(HAVE_LCD_COLOR)
void (*gradient_fillrect)(int x, int y, int width, int height,
unsigned start, unsigned end);
diff --git a/apps/screens.c b/apps/screens.c
index 020d0a3021..fde99912d5 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -207,12 +207,13 @@ bool set_time_screen(const char* title, struct tm *tm)
/* 6 possible cursor possitions, 2 values stored for each: x, y */
unsigned int cursor[6][2];
struct viewport *vp = &viewports[s];
+ struct viewport *last_vp;
struct screen *screen = &screens[s];
static unsigned char rtl_idx[] =
{ IDX_SECONDS, IDX_MINUTES, IDX_HOURS, IDX_DAY, IDX_MONTH, IDX_YEAR };
viewport_set_defaults(vp, s);
- screen->set_viewport(vp);
+ last_vp = screen->set_viewport(vp);
nb_lines = viewport_get_nb_lines(vp);
/* minimum lines needed is 2 + title line */
@@ -283,7 +284,7 @@ bool set_time_screen(const char* title, struct tm *tm)
if (nb_lines > 5)
screen->puts(0, 5, str(LANG_TIME_REVERT));
screen->update_viewport();
- screen->set_viewport(NULL);
+ screen->set_viewport(last_vp);
}
/* set the most common numbers */
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);