Page 1 of 1

Terminal scrolling

Posted: Mon May 18, 2020 9:40 am
by nexos
Hello,
I am implementing a graphical terminal driver, and was wondering how you scroll. I know how to scroll in text mode, but not graphical mode.
Thank you for your help.

Re: Terminal scrolling

Posted: Mon May 18, 2020 10:12 am
by Octocontrabass
It works the same regardless of mode.

Move the contents of your back buffer up one line, then copy it to the display adapter's frame buffer.

Or, if your terminal fills the whole screen and you have appropriate driver support, tell the display adapter to begin displaying one line lower in the frame buffer.

Re: Terminal scrolling

Posted: Mon May 18, 2020 11:06 am
by AndrewAPrice
Have your terminal driver/emulator store an array of lines (start a new entry whenever your program prints '\n', and if you have a fixed size display you can also start a new entry after reaching the edge).

When you go to update the screen, start drawing backwards from the scroll position (where scroll offset '0' means you're at the bottom and showing the latest stuff.)

Re: Terminal scrolling

Posted: Sat May 23, 2020 7:48 am
by nexos
I have gotten it to scroll one pixel, but when it tries to scroll up one line of text, it will freeze and display garbage at the top of the screen. Here is the scrolling code:

Code: Select all

void video_scroll()
{
    for(int i = 0; i < 8; i++)
    {
        int i = 0;
        for(i = 0; i < vid_info.framebufferWidth * (vid_info.framebufferHeight - 1); i++)
        {
            framebuffer[i] = framebuffer[i + vid_info.framebufferWidth];
        }
        for(int i = vid_info.framebufferWidth * (vid_info.framebufferHeight - 1); i < vid_info.framebufferWidth * vid_info.framebufferHeight; i++)
           framebuffer[i] = 0x000a3cc8;
    }
}
It loops 8 times, as that is the size of my font.

Re: Terminal scrolling

Posted: Sat May 23, 2020 10:21 am
by PeterX
You use the int variable i in three different contexts. That seems wrong to me.

Greetings
Peter

Re: Terminal scrolling

Posted: Sat May 23, 2020 10:51 am
by kzinti
You should scroll all 8 pixels rows in one loop, not do it 1 pixel row at a time. This would make you scrolling 8 times faster.

Here is how I do it (my own characters are 16 bits high) and the frame buffer is 32 bits/pixel.

Code: Select all

void GraphicsConsole::Scroll() const
{
    // Scroll text
    for (int y = 16; y != m_backbuffer->height; ++y)
    {
        void* dest = (void*)(((uintptr_t)m_backbuffer->pixels) + (y - 16) * m_backbuffer->pitch);
        const void* src = (void*)(((uintptr_t)m_backbuffer->pixels) + y * m_backbuffer->pitch);
        memcpy(dest, src, m_backbuffer->width * 4);
    }

    // Erase last line
    for (int y = m_backbuffer->height - 16; y != m_backbuffer->height; ++y)
    {
        uint32_t* dest = (uint32_t*)(((uintptr_t)m_backbuffer->pixels) + y * m_backbuffer->pitch);
        for (int i = 0; i != m_backbuffer->width; ++i)
        {
            *dest++ = m_backgroundColor;
        }
    }
}

Re: Terminal scrolling

Posted: Sat May 23, 2020 1:02 pm
by eekee
kzinti wrote:You should scroll all 8 pixels rows in one loop, not do it 1 pixel row at a time. This would make you scrolling 8 times faster.
Yes. And, not to rush you, but if you buffer the input, you can scroll the number of lines in the buffer. XTerm calls this "jumpscrolling", and it is insanely quick! I guess the buffering would be another thing to get right, though.