mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 13:33:27 -04:00
Merge pull request #2400 from thibautbus/fix/game3-unicode-braille
Let FireRed braille messages take Unicode braille cells
This commit is contained in:
@@ -236,6 +236,27 @@ local function chars(text)
|
||||
return tostring(text or ""):gmatch("[%z\1-\127\194-\244][\128-\191]*")
|
||||
end
|
||||
|
||||
-- A Unicode braille cell (U+2800-U+283F, dots 1-6 as bits 0-5) is drawn as that
|
||||
-- cell: pokefirered/include/characters.h:282 keeps every dot combination in the
|
||||
-- braille font, numbered dot 1 = 0x01, 4 = 0x02, 2 = 0x04, 5 = 0x08, 3 = 0x10,
|
||||
-- 6 = 0x20. A mod can hand over a European cart's own braille this way, cells
|
||||
-- such as German ä that no Latin character spells included.
|
||||
local CELL_BIT = { 0x01, 0x04, 0x10, 0x02, 0x08, 0x20 }
|
||||
|
||||
local function unicode_cell(ch)
|
||||
local b1, b2, b3 = ch:byte(1, 3)
|
||||
if #ch ~= 3 or b1 ~= 0xE2 or b2 ~= 0xA0 or not b3 or b3 < 0x80 or b3 > 0xBF then
|
||||
return nil
|
||||
end
|
||||
local dots, code = b3 - 0x80, 0
|
||||
for dot = 1, 6 do
|
||||
if dots % 2 == 1 then code = code + CELL_BIT[dot] end
|
||||
dots = math.floor(dots / 2)
|
||||
end
|
||||
return code
|
||||
end
|
||||
Braille.unicodeCell = unicode_cell
|
||||
|
||||
local encodeCache = {}
|
||||
local encodeCacheN = 0
|
||||
|
||||
@@ -252,9 +273,13 @@ function Braille.encode(text)
|
||||
cur = lines[#lines]
|
||||
inNumber = false
|
||||
elseif ch ~= "\r" then
|
||||
local digit = Braille.DIGIT[ch]
|
||||
local code = Braille.CODE[ch] or RECOVERED[ch]
|
||||
if digit then
|
||||
local cell = unicode_cell(ch)
|
||||
local digit = not cell and Braille.DIGIT[ch]
|
||||
local code = cell or Braille.CODE[ch] or RECOVERED[ch]
|
||||
if cell then
|
||||
-- a cell spells its own number sign, as the carts' braille does
|
||||
inNumber = false
|
||||
elseif digit then
|
||||
if not inNumber then
|
||||
inNumber = true
|
||||
cur[#cur + 1] = Braille.NUMBER
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env luajit
|
||||
-- Braille.encode draws a Unicode braille cell (U+2800-U+283F) as that very cell,
|
||||
-- so a mod can hand over a European cart's braille unchanged: the braille font
|
||||
-- holds every dot combination (pokefirered/include/characters.h:282), and some
|
||||
-- carts use cells no Latin character spells (German ä, dots 3-4-5).
|
||||
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
love = require("tests.love_stub")
|
||||
|
||||
local T = require("tests.harness")
|
||||
local check = T.check
|
||||
|
||||
local Braille = require("src.ui.game3.braille")
|
||||
|
||||
local function cell(dots)
|
||||
local bits = 0
|
||||
for d in dots:gmatch("%d") do bits = bits + 2 ^ (tonumber(d) - 1) end
|
||||
return string.char(0xE2, 0xA0, 0x80 + bits)
|
||||
end
|
||||
|
||||
-- The standard braille alphabet, dot numbers per letter.
|
||||
local LETTERS = {
|
||||
A = "1", B = "12", C = "14", D = "145", E = "15", F = "124", G = "1245", H = "125",
|
||||
I = "24", J = "245", K = "13", L = "123", M = "134", N = "1345", O = "135", P = "1234",
|
||||
Q = "12345", R = "1235", S = "234", T = "2345", U = "136", V = "1236", W = "2456",
|
||||
X = "1346", Y = "13456", Z = "1356",
|
||||
}
|
||||
local same = 0
|
||||
for letter, dots in pairs(LETTERS) do
|
||||
if Braille.encode(cell(dots))[1][1] == Braille.encode(letter)[1][1] then same = same + 1 end
|
||||
end
|
||||
check(same == 26, "each Unicode letter cell is the cart's cell for that letter (" .. same .. "/26)")
|
||||
|
||||
local seen, distinct = {}, 0
|
||||
for bits = 0, 63 do
|
||||
local code = Braille.encode(string.char(0xE2, 0xA0, 0x80 + bits))[1][1]
|
||||
if type(code) == "number" and code >= 0 and code < Braille.NUM_CHARS and not seen[code] then
|
||||
seen[code] = true
|
||||
distinct = distinct + 1
|
||||
end
|
||||
end
|
||||
check(distinct == 64, "the 64 Unicode cells reach the 64 cells of the font (" .. distinct .. ")")
|
||||
|
||||
check(Braille.encode(cell("345"))[1][1] == 0x1A, "German ä (dots 3-4-5) is drawn, which no Latin letter reaches")
|
||||
|
||||
local line = Braille.encode(cell("3456") .. cell("1") .. cell("12"))[1]
|
||||
check(#line == 3 and line[1] == Braille.NUMBER,
|
||||
"a cart's own number sign stays one cell, with no second one added")
|
||||
|
||||
check(Braille.width(cell("1") .. cell("12") .. "\n" .. cell("1")) == 2 * Braille.GLYPH_WIDTH,
|
||||
"the width counts cells, not UTF-8 bytes")
|
||||
local latin = Braille.encode("DIG HERE")[1]
|
||||
check(#latin == 8 and latin[1] == 0x0B, "Latin text still spells as before")
|
||||
|
||||
-- pokefirered/src/scrcmd.c:1558 braillemessage: the script's text reaches the
|
||||
-- font through TextIR.toPlain, which must keep the cells a mod's IR carries.
|
||||
local TextIR = require("src.core.game3.scripting.text_ir")
|
||||
local plain = TextIR.toPlain({ { t = "text", s = cell("125") .. cell("1") .. cell("136") .. cell("2345") },
|
||||
{ t = "nl" }, { t = "text", s = cell("345") }, { t = "eos" } }, {})
|
||||
local lines = Braille.encode(plain)
|
||||
check(#lines == 2 and #lines[1] == 4 and lines[2][1] == 0x1A,
|
||||
"a mod's braille message (French HAUT, then German ä) reaches the font cell for cell")
|
||||
|
||||
T.finish("game3_braille_unicode_test")
|
||||
Reference in New Issue
Block a user