@GTV reviews the Cosmic Fantasy 1-2 Switch collection by Edia, provides examples of the poor English editing/localization work. It's much worse for CF1. Rated "D" for disappointment, finding that TurboGrafx CF2 is better & while CF1's the real draw, Edia screwed it up...
Main Menu

Variable Width Font?

Started by Lochlan, 09/24/2014, 12:58 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Lochlan

Have any of you tried implementing this in ASM or HuC?  Or for another (perhaps similar) platform?  I googled a bit and I think I understand the basic high-level concepts of variable width fonts, but I have no idea what an implementation would look like on PCE.  I'm looking for any places to start before I go digging.  Thanks!
Quote from: ridgewood_general_store_1 on 08/15/2014, 11:12 AMI'm not sorry about this, as I'm not sorry about ANY attack by the goverrats.

ccovell

"tepples" in the NES Dev world has made VWF code for the NES, I think.  Maybe he's released it under Creative Commons, as he's a fan of that thing.

Try doing a search for his name and VWF.

cabbage

I made a proof-of-concept in HuC (screenshot attached) but didn't bother adding usefulness to it.

If you like, I can add some basic comments and upload the source, but really if you understand the theory behind VWF I'm sure you'll have little trouble writing a routine to suit your needs.

ccovell

A VWF would be far more useful with sans-serif fonts to gain any advantage from it, as in that picture each character is almost the same width anyway.

TurboXray

#4
Quote from: Lochlan on 09/24/2014, 12:58 AMHave any of you tried implementing this in ASM or HuC?  Or for another (perhaps similar) platform?  I googled a bit and I think I understand the basic high-level concepts of variable width fonts, but I have no idea what an implementation would look like on PCE.  I'm looking for any places to start before I go digging.  Thanks!
It's pretty easy, once you get a solid understanding how it works for tile based systems. And the planar base system makes it easy as well.
Here's an example:
starts @ 2:50 )

 You need to know a few things. 1) what the width for each character is. I create a width table for this, but you could technically check it on the fly (although that adds a good additional cpu resource). 2) have all your character left or right edge aligned. Since you're printing left to right, it's easiest to have them left edge aligned. I do this with no space - as in the single pixel column space follows it, but you can do it the other way too. Again, all this is prepped and done before assembling or compiling.

 The next thing you need to do is figure out the widest character of your set. This will determine if you need to write to a buffer of two consecutive tiles or more. If the largest character is 8 or less, then it won't span more than two tiles at ~any~ point. This is because the tile width is 8 pixels on the PCE. I usually keep all of my sets 8 pixels wide or less. It simplifies things.

 You need to do the same for height. Again, if you have any character taller than 8 pixels - you'll need to use another set of tiles below this. And you'll have to factor in line gap space. This can really complicate things if your tiles are slightly larger than 8 pixels tall, but have a line small line gap. This means you''ll need to either keep a line buffer in ram or read back vram to obtain the 'above' row of tiles for overlaying.  If that makes sense.

 The common method is to use only a smaller buffer in ram; 8x16 or 16x16. You usually don't buffer the whole line, because you're sequentially writing characters across the screen - one at a time. No need to constantly re-upload redundant parts of a line if it's already in vram. And like I mentioned earlier, for more complicated 'tall' characters and such - you can always read back the tiles you need to modify and then re-write them. It's slower, but still much faster than constantly reblitting a whole line for a single character updates.

 As for blitting or overlaying the characters, I use an internal counter to keep track of where I am in the buffer. If I start at a position of 0 (the left edge), and blit a 5 pixel wide character, I add 5 to the counter. If the counter is greater than 8 and I'm blitting another character, then I know to only blit it in the second tile of the buffer. I also check to see if the current position + the character to write is less than 16, if so then blit it. Else I need to reorder the buffer; I copy the contents of tile column #2 to tile column #1, and clear tile column #2. I AND off bits higher than $07 of the current position, and I increment the vram pointer to the next tile (not the next two tiles); I'm always writing two tile columns to vram, but I'm only incrementing by one tile on the vram pointer - on overflow.

 There is one other thing you need to take care of; line wrapping. You can either automatically check for this, or handled it via control codes in your script/text. Line wrapping is a problem for VWF, compared to FWF, because you could line wrap in a middle of a character. No good. So either check your line counter against the buffer pointer, along with the width of the current character to be written and clear the whole buffer and increment to the next tile set - or use a control code before the letter to write that does the same thing (clear the buffer, increment the vram tile position).

 Basically, in my example, I'm always writing two columns of tiles to vram. If encounter an 'overflow' past the second tile, I 'shift' everything over to the left and clear the right side and increment the vram pointer by one tile. Since my shift is exactly 8 pixels on each overflow, I just simply copy the right side to the left and clear the left; it's faster than achieves the same effect.

 I believe that's how it's typically done. But if not, it's how I do it. There are few details you need to take care of, but they depend on how you setup the text box/screen. But either way, you'll need a chunk of vram to act as a pseudo bitmap. And you'll have to clear this as well for new text strings or calls or similar, or do tilemap alterations if you plan to 'scroll' the text.

 If you want more complex features than that (like X/Y positioning at pixel resolution VS segmented buffer aligned resolution), then good luck with that or stick with FWF routine ;)

Lochlan

#5
Thank you to everyone for your replies, and especially Bonknuts!  This is great information, time to hit my editor hard!

Quote from: cabbage link=msg=372920 date=1411571t584If you like, I can add some basic comments and upload the source
Please do!  Thanks!
Quote from: ridgewood_general_store_1 on 08/15/2014, 11:12 AMI'm not sorry about this, as I'm not sorry about ANY attack by the goverrats.