Mode 3 font hello world

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
Post Reply
User avatar
danboid
Posts: 238
Joined: Sun Jun 14, 2020 12:14 am

Mode 3 font hello world

Post by danboid » Mon Sep 19, 2022 9:34 pm

I spent most of today trying to get my head around using fonts on the Uzebox but I've not been able to pull off a successful 'hello world' yet.

My first observation/comment is whats wrong with Print(), the standard kernel API function to print a string to the screen? In nearly all of the examples I've looked at, everyone has devised their own function to print text to the screen. Does Print() have some major shortcoming(s)? The exception seems to be Loderunner. SetFontTable() seems to have been deprecated, or at least I only get errors when I try to use it.

Lets re-use the Loderunner inc files and create a hello world, re-using its font. Why doesn't this not work, if we replace LodeRunner.c with the following and build/run it:

Code: Select all

#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include <uzebox.h>

#include "data/levelMaps.inc"
#include "data/tiles.inc"
#include "data/font_8x12.pic.inc"

int main() {
  SetTileTable(lode_tileset);
  SetFontTilesIndex(LODE_TILESET_SIZE);
  SetSpriteVisibility(false);
  ClearVram();
  Print(7,5,PSTR("CONGRATULATIONS!"));
}

Could someone fix this or otherwise provide a very minimal/simple example of how to use a font to print a string to a Mode 3 screen please?

Thanks!

User avatar
Artcfox
Posts: 1083
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: Mode 3 font hello world

Post by Artcfox » Mon Sep 19, 2022 10:24 pm

I don't think I've ever used the Print() function ever. Space is usually so tight that I only include the letters and symbols that I use, and most of the time I can get away by displaying text using RAM tiles, which are highly compressed, and can be re-colored on the fly. Here is a post on it, if you scroll down through the posts, you'll see I went through multiple iterations: https://uzebox.org/forums/viewtopic.php ... 28&p=18461

The RAM font approach allows for special effects, which I used gratuitously in Circuit Puzzle, like fading the help text in and out on a pixel by pixel basis: https://github.com/artcfox/circuit/blob ... it.c#L2170

User avatar
danboid
Posts: 238
Joined: Sun Jun 14, 2020 12:14 am

Re: Mode 3 font hello world

Post by danboid » Sun Oct 02, 2022 9:06 pm

Thanks for the link Artcfox!

I cobbled all of the ramfont bits including the data from the font included in laser2 into a fully stripped down c file for IKD but unfortunately I was still unable to print anything to the screen, which shows I still don't have a hang of some of the very basics of UB graphics (or anything) yet.

My latest non-working attempt looks something like this:

Code: Select all

#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <math.h>
#include <stdbool.h>
#include <stdlib.h>
#include <uzebox.h>

const uint8_t myramfont[] PROGMEM = {
  0x1c, 0x36, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x00,
  0x3f, 0x63, 0x63, 0x3f, 0x63, 0x63, 0x3f, 0x00,
  0x3c, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3c, 0x00,
  0x1f, 0x33, 0x63, 0x63, 0x63, 0x33, 0x1f, 0x00,
  0x7f, 0x03, 0x03, 0x3f, 0x03, 0x03, 0x7f, 0x00,
  0x7f, 0x03, 0x03, 0x3f, 0x03, 0x03, 0x03, 0x00,
  0x7c, 0x06, 0x03, 0x73, 0x63, 0x66, 0x7c, 0x00,
  0x63, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x00,
  0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00,
  0x78, 0x30, 0x30, 0x30, 0x30, 0x31, 0x1e, 0x00,
  0x63, 0x33, 0x1b, 0x0f, 0x1f, 0x3b, 0x73, 0x00,
  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7e, 0x00,
  0x63, 0x77, 0x7f, 0x7f, 0x6b, 0x63, 0x63, 0x00,
  0x63, 0x67, 0x6f, 0x7f, 0x7b, 0x73, 0x63, 0x00,
  0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00,
  0x3f, 0x63, 0x63, 0x63, 0x3f, 0x03, 0x03, 0x00,
  0x3e, 0x63, 0x63, 0x63, 0x7b, 0x33, 0x5e, 0x00,
  0x3f, 0x63, 0x63, 0x73, 0x1f, 0x3b, 0x73, 0x00,
  0x1e, 0x33, 0x03, 0x3e, 0x60, 0x63, 0x3e, 0x00,
  0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
  0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00,
  0x63, 0x63, 0x63, 0x77, 0x3e, 0x1c, 0x08, 0x00,
  0x63, 0x63, 0x6b, 0x7f, 0x7f, 0x77, 0x63, 0x00,
  0x63, 0x77, 0x3e, 0x1c, 0x3e, 0x77, 0x63, 0x00,
  0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
  0x7f, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x7f, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x06, 0x00,
  0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
};

void RamFont_Load(const uint8_t* ramfont, uint8_t len, uint8_t fg_color, uint8_t bg_color)
{
  SetUserRamTilesCount(len);
  for (uint8_t tile = 0; tile < len; ++tile) {
    uint8_t* ramTile = GetUserRamTile(tile);
    for (uint8_t row = 0; row < 8; ++row) {
      uint8_t data = (uint8_t)pgm_read_byte(&ramfont[tile * 8 + row]);
      for (uint8_t bit = 0; bit < 8; ++bit)
        if (data & (1 << bit))
          ramTile[row * 8 + bit] = fg_color;
        else
          ramTile[row * 8 + bit] = bg_color;
    }
  }
}

void RamFont_Print(uint8_t x, uint8_t y, const char *message, uint8_t len)
{
  for (uint8_t i = 0; i < len; ++i) {
    int8_t tileno = (int8_t)pgm_read_byte(&message[i]) - 'A';
    if (tileno >= 0)
      SetRamTile(x + i, y, tileno);
  }
}

const char pgm_press_a[] PROGMEM = "PRESS A TO CONTINUE";

int main() {
  ClearVram();
// Calls to DrawMap, or SetTile go here
RamFont_Load(myramfont, sizeof(myramfont) / 8, 0x00, 0xad);
  //WaitVsync(1);
  // Wait for button presses, etc...
  // Optionally call RamFont_Load() again here to change the FG and BG color of text
  RamFont_Print(5, 5, pgm_press_a, sizeof(pgm_press_a));

}
I have tried putting RamFont_Print() in a while loop, using different foreground colours and a few other things with no sign of text yet.

Can I not use these (1 BPP) ramfonts on the same screen as some 8 BPP tiles or sprites?

User avatar
Artcfox
Posts: 1083
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: Mode 3 font hello world

Post by Artcfox » Mon Oct 03, 2022 2:01 am

There is a fontman.zip file attached to this post: https://uzebox.org/forums/viewtopic.php ... 461#p18469 which includes the minimal amount of stuff that you need to get it working, including the Makefile inside the default/ directory.
Create a directory under the uzebox directory called MY_GAMES, and extract that .zip file into it, and then

Code: Select all

cd uzebox/MY_GAMES/fontman/default
and run:

Code: Select all

./scratch
and then run fontman.uze under the emulator.

If you look at the fontman.c, you'll see that you're missing the call to SetTileTable(tileset); and you aren't including a tileset.inc, and your Makefile will need to specify -DMAX_SPRITES and -DRAM_TILES_COUNT as part of the KERNEL_OPTIONS.

Feel free to start with that project, and change it to suit your needs.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest