Thursday, 22nd July 2010
The dsPIC33 video display controller project I am working on needs to support several common text output and drawing operations offered by existing BBC BASIC implementations. The previous demo included basic point, line and circle outlining functions, but I also need to output text and outline (or fill) rectangles, circles, ellipses and triangles. On top of that the drawing operations need to support multiple colours and plotting modes. Owing to processing power and memory limitations the output is black and white only but different "shades" can be implemented with dither patterns. The plotting modes allow you to perform logical operations between what you are drawing and what's currently on the buffer — for example, you could fill a circle that is logically ORed with the existing background or draw a line that inverts every pixel along its length rather than applying the new colour.
Filled rectangles and text output produce the above image.
Finding suitable algorithms for some of these routines has been a little tricky at times. Due to the way that filled shapes can be set to invert (rather than overwrite) what's on the background there has to be zero overdraw and the outline of filled triangles should exactly match the outline of a triangle drawn by plotting a line between its three vertices; this makes combining triangles to form more complex shapes possible, as you can guarantee that the overlap between the two shared vertices of a pair of triangles covers the same pixels as a line drawn between those two vertices.
Filled triangles produce a solid cube.
I ended up writing a program in C# that would plot a random triangle using the triangle filler I was attempting to write and then compare its outline to that of a triangle drawn by plotting lines between the three vertices. The final code is chock full of special cases and workarounds but has been tested against hundreds of thousands of random triangles and seems to be working!
Due to a shortage of memory there is only a single frame buffer, which (naturally) means there is no double-buffering and hence smooth animation becomes a little tricky. When connected to a TV one can take advantage of the vertical blanking period to update the buffer (this is a period below and above the active display where you only need to feed sync signals, not image data, to the TV) and still get decent effects as long as you don't try to do too much. The LCD has no such vertical blanking period and so some of the demos look rather flickery.
I have captured a video of the output of the circuit when running the demo which can be seen above. The horizontal grey lines are a limitation of my video capture card; these lines appear correctly as alternating black and white pixels on a real TV set! You can download the code for this demo from my site along with a PDF of the schematic. As this is a work in progress I'm sure there are plenty of bugs left to squash but I think it's getting there, slowly but surely!