From b951fb1113b9574002f5405ebcb4750c077746ff Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Mon, 23 Nov 2015 17:44:06 -0800 Subject: [PATCH] dumped fonts --- .gitignore | 3 + Makefile | 17 +- data/data2.s | 40 +- data/graphics/fonts/font0_japanese.png | Bin 0 -> 3099 bytes data/graphics/fonts/font0_latin.png | Bin 0 -> 3115 bytes data/graphics/fonts/font0_latin_widths.s | 512 ++++++++++++++++++ data/graphics/fonts/font1_japanese.png | Bin 0 -> 3493 bytes data/graphics/fonts/font1_latin.png | Bin 0 -> 3543 bytes data/graphics/fonts/font1_latin_widths.s | 512 ++++++++++++++++++ data/graphics/fonts/font2_japanese.png | Bin 0 -> 4532 bytes data/graphics/fonts/font2_japanese_widths.s | 512 ++++++++++++++++++ data/graphics/fonts/font2_latin.png | Bin 0 -> 3475 bytes data/graphics/fonts/font2_latin_widths.s | 512 ++++++++++++++++++ data/graphics/fonts/font6_braille.png | Bin 0 -> 220 bytes data/graphics/fonts/font7_latin.png | Bin 0 -> 3449 bytes data/graphics/fonts/font7_latin_widths.s | 512 ++++++++++++++++++ data/graphics/fonts/font8_latin.png | Bin 0 -> 3114 bytes data/graphics/fonts/font8_latin_widths.s | 512 ++++++++++++++++++ data/graphics/fonts/font9_japanese.png | Bin 0 -> 2327 bytes .../graphics/fonts/unused_japanese_font_1.png | Bin 0 -> 4480 bytes .../fonts/unused_japanese_font_1_widths.s | 512 ++++++++++++++++++ .../graphics/fonts/unused_japanese_font_2.png | Bin 0 -> 4507 bytes .../fonts/unused_japanese_font_2_widths.s | 512 ++++++++++++++++++ graphics_file_rules.mk | 168 +++--- tools/gbagfx/Makefile | 6 +- tools/gbagfx/convert_png.c | 2 +- tools/gbagfx/font.c | 326 +++++++++++ tools/gbagfx/font.h | 16 + tools/gbagfx/gfx.h | 2 +- tools/gbagfx/global.h | 12 +- tools/gbagfx/main.c | 397 +++++++------- tools/gbagfx/util.c | 42 -- tools/gbagfx/util.h | 4 - 33 files changed, 4774 insertions(+), 357 deletions(-) create mode 100644 data/graphics/fonts/font0_japanese.png create mode 100644 data/graphics/fonts/font0_latin.png create mode 100644 data/graphics/fonts/font0_latin_widths.s create mode 100644 data/graphics/fonts/font1_japanese.png create mode 100644 data/graphics/fonts/font1_latin.png create mode 100644 data/graphics/fonts/font1_latin_widths.s create mode 100644 data/graphics/fonts/font2_japanese.png create mode 100644 data/graphics/fonts/font2_japanese_widths.s create mode 100644 data/graphics/fonts/font2_latin.png create mode 100644 data/graphics/fonts/font2_latin_widths.s create mode 100644 data/graphics/fonts/font6_braille.png create mode 100644 data/graphics/fonts/font7_latin.png create mode 100644 data/graphics/fonts/font7_latin_widths.s create mode 100644 data/graphics/fonts/font8_latin.png create mode 100644 data/graphics/fonts/font8_latin_widths.s create mode 100644 data/graphics/fonts/font9_japanese.png create mode 100644 data/graphics/fonts/unused_japanese_font_1.png create mode 100644 data/graphics/fonts/unused_japanese_font_1_widths.s create mode 100644 data/graphics/fonts/unused_japanese_font_2.png create mode 100644 data/graphics/fonts/unused_japanese_font_2_widths.s create mode 100644 tools/gbagfx/font.c create mode 100644 tools/gbagfx/font.h diff --git a/.gitignore b/.gitignore index cca13a6a3..341c63013 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ *.8bpp *.gbapal *.lz +*.latfont +*.hwjpnfont +*.fwjpnfont pokeas pokeld pokeobjcopy diff --git a/Makefile b/Makefile index c6f0e129a..6c519190e 100644 --- a/Makefile +++ b/Makefile @@ -13,12 +13,7 @@ SHA1 := sha1sum -c .PHONY: rom tools gbagfx scaninc clean compare -gfx := tools/gbagfx/gbagfx -1bpp := @$(gfx) 1bpp -4bpp := @$(gfx) 4bpp -8bpp := @$(gfx) 8bpp -gbapal := @$(gfx) gbapal -lz := @$(gfx) lz +gfx := @tools/gbagfx/gbagfx scaninc := tools/scaninc/scaninc objs = asm/emerald.o @@ -52,11 +47,11 @@ include graphics_file_rules.mk %.png: ; %.pal: ; -%.1bpp: %.png ; $(1bpp) $< -%.4bpp: %.png ; $(4bpp) $< -%.8bpp: %.png ; $(8bpp) $< -%.gbapal: %.pal ; $(gbapal) $< -%.lz: % ; $(lz) $< +%.1bpp: %.png ; $(gfx) $< $@ +%.4bpp: %.png ; $(gfx) $< $@ +%.8bpp: %.png ; $(gfx) $< $@ +%.gbapal: %.pal ; $(gfx) $< $@ +%.lz: % ; $(gfx) $< $@ %.o: %.s $$($$@_deps) $(AS) $(ASFLAGS) -o $@ $< diff --git a/data/data2.s b/data/data2.s index 96ae70665..d048f018a 100644 --- a/data/data2.s +++ b/data/data2.s @@ -124,7 +124,7 @@ gMenuCursorDimensions: ; 82EA608 .byte 0, 0 gFont9JapaneseGlyphs: ; 82EA61C - .incbin "base_emerald.gba", 0x2ea61c, 0x2000 + .incbin "data/graphics/fonts/font9.hwjpnfont" ; Unreferenced data. This also comes before the gpu_bg.s data in Ruby and seems ; to be unreferenced there too. @@ -11093,7 +11093,7 @@ gUnknown_08616124: ; 8616124 .incbin "base_emerald.gba", 0x616124, 0x4 gFont6BrailleGlyphs: ; 8616128 - .incbin "base_emerald.gba", 0x616128, 0x1000 + .incbin "data/graphics/fonts/font6.fwjpnfont" gUnknown_08617128: ; 8617128 .incbin "base_emerald.gba", 0x617128, 0x48 @@ -12032,58 +12032,58 @@ gUnknown_0862B7FC: ; 862B7FC .incbin "base_emerald.gba", 0x62b7fc, 0x2e8 gFont8LatinGlyphs: ; 862BAE4 - .incbin "base_emerald.gba", 0x62bae4, 0x8000 + .incbin "data/graphics/fonts/font8.latfont" gFont8LatinGlyphWidths: ; 8633AE4 - .incbin "base_emerald.gba", 0x633ae4, 0x200 + .include "data/graphics/fonts/font8_latin_widths.s" gFont0LatinGlyphs: ; 8633CE4 - .incbin "base_emerald.gba", 0x633ce4, 0x8000 + .incbin "data/graphics/fonts/font0.latfont" gFont0LatinGlyphWidths: ; 863BCE4 - .incbin "base_emerald.gba", 0x63bce4, 0x200 + .include "data/graphics/fonts/font0_latin_widths.s" gFont7LatinGlyphs: ; 863BEE4 - .incbin "base_emerald.gba", 0x63bee4, 0x8000 + .incbin "data/graphics/fonts/font7.latfont" gFont7LatinGlyphWidths: ; 8643EE4 - .incbin "base_emerald.gba", 0x643ee4, 0x200 + .include "data/graphics/fonts/font7_latin_widths.s" gFont2LatinGlyphs: ; 86440E4 - .incbin "base_emerald.gba", 0x6440e4, 0x8000 + .incbin "data/graphics/fonts/font2.latfont" gFont2LatinGlyphWidths: ; 864C0E4 - .incbin "base_emerald.gba", 0x64c0e4, 0x200 + .include "data/graphics/fonts/font2_latin_widths.s" gFont1LatinGlyphs: ; 864C2E4 - .incbin "base_emerald.gba", 0x64c2e4, 0x8000 + .incbin "data/graphics/fonts/font1.latfont" gFont1LatinGlyphWidths: ; 86542E4 - .incbin "base_emerald.gba", 0x6542e4, 0x200 + .include "data/graphics/fonts/font1_latin_widths.s" gFont0JapaneseGlyphs: ; 86544E4 - .incbin "base_emerald.gba", 0x6544e4, 0x4000 + .incbin "data/graphics/fonts/font0.hwjpnfont" gFont1JapaneseGlyphs: ; 86584E4 - .incbin "base_emerald.gba", 0x6584e4, 0x4000 + .incbin "data/graphics/fonts/font1.hwjpnfont" gUnusedFullwidthJapaneseFontGlyphs: ; 865C4E4 - .incbin "base_emerald.gba", 0x65c4e4, 0x8000 + .incbin "data/graphics/fonts/unused_1.fwjpnfont" gUnusedFullwidthJapaneseFontGlyphWidths: ; 86644E4 - .incbin "base_emerald.gba", 0x6644e4, 0x200 + .include "data/graphics/fonts/unused_japanese_font_1_widths.s" gUnusedFullwidthJapaneseFont2Glyphs: ; 86646E4 - .incbin "base_emerald.gba", 0x6646e4, 0x8000 + .incbin "data/graphics/fonts/unused_2.fwjpnfont" gUnusedFullwidthJapaneseFont2GlyphWidths: ; 866C6E4 - .incbin "base_emerald.gba", 0x66c6e4, 0x200 + .include "data/graphics/fonts/unused_japanese_font_2_widths.s" gFont2JapaneseGlyphs: ; 866C8E4 - .incbin "base_emerald.gba", 0x66c8e4, 0x8000 + .incbin "data/graphics/fonts/font2.fwjpnfont" gFont2JapaneseGlyphWidths: ; 86748E4 - .incbin "base_emerald.gba", 0x6748e4, 0x200 + .include "data/graphics/fonts/font2_japanese_widths.s" gUnknown_08674AE4: ; 8674AE4 .incbin "base_emerald.gba", 0x674ae4, 0x32 diff --git a/data/graphics/fonts/font0_japanese.png b/data/graphics/fonts/font0_japanese.png new file mode 100644 index 0000000000000000000000000000000000000000..35345f399d51e0406ef35fe665e3d199ff800f5f GIT binary patch literal 3099 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 FV1gh6s>=WX literal 0 HcmV?d00001 diff --git a/data/graphics/fonts/font0_latin_widths.s b/data/graphics/fonts/font0_latin_widths.s new file mode 100644 index 000000000..3ea204048 --- /dev/null +++ b/data/graphics/fonts/font0_latin_widths.s @@ -0,0 +1,512 @@ + .byte 3 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 3 + .byte 4 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 3 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 3 + .byte 4 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 6 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 8 + .byte 7 + .byte 8 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 8 + .byte 7 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 5 + .byte 5 + .byte 5 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 4 + .byte 7 + .byte 5 + .byte 5 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 5 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 4 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 5 + .byte 3 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 1 + .byte 2 + .byte 3 + .byte 4 + .byte 5 + .byte 6 + .byte 7 + .byte 5 + .byte 7 + .byte 7 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 8 + .byte 5 + .byte 8 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 8 + .byte 7 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 3 diff --git a/data/graphics/fonts/font1_japanese.png b/data/graphics/fonts/font1_japanese.png new file mode 100644 index 0000000000000000000000000000000000000000..3d2d55541d5f9e56237dc71258998aeef86ef6ae GIT binary patch literal 3493 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 T0P_@m00000NkvXXu0mjfQ~{In literal 0 HcmV?d00001 diff --git a/data/graphics/fonts/font1_latin.png b/data/graphics/fonts/font1_latin.png new file mode 100644 index 0000000000000000000000000000000000000000..ade914858f4810795c03faa18e38f1263f761091 GIT binary patch literal 3543 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 literal 0 HcmV?d00001 diff --git a/data/graphics/fonts/font2_latin_widths.s b/data/graphics/fonts/font2_latin_widths.s new file mode 100644 index 000000000..21a688a62 --- /dev/null +++ b/data/graphics/fonts/font2_latin_widths.s @@ -0,0 +1,512 @@ + .byte 3 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 3 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 8 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 3 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 3 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 8 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 9 + .byte 8 + .byte 8 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 10 + .byte 8 + .byte 5 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 6 + .byte 6 + .byte 6 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 4 + .byte 6 + .byte 8 + .byte 5 + .byte 5 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 6 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 6 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 6 + .byte 3 + .byte 12 + .byte 12 + .byte 12 + .byte 12 + .byte 1 + .byte 2 + .byte 3 + .byte 4 + .byte 5 + .byte 6 + .byte 7 + .byte 8 + .byte 8 + .byte 8 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 5 + .byte 6 + .byte 5 + .byte 6 + .byte 6 + .byte 6 + .byte 3 + .byte 3 + .byte 6 + .byte 6 + .byte 8 + .byte 5 + .byte 9 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 5 + .byte 6 + .byte 6 + .byte 4 + .byte 6 + .byte 5 + .byte 5 + .byte 6 + .byte 5 + .byte 6 + .byte 6 + .byte 6 + .byte 5 + .byte 5 + .byte 5 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 8 + .byte 5 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 12 + .byte 12 + .byte 12 + .byte 12 + .byte 8 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 3 diff --git a/data/graphics/fonts/font6_braille.png b/data/graphics/fonts/font6_braille.png new file mode 100644 index 0000000000000000000000000000000000000000..cb4451bc2c0087bfd5d072668aa8f09ce550cd3c GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K59GIAaWQVb%E|B60@Ck99aN@s(g~g2Eaj?(fW4EPR;`kJS?HNN*9*hIdA%K*&K_V>IM>)QP&pmmKY?cGp{~> z%;N0(!@sVc5wERP{=ZByK|t_L48Pos$omxzE)(L9#P4oUQdl6rt9E|w8SxArA=QrB z*6oJz6XIQ>1dJDRaJ-V!;0e0R+^X~`mP0a-g{72Vgl*-!Mkm2c$1^QT3JLdFYz}$; UYTNNF0_ZFTPgg&ebxsLQ04w%UI{*Lx literal 0 HcmV?d00001 diff --git a/data/graphics/fonts/font7_latin.png b/data/graphics/fonts/font7_latin.png new file mode 100644 index 0000000000000000000000000000000000000000..08652d45f4896aac83a107b00b8086f2740b2964 GIT binary patch literal 3449 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 Ef`EUkkN^Mx literal 0 HcmV?d00001 diff --git a/data/graphics/fonts/font8_latin_widths.s b/data/graphics/fonts/font8_latin_widths.s new file mode 100644 index 000000000..3e5815eda --- /dev/null +++ b/data/graphics/fonts/font8_latin_widths.s @@ -0,0 +1,512 @@ + .byte 3 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 3 + .byte 4 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 3 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 3 + .byte 4 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 8 + .byte 5 + .byte 6 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 0 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 5 + .byte 5 + .byte 3 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 4 + .byte 5 + .byte 4 + .byte 4 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 5 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 4 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 5 + .byte 3 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 1 + .byte 2 + .byte 3 + .byte 4 + .byte 5 + .byte 6 + .byte 7 + .byte 5 + .byte 5 + .byte 5 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 7 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 3 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 3 + .byte 3 + .byte 5 + .byte 5 + .byte 5 + .byte 3 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 4 + .byte 4 + .byte 5 + .byte 4 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 7 + .byte 3 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 5 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 3 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 3 diff --git a/data/graphics/fonts/font9_japanese.png b/data/graphics/fonts/font9_japanese.png new file mode 100644 index 0000000000000000000000000000000000000000..cf5b6166826c41b2aab425190981257c47c6cdb8 GIT binary patch literal 2327 zcmV+y3F!8TP)G%K*vMRw5UzI?S-hXb;o)G)vMO(T^EhIJ zDpnH$kl<(4Q8yID!{I?$WjjAUs8rFOc7iIPfT{rju!lo87;8G(c0)DLqfB&aSL!J1 zelJgYlEZ1=AN_NrY~Rg1tR1Eq(kj+gu3j1vL=29_;wW3#p6@KlH z{!%e$)`|ceFdp2cV*F)E{8M&`0B-WFT_RvcLHE`!5ip}*8Q}^7xW%`|Z15k&Saf3X z=*BOKvFOC&k#LJ*EIP4xpom2=7M)l;dJcTXQJSP8CEc}0uj=iI9{}^0_QvQe2FMdWLsnuhiqjv<}!}0Y!2KbpmoUst8=;u zFa36UiMFgxRGv=x0sS-ziYC$b&WOYb6s?K#r7f9yngbzrSK-M?cyS)LDg^L+JOXwQ zgv69PuvOxjo2W`a9+h~BWYG{pl^DSzmI_xeePNn^7_0FudIC(2Mo%v$euS_IvWXf3`R&bS{9KWrVvjf@ zG7eb#bOcpx;g){fOutzI51_!DJ;3CGbTR8|uhU(IR9iGVlwD_{w3Bh-_Zit(LYDh8cJWv)M=9hZuM zHQk~jMFoof#a$`}_Bg%Sx@UhfH?DP86ywJI0aR|>2DPDu#L=BE)(oB=Bg5X zs^su`yEBzajUF1EDjm=UZt&$>fGXA|fW`~nsoVv9)VN|_`ng~+C^%JtNA%gCRK#Z! ztB0dp`IXPHgb|SVp-PPOcSS4j3RR?D70r-fUKW(_s9FV(t z4vd8+#)twZ%)3m-JwKvxKk&W&9W3R%Nltre+H(#CJWl=j{1Z+Ix!a7@xS#k}391UE z2RUe^BL~P&{96FsptyKA5N$!`3Tab~8fI91>N!AAdRw#Vqhw5w(N-zq9s_Q)F(pvphJk z(c0H<6+I3FLa(@Vpn3BNR6s%E4}Rw#*LV}D3TOuMS0HEb&orQN!*@tW8C7x9p944p zX97S|H$4IrY2x*b09}xj?J#43+b+S%2L~uDT@GkXF_)^Zx8+gI0XiV-1H0f2x*zT( zXA(!>%vbRU7IBE*Ssc*m!+%rYM zqvk0@W{Kv5)DIuP&Z#MiR{o!Wh=77Gpi5LL3qppG3LN*tpo=1bUKCIoDpHk(0*M2W zhhm0^tZl7Rn+>@t27H$P0(kQXny`kE@3qZ+j$1{8+p-Qdd=AJh7QK`V80m2PY%z5i z{KVX0dLSGoiv)aD%UsvGmbFS<&a*N{TMVct83X+LLl*fr$t-4P&A_$BH_Z=x<9}!S z2mgcP+e_&;=Q&aB+PR>Z8|sGKaK6qU%4L3wPuvg1YfJkg)Sd&*AZj!Ul{w(mQjf9R zIRGG%33do?0Z6q>U2_i5xTdlJAMgm!2&i=taDo4SVSorLHR>1*jA6eCJTy(ld&~wn z@Te@Y>x^IvT#LWp@Xm^Nb~T`RXIF0Xf5CF4m=)C35mt_?4OL`}i0h9ylMpg@eGdG? x*bK1YzXYs+2d*Q50vuN#!3xowdErX6@Nd)QP=y#Hc2)oY002ovPDHLkV1iugH|PKW literal 0 HcmV?d00001 diff --git a/data/graphics/fonts/unused_japanese_font_1.png b/data/graphics/fonts/unused_japanese_font_1.png new file mode 100644 index 0000000000000000000000000000000000000000..da4f2beacbc014d2fde8ba6c68df265ff2c94c23 GIT binary patch literal 4480 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 literal 0 HcmV?d00001 diff --git a/data/graphics/fonts/unused_japanese_font_1_widths.s b/data/graphics/fonts/unused_japanese_font_1_widths.s new file mode 100644 index 000000000..6d68f9326 --- /dev/null +++ b/data/graphics/fonts/unused_japanese_font_1_widths.s @@ -0,0 +1,512 @@ + .byte 0 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 9 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 9 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 9 + .byte 8 + .byte 7 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 8 + .byte 5 + .byte 9 + .byte 10 + .byte 10 + .byte 10 + .byte 8 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 8 + .byte 8 + .byte 8 + .byte 10 + .byte 10 + .byte 8 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 5 + .byte 6 + .byte 6 + .byte 2 + .byte 4 + .byte 6 + .byte 3 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 5 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 6 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 + .byte 10 diff --git a/data/graphics/fonts/unused_japanese_font_2.png b/data/graphics/fonts/unused_japanese_font_2.png new file mode 100644 index 0000000000000000000000000000000000000000..7da59c0eb46ce9a0bf4942874d188020023ff85f GIT binary patch literal 4507 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 z z)++Se_kqcuA7?hnsyF59j?gH7^${bG>dD0J2Y{2qT|p&CLa2MaJcf=jPa)G7)bR0i zMOaMMD~gU-*6=4=02N+CO>z#mgyJgAbN^LMwiZ5H`qYPlw>P$_kKqII}PF&|4PhP}MCvR+p*x8mcQy-ZVRZ6yHQdyxvM~!DkY(o-a{PX<0{RMt`iuzM^_ohTGwVz_nsi4K! zKchf~x;Y)AqimqhFULPsMKoX2-G`Q000IRVf7IW}v|Gs<*VyQ)vH1R5O$tZd>3k;O zA{GO*gbvgEE>{>6 z_xb9dmlng!J>qep-)!s@2>jJi>vG?vopdbv4*mqb9d7(7HNku(1d4n&8CY=U2y9Py zpjxBo_9BP2?JiiEf+qzw$STm}9h-N_0y-(?1^Vsek_n%Uv?>5D;&Fg8r}S-;IO-?^ z@}9$Zmo!)SNj@4SpjSN}=h`esU=Yoo*g{pTe$8hF`K5Yn$e5^l86U&N=S2;}B}qR1 zHqHfom{iI6E{@=Gw7*>YbUchasPalette) { SetPngPalette(png_ptr, info_ptr, &image->palette); - if (image->isObject) { + if (image->hasTransparency) { png_byte trans = 0; png_set_tRNS(png_ptr, info_ptr, &trans, 1, 0); } diff --git a/tools/gbagfx/font.c b/tools/gbagfx/font.c new file mode 100644 index 000000000..0dd6fbc3e --- /dev/null +++ b/tools/gbagfx/font.c @@ -0,0 +1,326 @@ +// Copyright (c) 2015 YamaArashi + +#include +#include +#include +#include +#include "global.h" +#include "font.h" +#include "gfx.h" +#include "util.h" + +unsigned char gFontPalette[][3] = { + {0x90, 0xC8, 0xFF}, // bg (saturated blue that contrasts well with the shadow color) + {0x38, 0x38, 0x38}, // fg (dark grey) + {0xD8, 0xD8, 0xD8}, // shadow (light grey) + {0xFF, 0xFF, 0xFF} // box (white) +}; + +static void ConvertFromLatinFont(unsigned char *src, unsigned char *dest, unsigned int numRows) +{ + unsigned int srcPixelsOffset = 0; + + for (unsigned int row = 0; row < numRows; row++) { + for (unsigned int column = 0; column < 16; column++) { + for (unsigned int glyphTile = 0; glyphTile < 4; glyphTile++) { + unsigned int pixelsX = (column * 16) + ((glyphTile & 1) * 8); + + for (unsigned int i = 0; i < 8; i++) { + unsigned int pixelsY = (row * 16) + ((glyphTile >> 1) * 8) + i; + unsigned int destPixelsOffset = (pixelsY * 64) + (pixelsX / 4); + + dest[destPixelsOffset] = src[srcPixelsOffset + 1]; + dest[destPixelsOffset + 1] = src[srcPixelsOffset]; + + srcPixelsOffset += 2; + } + } + } + } +} + +static void ConvertToLatinFont(unsigned char *src, unsigned char *dest, unsigned int numRows) +{ + unsigned int destPixelsOffset = 0; + + for (unsigned int row = 0; row < numRows; row++) { + for (unsigned int column = 0; column < 16; column++) { + for (unsigned int glyphTile = 0; glyphTile < 4; glyphTile++) { + unsigned int pixelsX = (column * 16) + ((glyphTile & 1) * 8); + + for (unsigned int i = 0; i < 8; i++) { + unsigned int pixelsY = (row * 16) + ((glyphTile >> 1) * 8) + i; + unsigned int srcPixelsOffset = (pixelsY * 64) + (pixelsX / 4); + + dest[destPixelsOffset] = src[srcPixelsOffset + 1]; + dest[destPixelsOffset + 1] = src[srcPixelsOffset]; + + destPixelsOffset += 2; + } + } + } + } +} + +static void ConvertFromHalfwidthJapaneseFont(unsigned char *src, unsigned char *dest, unsigned int numRows) +{ + for (unsigned int row = 0; row < numRows; row++) { + for (unsigned int column = 0; column < 16; column++) { + unsigned int glyphIndex = (row * 16) + column; + + for (unsigned int glyphTile = 0; glyphTile < 2; glyphTile++) { + unsigned int pixelsX = column * 8; + unsigned int srcPixelsOffset = 512 * (glyphIndex >> 4) + 16 * (glyphIndex & 0xF) + 256 * glyphTile; + + for (unsigned int i = 0; i < 8; i++) { + unsigned int pixelsY = (row * 16) + (glyphTile * 8) + i; + unsigned int destPixelsOffset = (pixelsY * 32) + (pixelsX / 4); + + dest[destPixelsOffset] = src[srcPixelsOffset + 1]; + dest[destPixelsOffset + 1] = src[srcPixelsOffset]; + + srcPixelsOffset += 2; + } + } + } + } +} + +static void ConvertToHalfwidthJapaneseFont(unsigned char *src, unsigned char *dest, unsigned int numRows) +{ + for (unsigned int row = 0; row < numRows; row++) { + for (unsigned int column = 0; column < 16; column++) { + unsigned int glyphIndex = (row * 16) + column; + + for (unsigned int glyphTile = 0; glyphTile < 2; glyphTile++) { + unsigned int pixelsX = column * 8; + unsigned int destPixelsOffset = 512 * (glyphIndex >> 4) + 16 * (glyphIndex & 0xF) + 256 * glyphTile; + + for (unsigned int i = 0; i < 8; i++) { + unsigned int pixelsY = (row * 16) + (glyphTile * 8) + i; + unsigned int srcPixelsOffset = (pixelsY * 32) + (pixelsX / 4); + + dest[destPixelsOffset] = src[srcPixelsOffset + 1]; + dest[destPixelsOffset + 1] = src[srcPixelsOffset]; + + destPixelsOffset += 2; + } + } + } + } +} + +static void ConvertFromFullwidthJapaneseFont(unsigned char *src, unsigned char *dest, unsigned int numRows) +{ + for (unsigned int row = 0; row < numRows; row++) { + for (unsigned int column = 0; column < 16; column++) { + unsigned int glyphIndex = (row * 16) + column; + + for (unsigned int glyphTile = 0; glyphTile < 4; glyphTile++) { + unsigned int pixelsX = (column * 16) + ((glyphTile & 1) * 8); + unsigned int srcPixelsOffset = 512 * (glyphIndex >> 3) + 32 * (glyphIndex & 7) + 256 * (glyphTile >> 1) + 16 * (glyphTile & 1); + + for (unsigned int i = 0; i < 8; i++) { + unsigned int pixelsY = (row * 16) + ((glyphTile >> 1) * 8) + i; + unsigned int destPixelsOffset = (pixelsY * 64) + (pixelsX / 4); + + dest[destPixelsOffset] = src[srcPixelsOffset + 1]; + dest[destPixelsOffset + 1] = src[srcPixelsOffset]; + + srcPixelsOffset += 2; + } + } + } + } +} + +static void ConvertToFullwidthJapaneseFont(unsigned char *src, unsigned char *dest, unsigned int numRows) +{ + for (unsigned int row = 0; row < numRows; row++) { + for (unsigned int column = 0; column < 16; column++) { + unsigned int glyphIndex = (row * 16) + column; + + for (unsigned int glyphTile = 0; glyphTile < 4; glyphTile++) { + unsigned int pixelsX = (column * 16) + ((glyphTile & 1) * 8); + unsigned int destPixelsOffset = 512 * (glyphIndex >> 3) + 32 * (glyphIndex & 7) + 256 * (glyphTile >> 1) + 16 * (glyphTile & 1); + + for (unsigned int i = 0; i < 8; i++) { + unsigned int pixelsY = (row * 16) + ((glyphTile >> 1) * 8) + i; + unsigned int srcPixelsOffset = (pixelsY * 64) + (pixelsX / 4); + + dest[destPixelsOffset] = src[srcPixelsOffset + 1]; + dest[destPixelsOffset + 1] = src[srcPixelsOffset]; + + destPixelsOffset += 2; + } + } + } + } +} + +static void SetFontPalette(struct Image *image) +{ + image->hasPalette = true; + + image->palette.numColors = 4; + + for (int i = 0; i < image->palette.numColors; i++) { + image->palette.colors[i].red = gFontPalette[i][0]; + image->palette.colors[i].green = gFontPalette[i][1]; + image->palette.colors[i].blue = gFontPalette[i][2]; + } + + image->hasTransparency = false; +} + +void ReadLatinFont(char *path, struct Image *image) +{ + int fileSize; + unsigned char *buffer = ReadWholeFile(path, &fileSize); + + int numGlyphs = fileSize / 64; + + if (numGlyphs % 16 != 0) + FATAL_ERROR("The number of glyphs (%d) is not a multiple of 16.\n", numGlyphs); + + int numRows = numGlyphs / 16; + + image->width = 256; + image->height = numRows * 16; + image->bitDepth = 2; + image->pixels = malloc(fileSize); + + if (image->pixels == NULL) + FATAL_ERROR("Failed to allocate memory for font.\n"); + + ConvertFromLatinFont(buffer, image->pixels, numRows); + + free(buffer); + + SetFontPalette(image); +} + +void WriteLatinFont(char *path, struct Image *image) +{ + if (image->width != 256) + FATAL_ERROR("The width of the font image (%d) is not 256.\n", image->width); + + if (image->height % 16 != 0) + FATAL_ERROR("The height of the font image (%d) is not a multiple of 16.\n", image->height); + + int numRows = image->height / 16; + int bufferSize = numRows * 16 * 64; + unsigned char *buffer = malloc(bufferSize); + + if (buffer == NULL) + FATAL_ERROR("Failed to allocate memory for font.\n"); + + ConvertToLatinFont(image->pixels, buffer, numRows); + + WriteWholeFile(path, buffer, bufferSize); + + free(buffer); +} + +void ReadHalfwidthJapaneseFont(char *path, struct Image *image) +{ + int fileSize; + unsigned char *buffer = ReadWholeFile(path, &fileSize); + + int glyphSize = 32; + + if (fileSize % glyphSize != 0) + FATAL_ERROR("The file size (%d) is not a multiple of %d.\n", fileSize, glyphSize); + + int numGlyphs = fileSize / glyphSize; + + if (numGlyphs % 16 != 0) + FATAL_ERROR("The number of glyphs (%d) is not a multiple of 16.\n", numGlyphs); + + int numRows = numGlyphs / 16; + + image->width = 128; + image->height = numRows * 16; + image->bitDepth = 2; + image->pixels = malloc(fileSize); + + if (image->pixels == NULL) + FATAL_ERROR("Failed to allocate memory for font.\n"); + + ConvertFromHalfwidthJapaneseFont(buffer, image->pixels, numRows); + + free(buffer); + + SetFontPalette(image); +} + +void WriteHalfwidthJapaneseFont(char *path, struct Image *image) +{ + if (image->width != 128) + FATAL_ERROR("The width of the font image (%d) is not 128.\n", image->width); + + if (image->height % 16 != 0) + FATAL_ERROR("The height of the font image (%d) is not a multiple of 16.\n", image->height); + + int numRows = image->height / 16; + int bufferSize = numRows * 16 * 32; + unsigned char *buffer = malloc(bufferSize); + + if (buffer == NULL) + FATAL_ERROR("Failed to allocate memory for font.\n"); + + ConvertToHalfwidthJapaneseFont(image->pixels, buffer, numRows); + + WriteWholeFile(path, buffer, bufferSize); + + free(buffer); +} + +void ReadFullwidthJapaneseFont(char *path, struct Image *image) +{ + int fileSize; + unsigned char *buffer = ReadWholeFile(path, &fileSize); + + int numGlyphs = fileSize / 64; + + if (numGlyphs % 16 != 0) + FATAL_ERROR("The number of glyphs (%d) is not a multiple of 16.\n", numGlyphs); + + int numRows = numGlyphs / 16; + + image->width = 256; + image->height = numRows * 16; + image->bitDepth = 2; + image->pixels = malloc(fileSize); + + if (image->pixels == NULL) + FATAL_ERROR("Failed to allocate memory for font.\n"); + + ConvertFromFullwidthJapaneseFont(buffer, image->pixels, numRows); + + free(buffer); + + SetFontPalette(image); +} + +void WriteFullwidthJapaneseFont(char *path, struct Image *image) +{ + if (image->width != 256) + FATAL_ERROR("The width of the font image (%d) is not 256.\n", image->width); + + if (image->height % 16 != 0) + FATAL_ERROR("The height of the font image (%d) is not a multiple of 16.\n", image->height); + + int numRows = image->height / 16; + int bufferSize = numRows * 16 * 64; + unsigned char *buffer = malloc(bufferSize); + + if (buffer == NULL) + FATAL_ERROR("Failed to allocate memory for font.\n"); + + ConvertToFullwidthJapaneseFont(image->pixels, buffer, numRows); + + WriteWholeFile(path, buffer, bufferSize); + + free(buffer); +} diff --git a/tools/gbagfx/font.h b/tools/gbagfx/font.h new file mode 100644 index 000000000..88c61b638 --- /dev/null +++ b/tools/gbagfx/font.h @@ -0,0 +1,16 @@ +// Copyright (c) 2015 YamaArashi + +#ifndef FONT_H +#define FONT_H + +#include +#include "gfx.h" + +void ReadLatinFont(char *path, struct Image *image); +void WriteLatinFont(char *path, struct Image *image); +void ReadHalfwidthJapaneseFont(char *path, struct Image *image); +void WriteHalfwidthJapaneseFont(char *path, struct Image *image); +void ReadFullwidthJapaneseFont(char *path, struct Image *image); +void WriteFullwidthJapaneseFont(char *path, struct Image *image); + +#endif // FONT_H diff --git a/tools/gbagfx/gfx.h b/tools/gbagfx/gfx.h index 473640d44..ecd436652 100644 --- a/tools/gbagfx/gfx.h +++ b/tools/gbagfx/gfx.h @@ -24,7 +24,7 @@ struct Image { unsigned char *pixels; bool hasPalette; struct Palette palette; - bool isObject; + bool hasTransparency; }; void ReadImage(char *path, int tilesWidth, int bitDepth, struct Image *image, bool invertColors); diff --git a/tools/gbagfx/global.h b/tools/gbagfx/global.h index ce4d6925d..65dd351d2 100644 --- a/tools/gbagfx/global.h +++ b/tools/gbagfx/global.h @@ -14,6 +14,8 @@ do { \ exit(1); \ } while (0) +#define UNUSED + #else #define FATAL_ERROR(format, ...) \ @@ -22,14 +24,8 @@ do { \ exit(1); \ } while (0) +#define UNUSED __attribute__((__unused__)) + #endif // _MSC_VER -#define GBAGFX_MAX_PATH 255 - -#define CHECK_PATH_LENGTH(path) \ -do { \ - if (strlen(path) > GBAGFX_MAX_PATH) \ - FATAL_ERROR("\"%s\" is too long a path.\n", path); \ -} while (0) - #endif // GLOBAL_H diff --git a/tools/gbagfx/main.c b/tools/gbagfx/main.c index 472a87f79..56a1c2c7b 100644 --- a/tools/gbagfx/main.c +++ b/tools/gbagfx/main.c @@ -9,25 +9,18 @@ #include "convert_png.h" #include "jasc_pal.h" #include "lz.h" +#include "font.h" -void ConvertToPng(char *imageFilePath, char *outputFilePath, char *paletteFilePath, bool isObject, int width) +struct CommandHandler +{ + const char *inputFileExtension; + const char *outputFileExtension; + void(*function)(char *inputPath, char *outputPath, int argc, char **argv); +}; + +void ConvertGbaToPng(char *inputPath, char *outputPath, int width, int bitDepth, char *paletteFilePath, bool hasTransparency) { struct Image image; - int bitDepth = 0; - - char *extension = GetFileExtension(imageFilePath); - - if (extension == NULL) - FATAL_ERROR("\"%s\" has no file extension.\n", imageFilePath); - - if (strcmp(extension, "1bpp") == 0) - bitDepth = 1; - else if (strcmp(extension, "4bpp") == 0) - bitDepth = 4; - else if (strcmp(extension, "8bpp") == 0) - bitDepth = 8; - else - FATAL_ERROR("Unexpected file extension \"%s\". Expected \"1bpp\", \"4bpp\", or \"8bpp\".\n", extension); if (paletteFilePath != NULL) { ReadGbaPalette(paletteFilePath, &image.palette); @@ -36,249 +29,249 @@ void ConvertToPng(char *imageFilePath, char *outputFilePath, char *paletteFilePa image.hasPalette = false; } - ReadImage(imageFilePath, width, bitDepth, &image, !image.hasPalette); + ReadImage(inputPath, width, bitDepth, &image, !image.hasPalette); - image.isObject = isObject; + image.hasTransparency = hasTransparency; - if (outputFilePath == NULL) { - ChangeFileExtension(imageFilePath, "png"); - outputFilePath = imageFilePath; - } - - WritePng(outputFilePath, &image); + WritePng(outputPath, &image); FreeImage(&image); } -void ConvertFromPng(char *imageFilePath, char *outputFilePath, int numTiles, int bitDepth) +void ConvertPngToGba(char *inputPath, char *outputPath, int numTiles, int bitDepth) { struct Image image; image.bitDepth = bitDepth; - ExpectFileExtension(imageFilePath, "png"); + ReadPng(inputPath, &image); - ReadPng(imageFilePath, &image); - - if (outputFilePath == NULL) { - char newExtension[5]; - snprintf(newExtension, 5, "%dbpp", bitDepth); - ChangeFileExtension(imageFilePath, newExtension); - outputFilePath = imageFilePath; - } - - WriteImage(outputFilePath, numTiles, bitDepth, &image, !image.hasPalette); + WriteImage(outputPath, numTiles, bitDepth, &image, !image.hasPalette); FreeImage(&image); } -void ConvertToJascPalette(char *paletteFilePath) +void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **argv) +{ + char *inputFileExtension = GetFileExtension(inputPath); + int bitDepth = inputFileExtension[0] - '0'; + char *paletteFilePath; + bool hasPalette = false; + bool hasTransparency = false; + int width = 1; + + for (int i = 3; i < argc; i++) { + char *option = argv[i]; + + if (strcmp(option, "-palette") == 0) { + if (i + 1 >= argc) + FATAL_ERROR("No palette file path following \"-palette\".\n"); + + i++; + + paletteFilePath = argv[i]; + + hasPalette = true; + } else if (strcmp(option, "-object") == 0) { + hasTransparency = true; + } else if (strcmp(option, "-width") == 0) { + if (i + 1 >= argc) + FATAL_ERROR("No width following \"-width\".\n"); + + i++; + + if (!ParseNumber(argv[i], NULL, 10, &width)) + FATAL_ERROR("Failed to parse width.\n"); + + if (width < 1) + FATAL_ERROR("Width must be positive.\n"); + } else { + FATAL_ERROR("Unrecognized option \"%s\".\n", option); + } + } + + ConvertGbaToPng(inputPath, outputPath, width, bitDepth, hasPalette ? paletteFilePath : NULL, hasTransparency); +} + +void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **argv) +{ + char *outputFileExtension = GetFileExtension(outputPath); + int bitDepth = outputFileExtension[0] - '0'; + int numTiles = 0; + + for (int i = 3; i < argc; i++) { + char *option = argv[i]; + + if (strcmp(option, "-num_tiles") == 0) { + if (i + 1 >= argc) + FATAL_ERROR("No number of tiles following \"-num_tiles\".\n"); + + i++; + + if (!ParseNumber(argv[i], NULL, 10, &numTiles)) + FATAL_ERROR("Failed to parse number of tiles.\n"); + + if (numTiles < 1) + FATAL_ERROR("Number of tiles must be positive.\n"); + } else { + FATAL_ERROR("Unrecognized option \"%s\".\n", option); + } + } + + ConvertPngToGba(inputPath, outputPath, numTiles, bitDepth); +} + +void HandleGbaToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) { struct Palette palette; - ExpectFileExtension(paletteFilePath, "gbapal"); - - ReadGbaPalette(paletteFilePath, &palette); - - ChangeFileExtension(paletteFilePath, "pal"); - - WriteJascPalette(paletteFilePath, &palette); + ReadGbaPalette(inputPath, &palette); + WriteJascPalette(outputPath, &palette); } -void ConvertFromJascPalette(char *paletteFilePath) +void HandleJascToGbaPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) { struct Palette palette; - ExpectFileExtension(paletteFilePath, "pal"); - - ReadJascPalette(paletteFilePath, &palette); - - ChangeFileExtension(paletteFilePath, "gbapal"); - - WriteGbaPalette(paletteFilePath, &palette); + ReadJascPalette(inputPath, &palette); + WriteGbaPalette(outputPath, &palette); } -void LZCompressFile(char *path) +void HandleLatinFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) +{ + struct Image image; + + ReadLatinFont(inputPath, &image); + WritePng(outputPath, &image); + + FreeImage(&image); +} + +void HandlePngToLatinFontCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) +{ + struct Image image; + + image.bitDepth = 2; + + ReadPng(inputPath, &image); + WriteLatinFont(outputPath, &image); + + FreeImage(&image); +} + +void HandleHalfwidthJapaneseFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) +{ + struct Image image; + + ReadHalfwidthJapaneseFont(inputPath, &image); + WritePng(outputPath, &image); + + FreeImage(&image); +} + +void HandlePngToHalfwidthJapaneseFontCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) +{ + struct Image image; + + image.bitDepth = 2; + + ReadPng(inputPath, &image); + WriteHalfwidthJapaneseFont(outputPath, &image); + + FreeImage(&image); +} + +void HandleFullwidthJapaneseFontToPngCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) +{ + struct Image image; + + ReadFullwidthJapaneseFont(inputPath, &image); + WritePng(outputPath, &image); + + FreeImage(&image); +} + +void HandlePngToFullwidthJapaneseFontCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) +{ + struct Image image; + + image.bitDepth = 2; + + ReadPng(inputPath, &image); + WriteFullwidthJapaneseFont(outputPath, &image); + + FreeImage(&image); +} + +void HandleLZCompressCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) { int fileSize; - unsigned char *buffer = ReadWholeFile(path, &fileSize); + unsigned char *buffer = ReadWholeFile(inputPath, &fileSize); int compressedSize; unsigned char *compressedData = LZCompress(buffer, fileSize, &compressedSize); free(buffer); - AddFileExtension(path, "lz"); - - WriteWholeFile(path, compressedData, compressedSize); + WriteWholeFile(outputPath, compressedData, compressedSize); free(compressedData); } -void LZDecompressFile(char *path) +void HandleLZDecompressCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) { - ExpectFileExtension(path, "lz"); - int fileSize; - unsigned char *buffer = ReadWholeFile(path, &fileSize); + unsigned char *buffer = ReadWholeFile(inputPath, &fileSize); int uncompressedSize; unsigned char *uncompressedData = LZDecompress(buffer, fileSize, &uncompressedSize); free(buffer); - RemoveFileExtension(path); - - WriteWholeFile(path, uncompressedData, uncompressedSize); + WriteWholeFile(outputPath, uncompressedData, uncompressedSize); free(uncompressedData); } int main(int argc, char **argv) { - if (argc < 2) - FATAL_ERROR("No args.\n"); + if (argc < 3) + FATAL_ERROR("Usage: gbagfx INPUT_PATH OUTPUT_PATH [options...]\n"); - char *command = argv[1]; + struct CommandHandler handlers[] = + { + { "1bpp", "png", HandleGbaToPngCommand }, + { "4bpp", "png", HandleGbaToPngCommand }, + { "8bpp", "png", HandleGbaToPngCommand }, + { "png", "1bpp", HandlePngToGbaCommand }, + { "png", "4bpp", HandlePngToGbaCommand }, + { "png", "8bpp", HandlePngToGbaCommand }, + { "gbapal", "pal", HandleGbaToJascPaletteCommand }, + { "pal", "gbapal", HandleJascToGbaPaletteCommand }, + { "latfont", "png", HandleLatinFontToPngCommand }, + { "png", "latfont", HandlePngToLatinFontCommand }, + { "hwjpnfont", "png", HandleHalfwidthJapaneseFontToPngCommand }, + { "png", "hwjpnfont", HandlePngToHalfwidthJapaneseFontCommand }, + { "fwjpnfont", "png", HandleFullwidthJapaneseFontToPngCommand }, + { "png", "fwjpnfont", HandlePngToFullwidthJapaneseFontCommand }, + { NULL, "lz", HandleLZCompressCommand }, + { "lz", NULL, HandleLZDecompressCommand }, + { NULL, NULL, NULL } + }; - if (strcmp(command, "png") == 0) { - if (argc < 3) - FATAL_ERROR("No image file path arg.\n"); + char *inputPath = argv[1]; + char *outputPath = argv[2]; - CHECK_PATH_LENGTH(argv[2]); + for (int i = 0; handlers[i].function != NULL; i++) { + char *inputFileExtension = GetFileExtension(inputPath); + char *outputFileExtension = GetFileExtension(outputPath); - char imageFilePath[GBAGFX_MAX_PATH + 1]; - strcpy(imageFilePath, argv[2]); - - char *outputFilePath = NULL; - char paletteFilePath[GBAGFX_MAX_PATH + 1]; - bool hasPalette = false; - bool isObject = false; - int width = 1; - - for (int i = 3; i < argc; i++) { - char *option = argv[i]; - - if (strcmp(option, "-output") == 0) { - if (i + 1 >= argc) - FATAL_ERROR("No output file path following \"-output\".\n"); - - i++; - - outputFilePath = argv[i]; - } else if (strcmp(option, "-palette") == 0) { - if (i + 1 >= argc) - FATAL_ERROR("No palette file path following \"-palette\".\n"); - - i++; - - CHECK_PATH_LENGTH(argv[i]); - - strcpy(paletteFilePath, argv[i]); - - hasPalette = true; - } else if (strcmp(option, "-object") == 0) { - isObject = true; - } else if (strcmp(option, "-width") == 0) { - if (i + 1 >= argc) - FATAL_ERROR("No width following \"-width\".\n"); - - i++; - - if (!ParseNumber(argv[i], NULL, 10, &width)) - FATAL_ERROR("Failed to parse width.\n"); - - if (width < 1) - FATAL_ERROR("Width must be positive.\n"); - } else { - FATAL_ERROR("Unrecognized option \"%s\".\n", option); - } + if ((handlers[i].inputFileExtension == NULL || strcmp(handlers[i].inputFileExtension, inputFileExtension) == 0) + && (handlers[i].outputFileExtension == NULL || strcmp(handlers[i].outputFileExtension, outputFileExtension) == 0)) { + handlers[i].function(inputPath, outputPath, argc, argv); + return 0; } - - ConvertToPng(imageFilePath, outputFilePath, hasPalette ? paletteFilePath : NULL, isObject, width); - } else if (strcmp(command, "1bpp") == 0 || strcmp(command, "4bpp") == 0 || strcmp(command, "8bpp") == 0) { - if (argc < 3) - FATAL_ERROR("No image file path arg.\n"); - - CHECK_PATH_LENGTH(argv[2]); - - char imageFilePath[GBAGFX_MAX_PATH + 1]; - strcpy(imageFilePath, argv[2]); - - char *outputFilePath = NULL; - int numTiles = 0; - int bitDepth = command[0] - '0'; - - for (int i = 3; i < argc; i++) { - char *option = argv[i]; - - if (strcmp(option, "-output") == 0) { - if (i + 1 >= argc) - FATAL_ERROR("No output file path following \"-output\".\n"); - - i++; - - outputFilePath = argv[i]; - } else if (strcmp(option, "-num_tiles") == 0) { - if (i + 1 >= argc) - FATAL_ERROR("No number of tiles following \"-num_tiles\".\n"); - - i++; - - if (!ParseNumber(argv[i], NULL, 10, &numTiles)) - FATAL_ERROR("Failed to parse number of tiles.\n"); - - if (numTiles < 1) - FATAL_ERROR("Number of tiles must be positive.\n"); - } else { - FATAL_ERROR("Unrecognized option \"%s\".\n", option); - } - } - - ConvertFromPng(imageFilePath, outputFilePath, numTiles, bitDepth); - } else if (strcmp(command, "pal") == 0) { - if (argc < 3) - FATAL_ERROR("No palette file path arg.\n"); - - CHECK_PATH_LENGTH(argv[2]); - - char paletteFilePath[GBAGFX_MAX_PATH + 1]; - strcpy(paletteFilePath, argv[2]); - - ConvertToJascPalette(paletteFilePath); - } else if (strcmp(command, "gbapal") == 0) { - if (argc < 3) - FATAL_ERROR("No palette file path arg.\n"); - - CHECK_PATH_LENGTH(argv[2]); - - char paletteFilePath[GBAGFX_MAX_PATH + 1]; - strcpy(paletteFilePath, argv[2]); - - ConvertFromJascPalette(paletteFilePath); - } else if (strcmp(command, "lz") == 0) { - if (argc < 3) - FATAL_ERROR("No file path arg.\n"); - - CHECK_PATH_LENGTH(argv[2]); - - char path[GBAGFX_MAX_PATH + 1]; - strcpy(path, argv[2]); - - LZCompressFile(path); - } else if (strcmp(command, "unlz") == 0) { - if (argc < 3) - FATAL_ERROR("No file path arg.\n"); - - CHECK_PATH_LENGTH(argv[2]); - - char path[GBAGFX_MAX_PATH + 1]; - strcpy(path, argv[2]); - - LZDecompressFile(path); - } else { - FATAL_ERROR("Unrecognized command \"%s\".\n", command); } - return 0; + FATAL_ERROR("Don't know how to convert \"%s\" to \"%s\".\n", inputPath, outputPath); } diff --git a/tools/gbagfx/util.c b/tools/gbagfx/util.c index 180b93d9b..5af380184 100644 --- a/tools/gbagfx/util.c +++ b/tools/gbagfx/util.c @@ -58,48 +58,6 @@ char *GetFileExtension(char *path) return extension; } -void ExpectFileExtension(char *path, char *expectedExtension) -{ - char *extension = GetFileExtension(path); - - if (extension == NULL) - FATAL_ERROR("\"%s\" has no file extension.\n", path); - - if (strcmp(extension, expectedExtension) != 0) - FATAL_ERROR("Unexpected file extension \"%s\". Expected \"%s\".\n", extension, expectedExtension); -} - -void AddFileExtension(char *path, char *extension) -{ - int pathLength = strlen(path); - int extensionLength = strlen(extension); - - if (pathLength + 1 + extensionLength > GBAGFX_MAX_PATH) - FATAL_ERROR("\"%s\" is too long a path to add the extension \"%s\".\n", path, extension); - - path[pathLength] = '.'; - memcpy(path + pathLength + 1, extension, extensionLength); - path[pathLength + 1 + extensionLength] = 0; -} - -void RemoveFileExtension(char *path) -{ - char *extension = GetFileExtension(path); - - if (extension == NULL) - FATAL_ERROR("\"%s\" doesn't have a file extension.\n", path); - - extension--; - - *extension = 0; -} - -void ChangeFileExtension(char *path, char *extension) -{ - RemoveFileExtension(path); - AddFileExtension(path, extension); -} - unsigned char *ReadWholeFile(char *path, int *size) { FILE *fp = fopen(path, "rb"); diff --git a/tools/gbagfx/util.h b/tools/gbagfx/util.h index ec81471c0..cb26a31ef 100644 --- a/tools/gbagfx/util.h +++ b/tools/gbagfx/util.h @@ -7,10 +7,6 @@ bool ParseNumber(char *s, char **end, int radix, int *intValue); char *GetFileExtension(char *path); -void ExpectFileExtension(char *path, char *expectedExtension); -void AddFileExtension(char *path, char *extension); -void RemoveFileExtension(char *path); -void ChangeFileExtension(char *path, char *extension); unsigned char *ReadWholeFile(char *path, int *size); void WriteWholeFile(char *path, void *buffer, int bufferSize);