Jump to content
IGNORED

[InyBASIC] Displaying a 4 pixel wide font


Recommended Posts

This example contains an assembly language function for creating and displaying a message in a 4 pixel wide font. It only supports upper case, digits and most of the punctuation.

 

Screenshot:-

post-21935-0-09498100-1458603446_thumb.gif

 

Source code (requires IntyBASIC 1.2.5 or above):-

TinyFont.bas

 

Finally, the ROM:-

TinyFont.rom

 

Any problems or questions, let me know.

 

Enjoy!

 

@nanochess: Feel free to include it in the next release of IntyBASIC.

  • Like 8
Link to comment
Share on other sites

This is cool (even if it is limited to about 3 unique lines of data before the Intellivision runs out of GRAM memory space...))

 

Some people have told me that there is too much hex in our examples, ;-)

so I changed the font data to "Bitmap" statements to make it easier to read (and tweak, although with a 4 bit wide font there isn't much room for tweaking...)

 

Sample:

   asm ; Left side font character bitmap data                    
    asm @@LeftFont_bitmaps:

          bitmap	  "        "  
          bitmap	  " #      "  
          bitmap	  "# #     "  
          bitmap	  "# #     "  
          bitmap	  "###     "  
          bitmap	  "# #     "  
          bitmap	  "# #     "  
          bitmap	  "        "  

          bitmap	  "        "  
          bitmap	  "##      "  
          bitmap	  "# #     "  
          bitmap	  "##      "  
          bitmap	  "# #     "  
          bitmap	  "# #     "  
          bitmap	  "##      "  
          bitmap	  "        "  

          bitmap	  "        "  
          bitmap	  " #      "  
          bitmap	  "# #     "  
          bitmap	  "#       "  
          bitmap	  "#       "  
          bitmap	  "# #     "  
          bitmap	  " #      "  
          bitmap	  "        "  

I put the font data into its own file.

 

Here is my hacked version:

tinyfont2.zip

 

 

Catsfolly

 

  • Like 1
Link to comment
Share on other sites

This is cool (even if it is limited to about 3 unique lines of data before the Intellivision runs out of GRAM memory space...))

Not much I can do about that :P

 

Some people have told me that there is too much hex in our examples, ;-)

Personally, I think hex is fine for data emitted from tools. Hopefully, constants.bas has diminished the amount of hex used in IntyBASIC commands.

  • Like 1
Link to comment
Share on other sites

Can you show an example of where that might be useful? I want to understand if I need to course-correct something I have in development at ththe moment.

 

 

I don't think the hex in this example would be an issue, moreso that it's basically not IntyBASIC :P

 

I didn't realize that nanochess had added string literals to DATA, though. Very handy. That'll make for some much easier code reading in places where I'm not cramming 2 bytes per DECLE.

Link to comment
Share on other sites

I don't think the hex in this example would be an issue, moreso that it's basically not IntyBASIC :P

 

True! But a pure IntyBASIC wouldn't render as many font characters per VBLANK :P. The code relies on the fact that there is still time after a wait command to poke data into GRAM.

 

I didn't realize that nanochess had added string literals to DATA, though. Very handy. That'll make for some much easier code reading in places where I'm not cramming 2 bytes per DECLE.

 

Yep! Only in 1.2.5 and beyond. Its a feature I requested. As far as I'm aware AS1600 does not have a directive for packing two bytes per DECLE. It does have STRING but thta only puts one ASCII byte per DECLE. I could probably create a macro so all you'd need is something like asm BSTRING("A string") in your code to use it. You'd need to roll your own print routine, but I expect you have that done already.

Link to comment
Share on other sites

 

True! But a pure IntyBASIC wouldn't render as many font characters per VBLANK :P. The code relies on the fact that there is still time after a wait command to poke data into GRAM.

 

 

Yep! Only in 1.2.5 and beyond. Its a feature I requested. As far as I'm aware AS1600 does not have a directive for packing two bytes per DECLE. It does have STRING but thta only puts one ASCII byte per DECLE. I could probably create a macro so all you'd need is something like asm BSTRING("A string") in your code to use it. You'd need to roll your own print routine, but I expect you have that done already.

 

A macro would be nice, this is a common enough use case. I almost always pack my DECLEs with two bytes at a time and then unpack them when reading.

 

-dZ.

Link to comment
Share on other sites

Can you show an example of where that might be useful? I want to understand if I need to course-correct something I have in development at ththe moment.

 

 

 

A common thing I do is to cram "text" data into DATA statements. Think of a boss-based adventure game, with a little message at the end of every level. And the exact values and lengths won't be correct as I'm doing this on the fly, but hopefully the idea comes across. Instead of my code being littered with a lot of statements like:

PRINT AT 20,"YOU HAVE SLAIN THE DRAGON"

You can write a generic print routine once, and then just call it against various DATA segments:

FOR i = 1 TO boss1_data(0) 'store the length of the message here
  PRINT AT screen_pos+i, boss1_data(i)
NEXT I

boss1_data: DATA 15,$2F,2B,3C,1D,22,11..... 'this will be 15 values (characters) long

<<becomes>>

boss1_data: DATA "YOU HAVE SLAIN THE DRAGON" 

Basically, it just makes things a lot easier to read. IntyBASIC will now internally translate the "YOU HAVE SLAIN THE DRAGON" into the internal hex vales for each of those letters. If you have a LOT of text in your game, this is HUGE.

 

This only works when you're being a bit "wasteful", and using a full DECLE for a single character. But you can actually store 2 characters into a single DECLE, like this:

DATA $2211, $2F23,.... etc

And just print them in pairs:

PRINT AT index,(data(index) AND $FF00)/256
PRINT AT index+1,(data(index) AND $00FF)

Unfortunately there's no way for IntyBASIC to work this out - yet. This is what the guys were talking about with using a macro.

 

DZ/Groovy, feel free to correct me if I'm explaining this wrong (or doing it wrong!). It's very early before work :P

  • Like 1
Link to comment
Share on other sites

But you can actually store 2 characters into a single DECLE

If you limit the characters to:

- Upper case alphabet: A to Z

- Digits: 0 to 9

- Limited punctuation: Space, question mark, exclamation mark and a full stop

 

You get 26+10+4, making a total of 40 characters. Using radix-40 (base 40) you can pack 3 of them as "a + (b * 40) + (c * 1600)", where a, b and c are indexes into your displayable character array and all of the values are in the range 0 to 39. This yields a maximum value of 39+(39*40)+(39*1600)=63999 which fits into a DECLE ;).

Link to comment
Share on other sites

 

A macro would be nice, this is a common enough use case. I almost always pack my DECLEs with two bytes at a time and then unpack them when reading.

 

-dZ.

Joe Z. wrote a nice macro for Space Patrol where the macro takes a string and outputs it with 2 characters per word.

 

Actually it doesn't just pack the ascii characters - it subtracts $20 from each character (which turns the character into a GROM index), then it multiplies each character by 8 (which puts the bits in the right position for backtab), and THEN it packs them two to a word.

 

With this packing scheme, the print routine can be fairly simple.

 

The macro is in S16.mac, and the print code is in P16.asm, in the Space Patrol source code:

 

http://spatula-city.org/~im14u2c/intv/spteaser/

 

 

(the website doesn't seem to be responding at the moment though...)

 

 

Catsfolly

Edited by catsfolly
Link to comment
Share on other sites

Joe Z. wrote a nice macro for Space Patrol where the macro takes a string and outputs it with 2 characters per word.

 

Actually it doesn't just pack the ascii characters - it subtracts $20 from each character (which turns the character into a GROM index), then it multiplies each character by 8 (which puts the bits in the right position for backtab), and THEN it packs them two to a word.

 

With this packing scheme, the print routine can be fairly simple.

 

The macro is in S16.mac, and the print code is in P16.asm, in the Space Patrol source code:

 

http://spatula-city.org/~im14u2c/intv/spteaser/

 

 

(the website doesn't seem to be responding at the moment though...)

 

 

Catsfolly

I use a similar strategy in P-Machinery (actually, inspired by Joe's macros).

 

It adjusts the characters by any bias ($20 by default) and packs them. It supports also C-style strings (null-terminated) as well as Pascal strings (length prefixed), or just plain packing.

 

I'll share the code when I get home.

 

dZ.

Link to comment
Share on other sites

You get 26+10+4, making a total of 40 characters. Using radix-40 (base 40) you can pack 3 of them as "a + (b * 40) + (c * 1600)"

Not only compression, thirty years ago this was known as encryption too, since you pack data in an odd radix that outsiders will have trouble reading without software to decrypt it. I found some online article reprinted from the 80's a few years ago doing some similar packing/encryption in BASIC. I implemented it in (6502) machine code, although I never got to use the routine...

 

This could be perfect for the potential text adventure, where one would like to pack a lot of text into the ROM, at the same time you don't want anyone snooping for clues in the data. Of course it would not be enough for proper encryption meant to protect theft, but that never was intended anyway.

 

Back to the original example, can the display of GRAM cards be moved around on the screen, perhaps 3x20 cards where the top row constantly is replaced by a new row below the others? I imagine the effect would not even be possible to call flickering, but with a such setup one could get 40x12 that might be bearable to read - or not?

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

Back to the original example, can the display of GRAM cards be moved around on the screen, perhaps 3x20 cards where the top row constantly is replaced by a new row below the others? I imagine the effect would not even be possible to call flickering, but with a such setup one could get 40x12 that might be bearable to read - or not?

For very short strings (less than or equal to 14 characters) this would work fine, but it'd flicker. The routine can only manages to program a limited number of characters per VBLANK. At more than 14 characters the next text block down would take 2 frames to render.

  • Like 1
Link to comment
Share on other sites

Ok, thanks.

 

Is that 14 logical characters or 14 GRAM cards? If the former, of course the entire routine would render pointless as you already can display 20x12 with native GROM cards. Even if that is 14 cards to redefine per frame, the benefit would be to get 28x12 resolution at the cost of flicker, and if you would go even higher to obtain a 32x12 or 40x12 resolution, it probably would look like a demo effect more than just flickering text.

Link to comment
Share on other sites

Ok, thanks.

 

Is that 14 logical characters or 14 GRAM cards? If the former, of course the entire routine would render pointless as you already can display 20x12 with native GROM cards. Even if that is 14 cards to redefine per frame, the benefit would be to get 28x12 resolution at the cost of flicker, and if you would go even higher to obtain a 32x12 or 40x12 resolution, it probably would look like a demo effect more than just flickering text.

Its 14 logical characters e.g. 7 GRAM cards. It would take over half a second to render a screens worth of the compacted characters which would result in a very odd display. Its not even flicker at that rate ;).

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...