Jump to content

Display Scrolling all the time


goeck

Recommended Posts

Hey everyone,

first post in the new forum..whohoo :-)Anyways, I have a concern here with my SSD1306 driver which I am about to release to the public, but prior I really want nice console up-scrolling.

Now I implemented some stuff, but I see the lines get scrolled all the way from the first line beeing written leading to spare lines between the normal written lines.

The scrolling gets called from console.c everytime gwinPutChar() gets called. Looking at the code tells me, that scrolling should only be called, when y_cursor and lineheight > gdisp_height (64 in this case). As far as I figured out all the defines and measures are there.


void gwinPutChar(GHandle gh, char c) {
...

if (gcw->cy + gcw->fy > gh->height) {
#if GDISP_NEED_SCROLL
/* scroll the console */
gdispVerticalScroll(gh->x, gh->y, gh->width, gh->height, gcw->fy, gh->bgcolor);
/* reset the cursor to the start of the last line */
gcw->cx = 0;
gcw->cy = (((coord_t)(gh->height/gcw->fy))-1)*gcw->fy;
#else
/* clear the console */
gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
/* reset the cursor to the top of the window */
gcw->cx = 0;
gcw->cy = 0;
#endif
}

...
}

Does anyone has a hint for me?

Thanks in advance.

Cheers

Stefan

Link to comment
Share on other sites

Hey goeck and welcome to the new forum :D

I'm sorry but I'm trying really hard to understand what you're saying... Is something not working for you or are you asking why it's implemented that way? Or is maybe something broken? I would have tried it out before this post but I'm currently not able to.

~ Tectu

Link to comment
Share on other sites

Hey Tectu,

thanks for trying... ;-) ... this is propably the most occuring issue that I personally have: "say it right, dude... :evil: " (speaking to myself)

The scrolling behaviour is some sort of broken.

OK, the point is I have written some sort of scrolling algorithm, that - when used as a simple function, called "by hand" - shits everything 11 pixels upwards which is just a line using UI2 font [i have to get the line height and spacing later on to automate this].

Now I put this stuff in the function sceleton called gdisp_lld_vertical_scroll(...). This gets called by gwinPutChar() under certain circumstances.

What I get afterwards is scrolling everytime I put some text on the display; no matter if its the very first line or the tenth. I have 5 visible lines on the display using the mentioned font.

After posting this issue, I even commented out the call of gdisp_lld_vertical_scroll() in gwinPutChar() and still, everything gets scrolled. The behaviour that I want to achieve is scrolling a line up only if the added line to the console was not visible. This should be done bye the if (gcw->cy + gcw->fy > gh->height) statement in gwinPutChar().

I'll investigate further tomorrow. My guess is that I have left some code unattended somewhere and now it's playing tricks... Couldn't find it till now.

Good night

Cheers

Link to comment
Share on other sites

OK, now I got it...

console.c states at the beginning

#define GWIN_CONSOLE_USE_CLEAR_LINES			TRUE

which I actually activated (set to true) and has been the problem. In console.c in gwinPutChar() after computing whether to scroll or not this code comes in focus


#if GWIN_CONSOLE_USE_CLEAR_LINES
/* clear to the end of the line */
if (gcw->cx == 0)
gdispFillArea(gh->x, gh->y + gcw->cy, gh->width, gcw->fy, gh->bgcolor);
#endif

I think this takes me to this portion of emulation.c


void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#if GDISP_HARDWARE_SCROLL
gdisp_lld_vertical_scroll(x, y, cx, cy, cy, color);
#elif GDISP_HARDWARE_LINES
coord_t x1, y1;

x1 = x + cx - 1;
y1 = y + cy;
for(; y < y1; y++)
gdisp_lld_draw_line(x, y, x1, y, color);
#else
coord_t x0, x1, y1;

x0 = x;
x1 = x + cx;
y1 = y + cy;
for(; y < y1; y++)
for(x = x0; x < x1; x++)
gdisp_lld_draw_pixel(x, y, color);
#endif
}

and since I have hardware scroll enabled this comes out like a double scroll.

Now I set GWIN_CONSOLE_USE_CLEAR_LINES to false and everything is just as expected: only one line scrolled only when the screen is already full :-)

Thanks for the time and support anyways, tectu.

Keep up the good work!

Cheers

Link to comment
Share on other sites

Oh, sorry about that... ;) But by the way, everytime I update the code from the repo, I manually have to set GWIN_CONSOLE_USE_CLEAR_LINES to FALSE, otherwise I get the bug back. I guess that's not the intended way of doing it. I have to look at the actual root of this bug again...

Anyway, now I am happy with nice smooth scrolling and thus I want to release the first version of this driver.

I packed everything together and uploaded it with this post.

Notes:

- Driver works only with SSD1306 hooked up over I2C (at least SPI lld needs to be added)

- Driver is written for 128x64 pixel displays (128x32 are only partly suppoerted and need small further work)

- after using GFX subsystem gdisp_lld_diaply() hast to be called "by hand" to push over framebuffer to display

- for nice scrolling GWIN_CONSOLE_USE_CLEAR_LINES has to be set to FALSE in file console.c

Please someone have a look at it.

Cheers

Stefan

SSD1306.zip

Link to comment
Share on other sites

  • 4 weeks later...

There is still a bug here in the driver scrolling routine.

GDISP_CONSOLE_USE_CLEAR_LINES just clears to the end of the line. Whilst turning this off has made the problem "seem" to disappear it is actually still there. The issue will continue to appear any time you try to fill an area using gdispFillArea().

What is happening is that because your driver has not defined a "fillarea" routine (or it is not turned on in your driver config file) the emulation layer looks for an alternative mechanism to quickly fill the area. In this case it has determined that you have a vertical scroll routine so it is using that to fill the area.

If you look at the documention for gdisp_lld_vertical_scroll() you will see that it is supposed to clear the new area revealed by the scroll operation. In this case the entire area is being scrolled out which should result in the entire area being "revealed" and therefore cleared. Have a look at your code in the gdisp_lld_vertical_scroll() routine specificly for this boundary case.

It is probably a good idea for performance reasons to also create and turn on a fill area routine.

Link to comment
Share on other sites

Hey, thanks for the input. This kind of hints solve the missing links in my brain... 8-)

I implemented gdisp_lld_fill_area() as just a function body and set GDISP_CONSOLE_USE_CLEAR_LINES back to TRUE and as you stated it's actually the same experience.

Firstly I will improve the scrolling algorithm again and afterwards imlement a filling strategy.

--- EDIT: ------

Just got it working. Thanks again for that hint! After Implementing fill area, pretty straight forward though, and killing a bug in the buffer shifting loop everything now works again. I uploaded it under v0.4 in the drivers thread (link mentioned earlier here).

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...