""" 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 " 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 " yield "" yield '#include "text.hpp"' yield "" def generate_source(): render, out = renderer() render(includes_source()); render(texts_source()) return out