summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2020-10-07 02:01:35 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2020-10-26 12:28:48 -0400
commit3237ae4a4ff9296a377ff9194a11038da161208f (patch)
treeaf4338c78467b9b0845d76c39da1fbe10f25e23e /apps
parent12f3ed1699d6bef25bed90ba95cbcc1a6bb4934a (diff)
downloadrockbox-3237ae4a4f.tar.gz
rockbox-3237ae4a4f.zip
LCD core move buf ptr and address look up function viewport struct
I'm currently running up against the limitations of the lcd_draw functions I want these functions to be able to be used on any size buffer not just buffers with a stride matching the underlying device [DONE] allow the framebuffer to be decoupled from the device framebuffer [DONE need examples] allow for some simple blit like transformations [DONE] remove the device framebuffer from the plugin api [DONE}ditto remote framebuffer [DONE] remove _viewport_get_framebuffer you can call struct *vp = lcd_set_viewport(NULL) and vp->buffer->fb_ptr while remote lcds may compile (and work in the sim) its not been tested on targets [FIXED] backdrops need work to be screen agnostic [FIXED] screen statusbar is not being combined into the main viewport correctly yet [FIXED] screen elements are displayed incorrectly after switch to void* [FIXED] core didn't restore proper viewport on splash etc. [NEEDS TESTING] remote lcd garbled data [FIXED] osd lib garbled screen on bmp_part [FIXED] grey_set_vp needs to return old viewport like lcd_set_viewport [FIXED] Viewport update now handles viewports with differing buffers/strides by copying to the main buffer [FIXED] splash on top of WPS leaves old framebuffer data (doesn't redraw) [UPDATE] refined this a bit more to have clear_viewport set the clean bit and have skin_render do its own screen clear scrolling viewports no longer trigger wps refresh also fixed a bug where guisyncyesno was displaying and then disappearing [ADDED!] New LCD macros that allow you to create properly size frame buffers in you desired size without wasting bytes (LCD_ and LCD_REMOTE_) LCD_STRIDE(w, h) same as STRIDE_MAIN LCD_FBSTRIDE(w, h) returns target specific stride for a buffer W x H LCD_NBELEMS(w, h) returns the number of fb_data sized elemenst needed for a buffer W x H LCD_NATIVE_STRIDE(s) conversion between rockbox native vertical and lcd native stride (2bitH) test_viewports.c has an example of usage [FIXED!!] 2bit targets don't respect non-native strides [FIXED] Few define snags Change-Id: I0d04c3834e464eca84a5a715743a297a0cefd0af
Diffstat (limited to 'apps')
-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
54 files changed, 472 insertions, 172 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 */