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
This commit is contained in:
William Wilgus 2020-10-07 02:01:35 -04:00
parent 12f3ed1699
commit 3237ae4a4f
74 changed files with 1595 additions and 967 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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)
{

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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;
}

View File

@ -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.

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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, ...)

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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)

View File

@ -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++;
}

View File

@ -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;

View File

@ -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();

View File

@ -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,

View File

@ -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
{

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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 */

View File

@ -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;

View File

@ -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();
}

View File

@ -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"))
{

View File

@ -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) {

View File

@ -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) |

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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... */

View File

@ -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];

View File

@ -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,

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 );

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -46,17 +46,32 @@
#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);
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;

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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__ */

View File

@ -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;
#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
#define FBADDR(x, y) (lcd_framebuffer + ((x) * LCD_FBHEIGHT) + (y))
#else
#define FBADDR(x, y) (lcd_framebuffer + ((y) * LCD_FBWIDTH) + (x))
#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 LCD_NBELEMS(w, h) ((w*STRIDE_MAIN(w, h)) + h)
#else
#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);
extern void lcd_set_drawinfo(int mode, unsigned foreground,
unsigned background);
void lcd_set_backdrop(fb_data* backdrop);
fb_data* lcd_get_backdrop(void);
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_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__ */

View File

@ -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. */

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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);