Jump to content
IGNORED

New GUI for the Atari 8-bit


flashjazzcat

Recommended Posts

  • 2 weeks later...

MrFish very kindly sent me some newly created fonts, including some very small typefaces similar to those used in SymbOS. Used in the simulated text editor, they give the text renderer a rather brutal work-out:

 

http://www.youtube.com/watch?v=-2IdeZzSjbI

 

Note the OS mouse pointer dancing around seems to be an issue with Altirra's mouse capturing.

 

...and it seems embedded Youtube videos suddenly no longer work. Sorry about that...

Edited by flashjazzcat
  • Like 5
Link to comment
Share on other sites

MrFish very kindly sent me some newly created fonts, including some very small typefaces similar to those used in SymbOS. Used in the simulated text editor, they give the text renderer a rather brutal work-out:

 

"Similar" only in looks, having diminished lower-case height (x-height). The result being that the font you're displaying here is actually smaller than symbOS's font in vertical dimensions, because SymbOS's retains full ascenders. Our icon label font has the same dimensions as SymbOS's system font, and therefore constitutes a more fair comparison. Still waiting to see a video of that. ;) Still... good to see what the limits are when pushing it...

Edited by MrFish
  • Like 1
Link to comment
Share on other sites

Thanks for that Paul. As you say, I just wanted to push the limits; I'll certainly test with the icon font for a fairer comparison. We also have two overlapping text windows, which I haven't yet tried in SymbOS and isn't demonstrated in Prodatron's videos.

 

Nothing like a good test to keep things grounded. ;) Now, let's see... didn't I give you an even smaller font than that?...

Link to comment
Share on other sites

 

Nothing like a good test to keep things grounded. ;) Now, let's see... didn't I give you an even smaller font than that?...

 

In other words, it takes longer to fill the window the smaller the font becomes? That's correct, and the main reason is that the overhead of clipping and rendering many small characters is greater than that of rendering fewer, larger characters. Once the character renderer is "in the loop" with a large glyph, it'll cover a lot of pixels pretty fast. With the even smaller font you sent, the speed takes another hit.

 

Still - I've just run the latest video alongside the SymbOS NotePad Test and the initial window refresh in both systems is quite comparable in speed. Also, when our window is enlarged to cover most of the desktop, the character density using the example font is measurably greater than that in the SymbOS editor. SymbOS's higher frame buffer bit count aside, this is the exact performance level I was aiming for (because - quite simply - SymbOS always struck me as blazingly fast, and remains an excellent benchmark for the A8 system).

 

Further into the video, we witness some delays as the various rectangles of the rearmost window are redrawn. This is one of the (few, and quite tolerable) drawbacks of the rectangle-list approach: that back window's client redraw is being called three times (for example) if the foremost window has split it into three rectangles. That's the bit I did a double-take about when Prodatron first clarified the concept for me. What we rely on is the certainty that it's faster to clip the cell rectangles for every character in the back window three times over (thereby avoiding drawing maybe half of the window content if there's stuff in front of it) than it is to draw every character in every window, regardless of whether they're obscured or not.

 

One way in which the rectangle lists really pull ahead from the previous masking approach is through the removal of said masking logic. Now, even when we DO have to render something, it renders faster because the masks have gone. But for the rectangle list approach to really shine, the clipping logic must be extremely efficient, otherwise we waste nearly as much time discovering we don't need to draw stuff as we used to actually drawing it regardless. That's really the crux of any comparison between the two techniques.

 

So, I can identify two areas which warrant continued attention and optimisation while we progress with other things: clipping, and small character rendering. The clipping (unfortunately) uses signed 16-bit comparisons (so we can draw and clip off-screen; the coordinate system running from -32768 to 32767 on both axes), but it's possible I might see ways of (further) speeding this up. Character rendering, meanwhile, is already optimised to death, and sub-8 pixel wide characters already have their own customised code. Of course there's always room for continued improvement... it just might not become apparent for a while.

 

In any case, thanks to extensive discussion and brainstorming on the topic in the preceding pages - not to mention a well optimised font file format - we surely have an excellent character renderer now, and definitely one of the fastest I've seen.

 

Good idea to reduce font height!

Feels like much more text fits on screen...

 

Wonder how readable it will be on my ancient TV ;)

 

4-bit fonts never seemed terribly comfortable via Y/C to me, but hopefully proportional fonts will be much easier on the eye. And a 6px high monospaced font would give you more than thirty lines of text in a "full screen" editor (with the menus/titles hidden) and fifty columns: great for writing code. :)

 

EDIT: Regarding rectangle-lists, I should add (if it's not obvious) that the visible rectangles comprising a back window are first clipped to the update or "dirty" region (i.e. the area vacated by a moved or closed window in front). Any rectangle not intersecting at all with the update rectangle is discarded, and thus we save bundles of processing there when a window in front is moved only a small distance.

Edited by flashjazzcat
  • Like 2
Link to comment
Share on other sites

Character rendering, meanwhile, is already optimised to death, and sub-8 pixel wide characters already have their own customised code. Of course there's always room for continued improvement... it just might not become apparent for a while.

 

Would it help knowing a font's entire set of glyphs are 1-byte in width? Because this will definitely be the case at times.

Link to comment
Share on other sites

 

Would it help knowing a font's entire set of glyphs are 1-byte in width? Because this will definitely be the case at times.

 

Maybe. Some quite aggressive pre-shifting could perhaps be done in those cases, although it wouldn't really require any extra information in the font file header: the font loader can easily scan the width table and decide if a font's general proportions are suitable for special treatment. As things stand at the moment, there are three distinct "cases" identified when rendering a character:

 

1) The data is 8 or fewer bits wide and does not require shifting across screen byte boundaries (i.e. width plus bit offset equals eight or less)

2) The data is 8 or fewer bits wide and DOES require shifting across screen byte boundaries (i.e. width plus bit offset equals nine or more)

3) The data is more than 8 bits wide and does or does not require shifting across screen byte boundaries (both these sub-conditions are handled in the same loop)

 

The most common rendering scenario involves a mixture of 1) and 2), so the renderer is already optimised for small fonts in that sense. Case 1) is especially efficient, since there's no buffering involved: the data is pulled from the font, shifted using the LUT, and then written to the screen. 2) handles both adjacent bytes in one pass, so is also pretty fast. With the corresponding speed increase when rendering small glyphs, then, the additional load has to be a) the increased rendering iteration, and b) clipping (i.e. pre-rendering) overhead.

 

Doing something drastic like rendering whole scanlines at once would probably require a pointer to the character data for every character in the line. You could then do a (ZP),Y load, using Y as the byte index into the character data, and then blit the data straight to the screen. This would only work for unstyled, plain text (using small fonts), and I haven't really looked into how efficient it would be. It might actually be considerably less efficient, since there's a bias there towards the pre-rendering side, and therefore a lot of work for stuff which might actually be clipped off.

 

It's worth noting, anyway, that the rectangle-list approach very much favours fast front window redraws, which I think is a sensible bias. You only perform one rendering pass on the front window (since it only comprises one rectangle), so you get the full benefit of faster rendering (because the masks have gone), with virtually no additional overhead. User input is buffered as well, so you can continue working while things are rendering in the background.

Link to comment
Share on other sites

Maybe. Some quite aggressive pre-shifting could perhaps be done in those cases, although it wouldn't really require any extra information in the font file header: the font loader can easily scan the width table and decide if a font's general proportions are suitable for special treatment. As things stand at the moment, there are three distinct "cases" identified when rendering a character:

 

1) The data is 8 or fewer bits wide and does not require shifting across screen byte boundaries (i.e. width plus bit offset equals eight or less)

2) The data is 8 or fewer bits wide and DOES require shifting across screen byte boundaries (i.e. width plus bit offset equals nine or more)

3) The data is more than 8 bits wide and does or does not require shifting across screen byte boundaries (both these sub-conditions are handled in the same loop)

 

The most common rendering scenario involves a mixture of 1) and 2), so the renderer is already optimised for small fonts in that sense. Case 1) is especially efficient, since there's no buffering involved: the data is pulled from the font, shifted using the LUT, and then written to the screen. 2) handles both adjacent bytes in one pass, so is also pretty fast. With the corresponding speed increase when rendering small glyphs, then, the additional load has to be a) the increased rendering iteration, and b) clipping (i.e. pre-rendering) overhead.

 

Doing something drastic like rendering whole scanlines at once would probably require a pointer to the character data for every character in the line. You could then do a (ZP),Y load, using Y as the byte index into the character data, and then blit the data straight to the screen. This would only work for unstyled, plain text (using small fonts), and I haven't really looked into how efficient it would be. It might actually be considerably less efficient, since there's a bias there towards the pre-rendering side, and therefore a lot of work for stuff which might actually be clipped off.

 

It's worth noting, anyway, that the rectangle-list approach very much favours fast front window redraws, which I think is a sensible bias. You only perform one rendering pass on the front window (since it only comprises one rectangle), so you get the full benefit of faster rendering (because the masks have gone), with virtually no additional overhead. User input is buffered as well, so you can continue working while things are rendering in the background.

 

The reason I ask is that it seems knowing the width of an entire set of glyphs for a font are 8 bits or fewer would save you from having to test whether it is so or not in each individual case.

Edited by MrFish
Link to comment
Share on other sites

Well, if it becomes necessary to compute the maximum character width, it can be done during the bitmap pointer fixup phase when the font is loaded:

	mva #0 MaxWidth

...
	ldy Char
	lda (CharWidthTab),y
	cmp MaxWidth
	bcc @+
	sta MaxWidth
@
	

No big deal - a few bytes in code which isn't especially time-critical. If it becomes a useful statistic, we can always stick it in the font header.

Edited by flashjazzcat
Link to comment
Share on other sites

Well, if it becomes necessary to compute the maximum character width, it can be done during the bitmap pointer fixup phase when the font is loaded:

	mva #0 MaxWidth

...
	ldy Char
	lda (CharWidthTab),y
	cmp MaxWidth
	bcc @+
	sta MaxWidth
@
	

No big deal - a few bytes in code which isn't especially time-critical. If it becomes a useful statistic, we can always stick it in the font header.

 

It's already being computed in my conversion program. I'm using it for calculating how to space glyphs in a given font for the display screens.

Link to comment
Share on other sites

Thanks to MrFish keeping me honest and grounded, I discovered a nearly overlooked optimisation:

 

 

In the previous demo, the text control which fills the windows with text was working off the window client area boundaries, in as much as it was throwing lines of text at the clipping routine from the top to the bottom of each window's client. However, since we're now rendering sub-rectangles (i.e. the various visible rectangles into which the client rectangle has been split), this approach made no sense at all. Lots of time was being wasted as the clipping routine got bombarded with text which wasn't even going to be displayed.

 

So - the text control is now properly optimised for operation with the rectangle lists, and only calls clipped rendering for those lines which are fully or partially within the sub-rectangle currently being rendered. This appears to have alleviated the pause apparent in the previous test, which was down to the renderer clipping text way outside of the visible areas.

  • Like 13
Link to comment
Share on other sites

Thanks guys. I've gotta admit, it's pretty damned fast now (thanks to all the ideas-people who helped), and I watched the video about six times last night after Bill Kendrick re-posted it via my Atari8 facebook page. MrFish spotted another lag, which encouraged me to implement similar optimisation on the horizontal plane too, so now it's marginally faster than it was in that video. I know this is all taking a bloody age, but I'm really encouraged that the A8 can pull off what's being asked of it, and then some. And this is all with a dummy scheduler IRQ running, on top of the mouse IRQ, and two NMIs... :)

  • Like 4
Link to comment
Share on other sites

FJC,

 

If I haven't said this before, this project is simply beyond amazing! You are a wizard, and I am glad to have the privilege of watching this GUI grow and evolve. Please keep up the great work you are doing. The whole community is going to benefit from your efforts.

I am sure this just sounds like empty accolades, but I sincerely mean every word. It is very exciting to watch such a large project go through the ups and downs that this one has been through. It shows just how under-utilized these 8 bit machines were and how well designed.

 

Russ

  • Like 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...