ftsf / nico

a Game Framework in Nim inspired by Pico-8.
MIT License
630 stars 36 forks source link

Need more useful error messages when loading invalid fonts. #75

Open milanbt opened 2 years ago

milanbt commented 2 years ago

In the example project generated by nicoboot, I can't change the default font even though I replaced the .png and .png.dat files.

If I change the index in loadFont and setFont, it compiles and then shows an error:

Error: unhandled exception: No font selected [Exception] Error: execution of an external program failed: '/Users/******/Code/nicotest/nicotest ' stack trace: (most recent call last) /private/var/folders/3d/70xtvzmj457d129np6fy7jjm0000gn/T/nimblecache-903273217/nimscriptapi_463822526.nim(187, 16) /Users/******/Code/nicotest/nicotest.nimble(20, 7) runrTask /opt/homebrew/Cellar/nim/1.6.2/nim/lib/system/nimscript.nim(273, 7) exec /opt/homebrew/Cellar/nim/1.6.2/nim/lib/system/nimscript.nim(273, 7) Error: unhandled exception: FAILED: nim c -r -d:danger -o:nicotest src/main.nim [OSError] Error: Exception raised during nimble script execution

I also tried renaming the file (to fonty.png) with no luck.

My code:

import nico

const orgName = "flkdsa"
const appName = "Working Title"

var buttonDown = false

proc gameInit() =
  loadFont(0, "fonty.png")
  loadSpriteSheet(0, "icon.png", 32, 32)

proc gameUpdate(dt: float32) =
  buttonDown = btn(pcLeft)

proc gameDraw() =
  cls()
  setColor(if buttonDown: 7 else: 3)
  setFont(0)
  printc("welcome to " & appName, screenWidth div 2, screenHeight div 2)

nico.init(orgName, appName)
nico.createWindow(appName, 320, 240, 4, false)
nico.run(gameInit, gameUpdate, gameDraw)

My 'fonty.png.dat': ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890

The png is attached. fonty

ftsf commented 2 years ago

You can use the debug build to get more useful error messages about where the error occured.

It looks like the png does not follow the correct font format, make sure it uses the same layout as the included font.png, specifically, transparent areas with black text with a white border around them.

image

milanbt commented 2 years ago

I tried making the glyph backgrounds transparent, but I guess since they have some gray/transparent pixels it doesn't work and I don't know how to automate making all my semitransparent pixels black to test that.

fonty

Is there any automated way to male a font in this format? I converted mine from a ttf with imagemagick, but it always ends up with some semitransparent anti-aliased edges.

ftsf commented 2 years ago

I draw mine pixel by pixel or edit an existing bitmap font, but maybe there's some software that will do it automatically, I'm not aware of one.

milanbt commented 2 years ago

I draw mine pixel by pixel or edit an existing bitmap font, but maybe there's some software that will do it automatically, I'm not aware of one.

I didn't end up using nico, but I came across this recently: https://raylibtech.itch.io/rtexpacker I think it should be able to load fonts as sprites and pack into a texture.

srozb commented 2 years ago

transparent areas with black text with a white border around them

Could you please elaborate on the specific format required by nico to support fonts? I couldn't find more information in the documentation as API doc contains very short explanation.

I was trying to load png fonts of size 16x16 px (92 chars) and despite the debug information, cannot understand what is the real issue:

proc gameInit() =
  loadFont(0, "fonts/onixgames/black.png")

Output of nimble rund:

readFile , /Users/slawek/src/nim/nimigolf/assets/fonts/onixgames/black.png.dat
readFile , /Users/slawek/src/nim/nimigolf/assets/fonts/onixgames/black.png
loadSurfaceFromPNGNoConvert , /Users/slawek/src/nim/nimigolf/assets/fonts/onixgames/black.png,  size: , 1472, x, 16,  type: , LCT_RGBA
loading RGBA image , /Users/slawek/src/nim/nimigolf/assets/fonts/onixgames/black.png
loading font from RGBA, /Users/slawek/src/nim/nimigolf/assets/fonts/onixgames/black.png, chars, 92
loading font /Users/slawek/src/nim/nimigolf/assets/fonts/onixgames/black.png with 92 chars, width: 1472
loaded font with 68/92 chars
/Users/slawek/src/nim/nimigolf/src/main.nim(26) main
/Users/slawek/.nimble/pkgs/nico-0.4.9/nico.nim(3074) run
/Users/slawek/.nimble/pkgs/nico-0.4.9/nico/backends/sdl2.nim(1866) run
/Users/slawek/src/nim/nimigolf/src/main.nim(9) gameInit
/Users/slawek/.nimble/pkgs/nico-0.4.9/nico.nim(2205) loadFont
/Users/slawek/.nimble/pkgs/nico-0.4.9/nico/backends/sdl2.nim(725) loadSurfaceFromPNGNoConvert
/Users/slawek/.nimble/pkgs/nico-0.4.9/nico.nim(2206) :anonymous
/Users/slawek/.nimble/pkgs/nico-0.4.9/nico.nim(2180) createFontFromSurface
Error: unhandled exception: didn't load all characters from font, loaded: 68 bitmaps of specified chars 92 [Exception]
Error: execution of an external program failed: '/Users/slawek/src/nim/nimigolf/nimigolf '
stack trace: (most recent call last)
/private/var/folders/9x/ytsxtsgs1573mhyn_dy3l82m0000gp/T/nimblecache-3515894660/nimscriptapi_579264793.nim(187, 16)
/Users/slawek/src/nim/nimigolf/nimigolf.nimble(23, 7) rundTask
/usr/local/Cellar/nim/1.6.4/nim/lib/system/nimscript.nim(273, 7) exec
/usr/local/Cellar/nim/1.6.4/nim/lib/system/nimscript.nim(273, 7) Error: unhandled exception: FAILED: nim c -r -d:debug -o:nimigolf src/main.nim [OSError]
     Error: Exception raised during nimble script execution

black

black.png.dat.txt

ftsf commented 2 years ago

This font is not valid because it doesn't have transparent areas surrounded by a white border. It just has black characters surrounded by white, so there's no way for nico to know where one character ends and the next one starts. I suggest comparing it to the included font.png and imitate it.

image

Note: white border to separate characters, transparent around characters (shown here in grey), black characters.

srozb commented 2 years ago

Thank you, that helped.

Please consider to expand the documentation regarding fonts handling.