I did a pretty big refactoring of the font system in Mysterious Space 0.8.2.2. I’ve tried to use a couple libraries to handle drawing text for me, but neither has worked out for one reason or another, so I’ve resigned myself to DOING IT MYSELF.
which is fine by me: it’s a fun problem to solve!
previously, I handled drawing text by simply having a “sprite sheet” (right), and a few methods – “WriteText”, “WriteCenteredText”, etc – that checked out this font sheet, and used it to draw the string you wanted.
computers store everything as numbers, so “A” is 65, “B” is 66, etc… “a” is 97, “b” is 98… and everything from question marks to periods to dollar signs all have their own number. so if the game needs to draw the letter “A”, it says “okay, that’s character 65, and each character is 8 pixels wide and 10 pixels tall…” and calculates out where in the sprite sheet the letter “A” appears, and draws that area on the screen.
when I added Advanced Technology, which draws straaaange characters, I just added another sprite sheet, and then updated the code to let me tell it WHICH font to draw; something liket his:
ActiveFont = AlienFont;
WriteText(“this text will appear in strange characters!”);
ActiveFont = NormalFont;
which is messy, but works…
UNTIL: I decide that I need ONE of the fonts to have slightly taller characters (to make room for accent marks over capital letters, as seen in the sprite sheet above…)
why is that problematic? because for the most part, this extra height isn’t needed, so when I ask the game to write out multiple lines of text, I don’t want it to actually space the lines out according to the full height of the font; it should subtract the little extra bit of space on top… but for the alien font, it SHOULDN’T…
so the game is starting to have to do things differently depending on what font it’s drawing with. oof! I need a place to store that kind of information!
and that, of course, is what object oriented programming is for 😛
SO: I’ve now created a Font “class” which has its sprite sheet, but also some extra data, like “how much space between lines?”
I also changed the code a little, in a way that’s hard to describe if you haven’t programmed… but basically, instead of saying “hey, game: draw some text using this font”, I now say “hey font: draw some text yourself”. I’ve moved the responsibility of drawing text to the fonts themselves, since the fonts have all the extra information they need to really do the job. (sure, the game could ask the fonts for that information when drawing, but putting the logic near the data keeps things tidy. did that make sense? I hope that made sense.)
this will also be helpful when I add Cyrillic characters (for Russian), Greek characters, and maybe even Japanese, because: remember how I mentioned that every character has a number? and “A” is 65? well, the first Russian character is 1040! and there are some Japanese characters up in the 20,000s! if you look back at that font sprite sheet I showed before, it only has a couple hundred characters… in order to get up to 20,000, it would have to be ENORMOUSLY tall, but worst of all, most of it would be completely empty! (there are some other language’s characters in there, sure, but also other things, like characters from long-dead languages, mathematical and astrological symbols, some emoji, maybe, and many other things that I don’t need…
what would make more sense, then, is for a single font to have multiple sprite sheets, and for it to know the range of characters that each of its sprite sheets contain. this is going to require even MORE code/logic, and more data, but we’ve already put that all in one place – in the fonts themselves – so it’ll be okay 😛
so! that’s some of the behind-the-scenes involved in the seemingly-simple task of drawing letters on the screen. it’s a problem that’s been solved many times before (ｙ߀üｒ ｃ߀ｍρúｔêｒ ïｓ ԁｏｉлǥ íｔ ｒìǥｈｔ ｎｏɰ!), and I would have liked to have taken advantage of that previous work, but, again, I haven’t been able to find some code that works (especially for Mysterious Space’s retro style), and that’s alright: it IS an interesting problem that, and I’m having fun working through it myself 🙂