#! /usr/bin/python # char_compiler.py # # Copyright (c) 2002, 2003 Bruce Kroeze # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. """ char_compiler Parses "raw" files showing how to draw 15 seg characters in a rude ascii format, generating a lookup table with 15 bit binary values for the characters The "raw" file is formatted like so: 8 --- [ ] --- [ ] --- === using a map of the segments like this: a ------- [\ i: /] f[ \ : / ]b [ n\:/j ] g--- ---h [ m/:\k ] e[ / : \ ]c [/ l: \] ------- o d flattening tho segments into binary: abcdefghijklmno the example above would be: 0111111110000000 """ import string, time, sys # INCLUDE_LH = 1 # make byte-size defs too INCLUDE_LH = 0 # full ascii visible - starts at 32 ASCII = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" SEGS = {} CHARNAMES = {"~" : "TILDE", "!" : "EXCLAMATION", "$" : "DOLLAR", "%" : "PERCENT", "^" : "CARAT", "&" : "AMPERSAND", "*" : "ASTERISK", "(" : "L_PAREN", ")" : "R_PAREN", "[" : "L_BRACKET", "]" : "R_BRACKET", "{" : "L_BRACE", "}" : "R_BRACE", "+" : "PLUS", "-" : "MINUS", "=" : "EQUAL", "/" : "SLASH", "\\" : "BACKSLASH", "|" : "PIPE", '"' : "QUOTE", "'" : "SINGLEQUOTE", "`" : "TIC", "<" : "LESS", ">" : "GREATER", "_" : "UNDERSCORE", "?" : "QUESTION", "," : "COMMA", "." : "PERIOD", " " : "SPACE", "#" : "ALL", ":" : "UPARROW", ";" : "DOWNARROW", "@" : "AT"} def get_label(ch): """Get the DEFINE label for the character.""" if CHARNAMES.has_key(ch): label = CHARNAMES[ch] else: label = ch return label def binary(val, digits): """Simple little binary converter""" b = "" while digits > 0: if (val & (1 << (digits - 1))): b += "1" else: b += "0" digits -= 1 return b def get_segs(): """Lazy load segment-to-binary values""" if SEGS == {}: letters = "ABCDEFGHIJKLMNO" for ix in range(0, 15): SEGS[letters[ix]] = 1 << ix return SEGS def parse_seg(raw): """Convert a shape definition to a value.""" for ix in range(0,len(raw)-1): llen = len(raw[ix]) if llen < 5: raw[ix] = raw[ix] + (" " * (5-llen)) while len(raw) < 5: raw.append(" ") L1 = raw[0] L2 = raw[1] L3 = raw[2] L4 = raw[3] L5 = raw[4] segs = get_segs() val = 0 if "-" in L1: val += segs["A"] if "[" in L2: val += segs["F"] if "\\" in L2: val += segs["N"] if "|" in L2: val += segs["I"] if "/" in L2: val += segs["J"] if "]" in L2: val += segs["B"] if "-" in L3[0:2]: val += segs["G"] if "-" in L3[3:]: val += segs["H"] if "[" in L4: val += segs["E"] if "/" in L4: val += segs["M"] if "|" in L4: val += segs["L"] if "\\" in L4: val += segs["K"] if "]" in L4: val += segs["C"] if "-" in L5: val += segs["D"] if "." in L5: val += segs["O"] return val def load_chardefs(fname): """Load the shape file named, returning the raw shape defs in a dictionary.""" file = open(fname, 'r') all = file.read() file.close() alldefs = all.split("=====") chardefs = {" " : []} for chardef in alldefs: lines = chardef.split("\n") if len(lines[0]) == 0: ix = 1 else: ix = 0 char = lines[ix] chardefs[char] = lines[(ix+1):] return chardefs def make_headerfile(fname): """Spit out the header file based on the named shapefile.""" print """/* 15 Segment Defines * * Generated by char_compiler.py * on %s * * Copyright (c) 2002, 2003 Bruce Kroeze * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * --------------------------------- * * 15 Segments Lettering * a * ------- * [\ i: /] * f[ \ : / ]b * [ n\:/j ] * g--- ---h * [ m/:\k ] * e[ / : \ ]c * [/ l: \] * ------- o * d * --------------------------------- */ """ % time.asctime() print "// SEGMENT LETTERS" segs = get_segs() letters = segs.keys() letters.sort() for letter in letters: segval = segs[letter] b = binary(segval, 16) print "// Segment: %s Hex val: 0x%04x" % (letter, segval) print "#DEFINE SEG15%s 0b%s" % (letter, b) if INCLUDE_LH: print "#DEFINE SEG15%sh 0b%s" % (letter, b[0:8]) print "#DEFINE SEG15%sl 0b%s" % (letter, b[-8:]) print print "// CHARACTER SHAPES" chars = load_chardefs(fname) letters = chars.keys() letters.sort() for letter in letters: label = get_label(letter) segval = parse_seg(chars[letter]) print "/* Character: %s" % label for line in chars[letter]: stripline = line.rstrip() if stripline: print " * " + stripline else: print " *" print " * Hex val: 0x%04X */" % segval b = binary(segval, 16) print "#DEFINE SEG15_%s 0b%s" % (label, b) if INCLUDE_LH: print "#DEFINE SEG15_%sh 0b%s" % (label, b[0:8]) print "#DEFINE SEG15_%sl 0b%s" % (label, b[-8:]) print print line = "const int16 SEG15_ASCII[] = {" for letter in ASCII: letter = letter.upper() if not letter in letters: label = "SPACE" else: label = get_label(letter) if len(line) > 60: print line line = " " line += "SEG15_%s, " % label line = line[:-2] + "};" print line print """ // Get the 16 bit value of the segments to light // for character "ch" int16 get_15seg(char ch) { if (ch > 31 && ch < %i) { ch -= 32; return SEG15_ASCII[ch]; } else { return SEG15_SPACE; } } """ % (len(ASCII)+32) if __name__ == "__main__": if not len(sys.argv) >= 2: print "USAGE: char_compiler def-file" else: make_headerfile(sys.argv[1])