Of the "trivial" texts that the current parser can handle, these are now being inserted in obj_events.
146 lines
3.4 KiB
Python
146 lines
3.4 KiB
Python
"""
|
|
const uint8_t string[] = "foo" "\x0a" "abc";
|
|
"""
|
|
|
|
from itertools import chain
|
|
from parse import parse
|
|
from generate.generate import renderer
|
|
|
|
_control_encode = {
|
|
'text_end': None,
|
|
'text_ram': None,
|
|
'text_start': None,
|
|
'text_decimal': None,
|
|
'text_bcd': None,
|
|
'text' : 0x80,
|
|
'next' : 0x81,
|
|
'line' : 0x82,
|
|
'para' : 0x83,
|
|
'cont' : 0x84,
|
|
'done' : 0x85,
|
|
'prompt' : 0x86,
|
|
'page' : 0x87,
|
|
}
|
|
|
|
_bracketed_encode = {
|
|
'PKMN' : '\\x96',
|
|
'COLON' : '\\xa6',
|
|
# fixme hacks
|
|
'PLAYER': 'PLAYER',
|
|
'RIVAL' : 'RIVAL',
|
|
'TARGET': 'TARGET',
|
|
'USER' : 'USER',
|
|
'SCROLL': 'SCROLL', # _ContTextNoPause
|
|
'_CONT' : '_CONT', # _ContText
|
|
}
|
|
|
|
def encode_bracketed(bracketed):
|
|
# see control.hpp
|
|
assert bracketed in _bracketed_encode, bracketed
|
|
return _bracketed_encode[bracketed]
|
|
|
|
def parse_bracketed(string):
|
|
chars = []
|
|
in_bracket = False
|
|
for c in string:
|
|
if c == '<':
|
|
assert in_bracket is False
|
|
in_bracket = True
|
|
if chars:
|
|
yield ''.join(chars)
|
|
chars = []
|
|
elif c == '>':
|
|
assert in_bracket is True
|
|
in_bracket = False
|
|
yield encode_bracketed(''.join(chars))
|
|
chars = []
|
|
elif ord(c) == 165:
|
|
if chars:
|
|
yield ''.join(chars)
|
|
chars = []
|
|
yield '\\xa5'
|
|
else:
|
|
chars.append(c)
|
|
if chars:
|
|
yield ''.join(chars)
|
|
|
|
def encode_control(control):
|
|
assert control in _control_encode, control
|
|
encode = _control_encode[control]
|
|
if encode is not None:
|
|
return f'\\x{encode:x}'
|
|
else:
|
|
return None
|
|
|
|
def quote(s):
|
|
return f'"{s}"'
|
|
|
|
def generate_literals(text):
|
|
for control__value in text:
|
|
if len(control__value) == 1:
|
|
control, = control__value
|
|
ec = encode_control(control)
|
|
if ec is not None:
|
|
yield ec
|
|
elif len(control__value) == 2:
|
|
control, value = control__value
|
|
ec = encode_control(control)
|
|
if ec is None:
|
|
continue
|
|
yield ec
|
|
yield from parse_bracketed(value)
|
|
else:
|
|
assert False, control__value
|
|
|
|
def generate_text(name, text):
|
|
yield f"const uint8_t {name}[] = ("
|
|
for literal in generate_literals(text):
|
|
yield quote(literal)
|
|
yield ");"
|
|
|
|
def calculate_length(text):
|
|
return sum(
|
|
1 if literal[0:2] == '\\x' else len(literal)
|
|
for literal in generate_literals(text)
|
|
)
|
|
|
|
def texts_header():
|
|
text_list = chain.from_iterable(
|
|
d.items() for d in parse.text_list())
|
|
|
|
for name, text in text_list:
|
|
length = calculate_length(text) + 1
|
|
yield f"extern const uint8_t {name}[{length}];"
|
|
|
|
def includes_header():
|
|
yield "#pragma once"
|
|
yield ""
|
|
yield "#include <cstdint>"
|
|
yield ""
|
|
|
|
def texts_source():
|
|
text_list = chain.from_iterable(
|
|
d.items() for d in parse.text_list())
|
|
|
|
for name, text in text_list:
|
|
yield from generate_text(name, text)
|
|
yield ""
|
|
|
|
def generate_header():
|
|
render, out = renderer()
|
|
render(includes_header());
|
|
render(texts_header())
|
|
return out
|
|
|
|
def includes_source():
|
|
yield "#include <cstdint>"
|
|
yield ""
|
|
yield '#include "text.hpp"'
|
|
yield ""
|
|
|
|
def generate_source():
|
|
render, out = renderer()
|
|
render(includes_source());
|
|
render(texts_source())
|
|
return out
|