Redesign text rendering.
lennart-benschop opened this issue · comments
I'm less than happy with the way the entire canvas is re-rendered each frame from the text data.
As soon as we add line drawing and whatnot, we cannot store the parameters of all lines drawn and re-render them each time.
Think of the triangles.bas demo that keeps drawing triangles indefinitely, where each triangle overwrites parts of previous ones.
So I would like to draw all characters, lines etc. onto one 'surface' (which may or may not be the window's own canvas) and then possibly blit this into the window's canvas each frame. This way we may be able to draw sprites on top of this when we get to that (or the cursor possibly). When scrolling we move part of the 'surface' using an appropriate blit function. Characters can be drawn by plotting each pixel (first clear the rectangle to the background colour).
The real Agon hardware draws each character as a bitmap into the frame buffer. When you update a character in the font using VDU 23, future instances will be redrawn with the updated pattern, but previously drawn characters will stay as-is.
Totally agree with this. I did it this way, because I thought it would be easy to support the get_char() function of the vdp. But I did not look into it. It actually reads pixels from the screenbuffer and trys to match them with the chars in the font. So my approach can result in a different behaviour when there are same looking chars in the font. So it needs to be changed anyway.
My current idea is to use 2 buffers. One for the textrendering and one for sprites / graphics. Then just combine those two to the result framebuffer each vsync.
I would use the first buffer for both text and PLOT graphics (as the real Agon VDP has this the same) and use the second buffer only for sprites. The GET$() function cannot read a char from the screen if a line is drawn over it, neither on the real Agon nor on the emulator.