Proportional Text Print (catchy name TBA)

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Proportional Text Print (catchy name TBA)

Post by arkannoyed »

Been doing some messin' with some text printing. Very much a work in progress, though it seems to work quite well for a morning work! 8-)

Image

Need to optimise the way the characters are stored a bit and add the ability to read a 'plasma' file so that some nice effects can be achieved.

Currently the CHR set is full 96 characters and 1536 bytes

Print routine is a bit basic, but only 70 bytes.
Last edited by arkannoyed on Wed Aug 22, 2018 3:48 pm, edited 1 time in total.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Proportional Text Print (catchy name TBA)

Post by Ast A. Moore »

Looks gorgeous, but the spacing between words needs to be a tad wider.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Proportional Text Print (catchy name TBA)

Post by arkannoyed »

Yes, you're probably right, bit squished.

Hang on....

Any better?

Image
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Proportional Text Print (catchy name TBA)

Post by arkannoyed »

Just in case its not obvious what its doing, I'll explain.

Each character consists of up to 15 frames of 'animation' where its drawn onto the screen pixel by pixel. This means that a text string must be printed 15 times in order to print fully all of the characters within it. As the characters are XOR'ed onto the screen, by actually repeating the process, we can clear the text via the exact same process.

As the printing is proportional, it gives it a nicer look I think, and its actually not that much more tricky to program. Each character occupies 16 bytes, with the first byte being the width in pixels, which is essential for calculating the next X offset. The following 15 bytes consist of an X-offset from the current position and a Y offset. the pixel there is XOR'ed.

An early version used a plasma table to achieve print effects, but that needs work, as it all got a wee bit complicated!

As speed isn't actually paramount, there is probably quite a bit of scope to compress the character set to possibly less than half its current size, with no noticeable slow-down in performance.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Proportional Text Print (catchy name TBA)

Post by Ast A. Moore »

arkannoyed wrote: Wed Aug 22, 2018 3:59 pm Yes, you're probably right, bit squished.

Hang on....

Any better?

Image
Oh, yes. Looks great now!
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Proportional Text Print (catchy name TBA)

Post by Ast A. Moore »

Does it auto-split words and start a new line when it reaches the righthand edge of the screen? I remember it took me a couple of tries to implement that just right in my proportional-width font printing routine. (I haven’t revisited it since, so the code is bit on the ugly side.)
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Proportional Text Print (catchy name TBA)

Post by arkannoyed »

Ast A. Moore wrote: Wed Aug 22, 2018 9:09 pm Does it auto-split words and start a new line when it reaches the righthand edge of the screen? I remember it took me a couple of tries to implement that just right in my proportional-width font printing routine. (I haven’t revisited it since, so the code is bit on the ugly side.)
Currently nothing as advanced or clever as splitting words. It uses 3 bytes at the start of a line, bit no. (80,40,20,10 etc), then screen address, followed by the text. the line ends with a control character to indicate that theres either a new print position, or its the end of printing.

Its not quite the look I was after. I want more control over the rate of printing on individual lines, but thats next in line for development.
User avatar
djnzx48
Manic Miner
Posts: 729
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Proportional Text Print (catchy name TBA)

Post by djnzx48 »

Looks good! Although 1.5K for a font seems quite a lot. Could you somehow use an LFSR to select the pixels that turned on in each character, and so avoid storing them all one by one? The main problem is that it would involve a lot more iterations over each character, unless you somehow got it to only pick from the pixels that actually get drawn, and ignore all the empty space.

Instead of storing an x and y coordinate for each pixel, you could try storing an wrap-around x offset from the previous pixel. Then you could potentially store each pixel using 4 bits or less. Characters like i and j that have 'gaps' in them might pose problems though, and it would slow down as more pixels get drawn. If there aren't many characters using all 15 pixels it might not be too bad.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Proportional Text Print (catchy name TBA)

Post by arkannoyed »

To store the pixels in a linear manor would actually still use 6 bits, which is basically what it uses now for each frame ( 3 for x, 3 for y). If we assume the largest character (M or W) to be 5 bits wide and of a maximum of 7 high (if we take the descenders and taller characters into account), that gives 5x7=35 bits, which encodes in 6 bits. An LFSR would be a nightmare to code for each character, no idea how that might work at the moment, but I agree, it would potentially save a lot as a progression. There are other methods, such as using 3 bits to determine where the next pixel is drawn. This gives the possibility of any of 8 neighbors to set next, but doesn't allow for changing position within the matrix. If the smaller characters could use Elias Gamma or Delta encoding, that might give a slight advantage, but actually when you consider that there aren't many smaller characters, then any local advantage would be wiped out with bigger characters.

In fact, though 15 frames are possible (max) per character, only about 10-12 are used in most cases, sometimes less, so if either indexing or some other direct addressing method were used, then quite a chunk could be saved. A standard CHR set of 8x8 is around 768 bytes, and something around that might be possible. As I said, speed isn't actually the point here, so something a bit slow that has to do a lot of faffing for each character and its associated frame isn't going to spoil the effect much really. Another possibility that actually just popped into my head as I type this is maybe using an index of sequences, as a lot of the characters adopt the same patterns for significant parts of their structure. Therefore, 'a' for instance adopts 10 of the 11 frames that 'd' does, 'i' uses much of 'l' etc. Indexing those sequences could potentially save very large chunks, though would mean a less amorphous look to the progressing of each letter maybe, though that depends entirely upon the actual text being printed.

With this method of referencing sequences, I might achieve something quite useful in size.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Proportional Text Print (catchy name TBA)

Post by arkannoyed »

Oh yes, and by the way, the video (GIF) above is slowed down a touch to better show the animation. It actually runs a little faster than that.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Proportional Text Print (catchy name TBA)

Post by arkannoyed »

djnzx48 wrote: Thu Aug 23, 2018 8:27 am Looks good! Although 1.5K for a font seems quite a lot. Could you somehow use an LFSR to select the pixels that turned on in each character, and so avoid storing them all one by one? The main problem is that it would involve a lot more iterations over each character, unless you somehow got it to only pick from the pixels that actually get drawn, and ignore all the empty space.

Instead of storing an x and y coordinate for each pixel, you could try storing an wrap-around x offset from the previous pixel. Then you could potentially store each pixel using 4 bits or less. Characters like i and j that have 'gaps' in them might pose problems though, and it would slow down as more pixels get drawn. If there aren't many characters using all 15 pixels it might not be too bad.
Mmmmmm....actually, the LSFR idea might not be far off what I had in mind at the start. I hadn't put two and two together. By separating the X and Y components it might be possible to reference a position or offset in a string of X or Y progressions, therefore just needing 2 references for each character. The frame is just then a progression along those strings.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Proportional Text Print (catchy name TBA)

Post by Ast A. Moore »

arkannoyed wrote: Thu Aug 23, 2018 8:26 am
Ast A. Moore wrote: Wed Aug 22, 2018 9:09 pm Does it auto-split words and start a new line when it reaches the righthand edge of the screen? I remember it took me a couple of tries to implement that just right in my proportional-width font printing routine. (I haven’t revisited it since, so the code is bit on the ugly side.)
Currently nothing as advanced or clever as splitting words. It uses 3 bytes at the start of a line, bit no. (80,40,20,10 etc), then screen address, followed by the text. the line ends with a control character to indicate that theres either a new print position, or its the end of printing.
If your font (well, your line, really) is 8 pixels tall, you can use the attribute address for tracking the current print position and then convert it into a bitmap address. It’s quite a bit faster and saves you the trouble of working around the crazy screen layout. It also gives you your carriage return/line feed for “free” (well, to a degree). Finally, if you wish to color in the text as you print it, you also get that automatically.

If your line height is not a multiple of eight, then, yeah, you’re in trouble. ;)
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
arkannoyed
Manic Miner
Posts: 435
Joined: Mon Feb 05, 2018 9:56 am
Location: Northamptonshire

Re: Proportional Text Print (catchy name TBA)

Post by arkannoyed »

I've used the ATTRs address in a few other routines to track the position. Actually with this routine, as long as you stay within a screen third, then just by incrementing E (of the DE screen address) when the global bit marker indicates to do so, gives no issues.

I'm now deep into examining the character code, trying out a few ideas!
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Proportional Text Print (catchy name TBA)

Post by Ast A. Moore »

arkannoyed wrote: Thu Aug 23, 2018 12:50 pm as long as you stay within a screen third, then just by incrementing E (of the DE screen address) when the global bit marker indicates to do so, gives no issues.
Oh, yeah. Long as you’re not crossing a screen third’s boundary, you’re good.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
Seven.FFF
Manic Miner
Posts: 736
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Proportional Text Print (catchy name TBA)

Post by Seven.FFF »

This is great stuff :)
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
djnzx48
Manic Miner
Posts: 729
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Proportional Text Print (catchy name TBA)

Post by djnzx48 »

Does it matter in what order the pixels get drawn? What I meant was not to store the pixels as an offset from the top left of the character, but a relative offset as the number of pixels to the right of the previous pixel. Then for a 5 pixel wide character, 4 bits is enough to go three lines down, and 3 bits will get you to the next line and a few pixels to the right, which should be enough to encode most characters (the problems would likely occur with characters that are both wide and have a lot of vertical space, like '_' or ','). Going downwards might work, except thin characters like '!', '.', or '|' would pose problems.

If the order of drawing is important, then you can get semi-random ordering with a 4-bit LSFR determining which pixel gets drawn each time round the loop, maybe with an offset for each character in the text so that they don't all draw in exactly the same way.

Your method sounds much better though so I'd just disregard this idea and go with the referencing thing instead.
Post Reply