Skip to content

Commit

Permalink
Add a whole font and some real text, wahoo
Browse files Browse the repository at this point in the history
  • Loading branch information
eevee committed Jul 8, 2018
1 parent 1b19ac3 commit 5b2fc12
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 42 deletions.
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ BUILD := build
RGBASM := rgbasm
RGBLINK := rgblink
RGBFIX := rgbfix
PYTHON := python

NAME := anise-cheezball-rising
TARGET := $(BUILD)/$(NAME).gbc
Expand All @@ -17,7 +18,17 @@ DEPS := $(foreach src,$(SOURCES),$(patsubst $(SRC)/%,$(BUILD)/%.deps,$(src)))

all: $(TARGET)

$(BUILD)/%.rgbasm.o: $(SRC)/%.rgbasm
# Special intermediate targets

$(BUILD)/font.inc: util/font-to-tiles.py data/font.png
$(PYTHON) util/font-to-tiles.py data/font.png > $(BUILD)/font.inc

# The regular expected stuff
# TODO: i've manually listed font.inc here because otherwise, on first build,
# rgbasm will balk that it doesn't exist, so it'll never create the deps file,
# so make will never know it needs to be built first. this enforces build
# order without supplying the explicit dependency. is there a better fix?
$(BUILD)/%.rgbasm.o: $(SRC)/%.rgbasm | $(BUILD)/font.inc
$(RGBASM) -i $(SRC)/ -i $(BUILD)/ -M $(BUILD)/$*.rgbasm.deps -o $@ $<

$(TARGET): $(OBJECTS)
Expand All @@ -32,4 +43,6 @@ clean:
rm -f $(SYMFILE)

# Include generated dependency files
# TODO: if i remove a dep, make will be unable to recreate it, but these
# lingering files will still say it's necessary. is that fixable?
-include $(DEPS)
Binary file added data/font.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 5 additions & 41 deletions src/main.rgbasm
Original file line number Diff line number Diff line change
Expand Up @@ -527,47 +527,10 @@ include "tilesets/testmap.rgbasm"
include "tilesets/testanise.rgbasm"

SECTION "Font", ROMX
; FONT
font:
; A
db 6
dw `00000000
dw `00000000
dw `01110000
dw `10001000
dw `10001000
dw `10001000
dw `11111000
dw `10001000
dw `10001000
dw `10001000
dw `10001000
dw `00000000
dw `00000000
dw `00000000
dw `00000000
dw `00000000
; B
db 6
dw `00000000
dw `00000000
dw `11110000
dw `10001000
dw `10001000
dw `10001000
dw `11110000
dw `10001000
dw `10001000
dw `10001000
dw `11110000
dw `00000000
dw `00000000
dw `00000000
dw `00000000
dw `00000000

text:
db "ABABAAA", 0
db "Hello, world!", 0
; FONT
font: include "font.inc"

SECTION "Text buffer", WRAM0[$C200]
text_buffer:
Expand Down Expand Up @@ -689,7 +652,7 @@ show_dialogue:
; character address in hl and /then/ put it in de. But I
; already pushed de, so I can use that as scratch space.
push hl
sub a, 65 ; TODO temporary
sub a, 32 ; TODO temporary...?
ld hl, font
ld de, 33 ; 1 width byte + 16 * 2 tiles
; TODO can we speed striding up with long mult?
Expand Down Expand Up @@ -784,6 +747,7 @@ show_dialogue:
; right? wait, no, it comes /before/... well fuck
; TODO actually that might make something weird happen due
; to the inc b above, maybe...?
dec b
add a, b ; a <- new x offset
ld bc, -32 ; move the VRAM pointer back...
add hl, bc ; ...to the start of the tile
Expand Down
77 changes: 77 additions & 0 deletions util/font-to-tiles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""Converts a PNG containing a variable-width font into a source
file for rgbasm.
The image format is similar to the one LÖVE uses: the upper-left
pixel of the whole image is considered to mark the start of a
new letter whenever it appears in the top row. Unlike LÖVE,
that column is also part of the following letter, and is
replaced with color zero. Also, no letter may be wider than 8
pixels (though the renderer includes a 1px gap after every
character).
The palette is ignored and indices are used directly, but
generally color 0 should be the background and color 1 should be
the primary text color.
"""
from pathlib import Path
import sys

import PIL.Image


TILE_SIZE = 8
METATILE_SIZE = 16


def main(font_image_path):
im = PIL.Image.open(font_image_path)

width, height = im.size
if height != 16:
# TODO well, not necessarily! in fact i'd like to cut
# it down to 12. but for now, yes
raise RuntimeError("Font image must be exactly 16 pixels tall")

pixels = im.load()
indicator = pixels[0, 0] # this color starts a new glyph
glyph_starts = [] # x-offsets of where glyphs begin
glyphs = [] # lists of rows of pixels

# Deal with the first row first, so we know where the
# divisions are
for x in range(width):
pixel = pixels[x, 0]
if pixel == indicator:
glyph_starts.append(x)
glyphs.append([[]])
pixel = 0
glyphs[-1][0].append(pixel)
# TODO enforce no more than 8 pixels

# Continue with subsequent rows
for y in range(1, height):
g = -1
for x in range(width):
if g + 1 < len(glyph_starts) and x == glyph_starts[g + 1]:
g += 1
glyphs[g].append([])
pixel = pixels[x, y]
glyphs[g][-1].append(pixel)

# Write it out
for g, glyph in enumerate(glyphs):
if g + 1 < len(glyphs):
glyph_width = glyph_starts[g + 1] - glyph_starts[g]
else:
glyph_width = width - glyph_starts[g]

print(f"; {chr(g + 32)}")
print(f" db {glyph_width}")

for row in glyph:
row = (row + [0] * 8)[:8]
print(' dw `' + ''.join(map(str, row)))


if __name__ == '__main__':
main(*sys.argv[1:])

0 comments on commit 5b2fc12

Please sign in to comment.