Today I would like to write a little about string-printing (same applies to all raster images).
How are strings drawn by vectrex BIOS?
The vectrex BIOS stores a raster “image” of all characters supported, this can be seen e.g. by using dumpi:
Each char is represented by 7 bytes, each byte repressents one row of the character and each bit position one column. So the “pixel” size of one char is 8*7 (height * width).
If a string is to be printed, the BIOS loads the address of the bitmap, examines each character of the string and uses the char values as a lookup reference into the raster image and outputs in one long line the first row of all characters of the string.
Of each char (in the string) the first byte is read and the bits which are set are output with the “light switched on” and bits which are not set are output with the “light switched off”.
Actually each line of a String output is one long line which changes its “pattern”-byte continually along the way. Lets call this thing a “string-line” for easier reference.
All raster outputs on a vectrex are more or less done exactly that way.
Outputting more than one line
There is virtually no way the above explained can be made more efficient. To output one byte of (raster) data you need one full “shift cycle”. One shift cycle takes 18 (CPU) cylces. You can finish that sooner – than you did not output 8 bits, you can finish that later, but you will not output more bits.
So – exactly 18 cycles is what it takes. Fullstop!
The only way one can change the output of “complete” strings is to change the things which are done in between the output of each string-line.
Take a look at the following image, here I show three different ways what can be done:
a) BIOS routine – the original
This I call “uni directional output”, in short:
- output one string line
- go a little bit down
- go back to the start of the line
- do the above 7 times
b) Moon Lander routines (and some of “thomas”)
This I call “bi directional output”, in short:
- output one string line
- go down a little bit
- while going back output an “inverse string line”
- do above for all 7 lines
c) Alex Herbert/Kristof Tuts (?) routines
This I call “synced output”, in short
- output one string line
- zero the integrators, and wait
- reposition beam to start and move down a little
- do the above 7 times
Pros /Cons
uni directional output
Speed – medium (shown example 10486 cycles for “Hello world this is a wonderfull day”)
vulnerable to vectrex drift, the longer the text the more “italic” it gets
bi directional output
Speed – fast (shown example 6209 cycles for “Hello world this is a wonderfull day”)
vulnerable to vectrex drift, but not as much as “uni”, tends to be a bit more “grizzly”
reports, that it does not work on all vectri (although I have not seen that in real live yet)
synced output
Speed – slow (shown example 12443 cycles for “Hello world this is a wonderfull day”)
not! vulnerable to vectrex drift
Example routines will be included in the next version of Vide.
Regards
Malban
Great explanation. I guess the draw_raster_image routine is equivalent to bi directional output. On the subject of which, draw_raster_image works fine here on hardware, fine in any VIDE config apart from digital.vsv, and fails in ParaJVE. I guess this is to be expected.
The raster routines in Bresenham by Metalvotze use a close copy of the BIOS Print_str routine and as far as I can tell, use uni-directional output. This explains I guess why they work fine on ParaJVE.
Personally I prefer to use your faster draw_raster_image and don’t have a problem breaking ParaJVE compatibility for my production.
Hi,
I know lineart demo uses a bi-directional raster output routine, but the openly available sources were “fixed” so they work on ParaJVE. The originals were fine for the hardware, otherwise these demos would not have been accepted at the demo parties.
The last days (even befor I wrote the “sync” PrintStr routines) I wrote a “sync” raster draw routine (which is also uni-directional). The output is much more stable in relation to drift – but quite a lot slower. It depends on where you want to use the imagery. As a title screen I would prefer the synced ones because of a very clear and drift-free display. If you use raster drawing inside a fast game – you always have to compromise…
Regards
Malban
Ah, that’s very interesting, I hadn’t realised Lineart’s raster routine was bidirectional. I’ve only examined the source for Bresenham, but I’ll go and study Lineart as well. Thanks 🙂
Aha, I see the TILTFIX1 and TILTFIX2 constants and a few extra nops and where they are used; they “jump out” in the source as being added by a different coder (different tab settings). This could give a route to fixing your nice draw_raster_image for ParaJVE, not that ParaJVE compatibilty is necessarily a priority of course 🙂 Still, I’ll investigate further.
Just reporting in on this. Lineart was a bit of a red herring; the “ParaJVE fixed” binaries no longer work on hardware! vecxi of course shows the truth and behaves identically to hardware; I have really come to trust and love vecxi+dissi+tracki! I had been foolishly assuming they had found a solution that worked on both, but of course it couldn’t be, given ParaJVE’s inaccurate timing.
I didn’t realise this until I had reversed their raster format and written a JS converter. It’s quite similar though not identical to your own bidir format. Here is the converter for your reference (if you care to play with their output routines): http://pastebin.com/ESYDQgYu
Their routine is quite sneaky in that it is readily usable as a textwriter too, due to the fact you supply an index string for your raster graphic. I haven’t actually timed their routine against your raster routine though, I’m sticking with yours for my limited raster needs; for which, thanks 🙂
The ‘output a line’ part of this – you’ve done implementations where the line is drawn horizontally from left to right, and from right to left. But would it be possible to modulate _any_ angle of line with the bit patterns for text? – i.e. would it be possible to draw text along an arbitrary slope (as well as with vertical lines to get text at 90 degrees). (Even if it had to be restricted to using an angle that was fixed at compile time, if that helped precompute things like the next row starting position more efficiently.)
That is certainly possible, look e.g. at: 11th of October – The Disc!
or as part of Vectorblade, the spinning wheel:
yep, that looks like it – thanks!