Currently it is a Free Pascal library targeted at driving Waveshare's small e-Paper displays for Raspberry Pi. The above sample displays (from the included test program) demonstrate that you can utilize multiple overlapping display windows (if you want them), clipping to arbitrary shapes (ditto), multiple font styles, sizes, and rotation, full justification of text, large font sizes, a variety of geometric shapes, and bitmap scaling and orientation.
Clunkdraw tarball: clunkdraw.tgz
The 1984 introduction of the 68000-based Macintosh electrified the entire microcomputer industry, this company included. Proof that a modestly priced 16-bit system using a high level language (like C) was not only at least as powerful as the Z-80 and supported a much larger flat address space, dramatically easing programming, but was capable of supporting nearly any customer's written language using a graphics-only hardware platform, and was even capable of supporting a paradigm shift to a GUI environment.
(Apple's high list prices did not confuse the engineers at the Small Company, they were well aware of the very modest incremental component cost over a Z-80 solution. While Intel's extant 8086 CPU family would also support more memory than a Z-80, the Company was already highly experienced with the memory bank switching and code segmentation necessary to get around the Z80's 64KB limit, and had absolutely zero interest in jumping 'forward' to a 'solution' that still required all the same kind of software machinations in order to avoid the very same 64KB limit. Not Good Enough, and thank you for playing, Intel. Other reasonable candidates were offered by Zilog [Z8000, still with a marked 64KB odor] and National Semiconductor [16032, slow and buggy], but Motorola's offering was the most mature, and support software [OS, C compiler] was readily available, as were second sources of parts through Hitachi. Intel's own 386, their first product to actually compete effectively with the 68000, was just becoming a potential choice at this time, but it was new, expensive, and single-sourced, all of which removed it from consideration.)
The subsequent releases of comparable low-cost Atari and Amiga systems hammered home the proof, and commercial releases of Unix-based systems using the same 68000 processor family showed just how capable these systems could be. All of a sudden the Company had a clear direction in which to go, one that would be a significant improvement over the Z-80 product line, both in customer perception and in ease of development.
However, the first 68010-based next-generation systems the Company developed suffered from a lack of vision on the part of management. While the hardware was very good, as was the DNIX-based system software and the C compiler, the application layer software was very pedestrian, and was based around a VT220 non-graphics 24×80 terminal model that was barely even capable of supporting European languages. (It didn't, but could have easily enough.) No Arabic, no Hangul, and no graphics.
A major problem was that while everybody involved could see the improved capability of the new product line's hardware base, they had essentially all spent that same performance dollar, resulting in severe under-performance in the final result. Crippling underperformance, in fact. They had forgotten that the 68010 'advantage' had already been spent: on using C instead of assembly language. The 68010 had only twice the clock rate of the Z-80, and twice the bus width. Yes, it supported a lot more memory directly and thus eliminated bank-switching considerations, and the CPU's more and larger registers cut down on the data shuffling that generally plagued 8-bit processors, but when using C it wasn't really that much faster than the Z-80 had been at running custom application code. And, the graphics-only video hardware of the new platform was decidedly more sluggish than the more expensive (but less flexible) dedicated-language video hardware of the Z-80 platforms, so even if there had been a performance surplus it was gone already.
(We're getting there, be patient!)
The prototypes were slow. Orders (yes, more than one) of magnitude too slow. It was common during development to push some menu keys and then go to lunch. Once you came back it might be ready to look at to see if it had done the right thing, but lunchtime wasn't always long enough. The best engineers in the company were thrown at the problem, and told to 'optimize' it. They tried, and made some headway, but the starting point was so bad... The selected architecture was simply not practical on the platforms of the day.
The language vendor, when contacted, said "Don't do that, that's not what that query language is for, why aren't you accessing the database using the conventional API?" High-end engineering workstations, many times more expensive than any customer would consider purchasing for their bank tellers, underperformed by at least one order of magnitude when running the new code, even when optimized. The Company's own engineers unanimously said "this is bad and can't be fixed, we have to do something else". This all fell upon deaf ears.
Management hired performance consultants to show the Company's engineers the errors of their ways. The consultants tested the new platform, its hardware and system software, and ranked it higher than anything else in its class they had ever seen. Their report basically said: "Listen to your people, they're very good." No matter, management had somehow hitched its wagon to this particular 'solution', and that was that. The deaf ears became hostile ears: The engineers were told that anybody who persisted in nay-saying had better just shut up and fix the problem, or else seek employment elsewhere.
Of course, it was not just that management had chosen the wrong software architecture for the new product, if you don't make an occasional mistake you're not trying hard enough. The sin was that they were completely unwilling to admit that it had been a mistake, and do something else to fix it while it was still possible to do so. The engineers could not solve the architectural problem, and the managers would not budge on the architecture. The Company's entire future was tied to this one decision; the managers were betting the farm, but it wasn't actually their farm to bet. And the months, eventually years, rolled by...
To recap: the new hardware and system software was best-in-class, and the system had enough memory and performance to rapidly deploy new procedural applications written in C. But all that was available to the application for user I/O was a fairly sluggish VT-220 subset terminal emulation. This was no better than what the old Z-80 systems could offer, and in fact was worse because it was really quite sluggish in comparison. A Z-80 could drive, using assembly language, a memory-mapped hardware ASCII video subsystem extremely fast. Video responsiveness of all the old systems was unsurpassed in the industry. The new video hardware had met its design targets of supporting the written language of any customer, and supporting facsimile (signatures, checks, etc.) graphics, all at a modest cost, but there was no system or application software to support this, only the terminal emulator, and the innate performance of the display hardware was decidedly marginal as it required system software to do all the character generation rather than using dedicated hardware.
We needed something that looked better, a lot better, to draw attention away from the fact that applications on the new platform felt noticeably slower than on the old. We needed something that could better support languages, and facsimile graphics, than the terminal emulation or the old products. Emphasis on what you've gained compared to the old, not on what you've lost.
The X Window System existed by then, but all known implementations themselves consumed memory in excess of the total available on the target system, leaving none for the application or the operating system, and only had been seen working on much faster hardware than the target system, so it was of no real interest or use.
(And we're here, finally.)
The alternative product was demonstrable (to customers) within three months, and was a roaring success. (Did we mention that the engineering staff really was quite good?) Some heads did end up rolling regarding the database debacle, as one might expect. Unfortunately the Empress database itself also got caught up in the purge, although it was not at fault and was itself a good performer. We'd paid a million dollars for it and its M-Builder query prototyping language that we'd mis-applied as an application environment, and we ended up throwing it all away. We eventually wrote our own application-specific database, but we'd probably have been better served by using the one we'd already bought. But, feelings were running pretty high at that point...
Eventually Clunkdraw gained a network-independent client/server layer, vaguely similar to what X Windows offers, which dramatically improved what could be done with the system, especially in training, supervisory, and remote debugging roles. But the imaging model remained that of Quickdraw. We also ported Clunkdraw, in C and assembler, to the TI 34010 graphics CPU for use in our later color products. At some point gateway programs to both Windows 3.1 and Macintosh systems were created, allowing them to run our financial applications too. (The translation from Clunkdraw to true Quickdraw was particularly easy, as you can imagine, but the network connectivity was much more difficult, as we did not use TCP/IP but rather an Ethernet form of X.25 networking, and the target Macs didn't even use Ethernet.) Eventually there were many man-years invested in this code base, and it was generally highly satisfactory within its market niche.
I eventually found myself again working for the same man that had founded the Small Company. I was looking at using a small monochrome e-Paper display, because of its unequalled strengths in the ambient lighting department. Unfortunately the demo library that came with the display kind of sucked, and I found myself waxing nostalgic for the simplicity, capability, and familiarity of Clunkdraw. The e-Paper display did not integrate into the host Raspberry Pi's GUI system, you are intended to drive it as a pure peripheral, using an I/O library of your own.
And then the light went on: Why not resurrect Clunkdraw? At least partially? The environment I needed was Pascal, but Quickdraw itself was clearly very happy in Pascal, since it started out there, and porting from basic C to basic Pascal is a near-trivial mechanical exercise. The RPi is very fast, avoiding assembly language probably isn't a hardship now. And I only needed a couple of calls... all the familiar old arguments. And so the die was thrown. All I needed to do was a mechanical translation of C to Pascal for the few parts I needed, and to write some naive pixel-plotting code to replace the elaborate optimized assembly language of original Clunkdraw, and I'm good. It looked like only a few days would be required for what I needed in the new product, and the results would be infinitely better-looking and more familiar than what I'd get continuing on with the e-Paper demo library...
It was so much fun and worked so well that I got carried away, and ended up porting everything in the monochrome imaging layer over the course of a month. (Not the networking layer nor the color code, which were themselves substantial and not a good fit to the new environment.) The new drawing code itself is very naive, and an extremely poor performer when compared to original Clunkdraw. But, the RPi is so fast and our needs were so modest that it simply doesn't matter here.
No, it's not C, and it's certainly not C++. It's a near-trivial exercise to port it to C, though. It is probably a nearly trivial exercise to port it to any procedural language environment.
.alibrary (remember this predated the advent of shared object libraries, and even predated Linux) so that a client application needn't contain any code it wasn't using. Pascal does not really support this model. Rather, it prefers larger-grained units. Clunkdraw in Pascal has been split into nine units, mostly just to make it easier to work on.
Also, original Clunkdraw stored all its fonts on disk, in part because the sum of all its fonts occupied a substantial portion of a client's address space, but this definitely introduced an unwelcome external dependency. The RPi supports much larger address spaces, so this implementation puts all but one of the fonts in an optional unit, a large one, but one which can be avoided if you don't need the fonts. Clunkdraw in Pascal relies on nothing outside of itself, and adds no additional dependencies at either compile or run time.
Because it doesn't look like Pascal supports the same concept as C's function pointers, allowing late binding, the number of units is relatively small, and things are packaged together. Unit X refers to Y, which in turn refers to Z, and you end up including a bunch of the units as often as not. This could maybe be done better by an expert, which I am not. But, this is good enough for now.
There are nine units, plus test programs and etc.:
The size of this library is no problem at all for a Raspberry Pi, or something similar, but it's far too big for use on an Arduino. A fine-grained
File Contains 105,568 16,001 epaper.pas E-Paper SPI access 155,901 58,776 clunkdraw.pas Lines; Rectangles; Region clipping, drawing; Support 5,342,618 1,087,081 clunkfonts.pas All but one font 30,367 8,724 clunkpoly.pas Polygons 38,358 11,940 clunkregions.pas Region manipulation 33,800 7,994 clunkrounds.pas Ovals; Arcs and Wedges; Rounded Rectangles 6,805 2,305 clunksave.pas MacPaint and PBM file saving (for screen shots) 70,359 25,802 clunktext.pas Text drawing; Default font 91,510 21,396 clunkwinds.pas Overlapping windows
.aC library of Clunkdraw might be useful on an Arduino, if you were not using very many of the Clunkdraw features.
Return to Site Home