Rev 183 | Rev 185 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
using System;using System.Collections;using System.Collections.Generic;using System.Drawing;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;namespace nitdcscore {public class Oled {public const int LCD_WIDTH = 128;public const int LCD_HEIGHT = 64;public const int EXTERNALVCC = 0x01;public const int SWITCHCAPVCC = 0x02;public const int SETLOWCOLUMN = 0x00;public const int SETHIGHCOLUMN = 0x10;public const int MEMORYMODE = 0x20;public const int COLUMNADDR = 0x21;public const int PAGEADDR = 0x22;public const int DEACTIVATESCROLL = 0x2E;public const int SETSTARTLINE = 0x40;public const int SETCONTRAST = 0x81;public const int CHARGEPUMP = 0x8D;public const int SEGREMAP = 0xA0;public const int DISPLAYALLON_RESUME = 0xA4;public const int DISPLAYALLON = 0xA5;public const int NORMALDISPLAY = 0xA6;public const int INVERTDISPLAY = 0xA7;public const int SETMULTIPLEX = 0xA8;public const int DISPLAYOFF = 0xAE;public const int DISPLAYON = 0xAF;public const int COMSCANINC = 0xC0;public const int COMSCANDEC = 0xC8;public const int SETDISPLAYOFFSET = 0xD3;public const int SETCOMPINS = 0xDA;public const int SETVCOMDETECT = 0xDB;public const int SETDISPLAYCLOCKDIV = 0xD5;public const int SETPRECHARGE = 0xD9;public byte[] buffer = new byte[Oled.LCD_WIDTH / 8 * Oled.LCD_HEIGHT];public int vccstate { get; set; }public byte i2caddr { get; set; }public i2cmaster i2c { get; set; }public Oled(int vccstate, byte i2caddr, i2cmaster i2c) {this.vccstate = vccstate;this.i2caddr = i2caddr;this.i2c = i2c;for (int i = 0; i < (LCD_WIDTH * LCD_HEIGHT / 8); i++) {buffer[i] = new byte();buffer[i] = 0x00;}}public void init() {// Init sequenceoled_command(DISPLAYOFF);oled_command(SETDISPLAYCLOCKDIV);oled_command(0x80); // Suggested ratiooled_command(SETMULTIPLEX);oled_command(LCD_HEIGHT - 1);oled_command(SETDISPLAYOFFSET);oled_command(0x00); // No offsetoled_command(SETSTARTLINE | 0x00); // Start line 0oled_command(CHARGEPUMP);if (this.vccstate == EXTERNALVCC)oled_command(0x10);elseoled_command(0x14);oled_command(MEMORYMODE);oled_command(0x00);oled_command(SEGREMAP | 0x01);oled_command(COMSCANDEC);// 128-64 specificoled_command(SETCOMPINS);oled_command(0x12);oled_command(SETCONTRAST);if (this.vccstate == EXTERNALVCC)oled_command(0x9F);elseoled_command(0xCF);oled_command(SETPRECHARGE);if (this.vccstate == EXTERNALVCC)oled_command(0x22);elseoled_command(0xF1);oled_command(SETVCOMDETECT);oled_command(0x40);oled_command(DISPLAYALLON_RESUME);oled_command(NORMALDISPLAY);oled_command(DEACTIVATESCROLL);oled_command(DISPLAYON);}public void display() {oled_command(COLUMNADDR);oled_command(0x00); // Column start addressoled_command(LCD_WIDTH - 1); // Column end addressoled_command(PAGEADDR);oled_command(0x00); // Page start addressoled_command(7); // Page end address (7 for 64 pixels)for (int i = 0; i < (LCD_WIDTH * LCD_HEIGHT / 8); i++) {byte[] data = new byte[16];for (int j = 0; j < 16; j++) {data[j] = buffer[i];i++;}i--;i2c.WriteI2cData(i2cUtils.addressToWrite(this.i2caddr), data, 16);}}public int oled_command(byte c) {byte[] data = { 0x00, c };i2c.WriteI2cData(i2cUtils.addressToWrite(this.i2caddr), data, 2); ;//data[0] = c;//i2c.WriteI2cData((byte)this.i2caddr, data, 1);return 0;}}public class BmpImage {public string filename; // The image filenamepublic int filesize; // Total size of thepublic int datastart; // Location of the start of image datapublic int imagesize; // The size of actual image datapublic int width; // Width of the imagepublic int height; // Height of the imagepublic int bpp; // Bits per pixel of the imagepublic int bytepad; // Bytes padded to align image rowpublic byte[] data; // The bmp image datapublic BitArray[] bitdata; // Data in bitarray formatpublic BmpImage(string filename) {this.filename = filename;filesize = 0;datastart = 0xffffff;imagesize = 0;width = 0;height = 0;bpp = 0;bytepad = 0;data = new byte[8192];bitdata = new BitArray[1];this.load();}public int load() {using (BinaryReader b = new BinaryReader(File.Open(this.filename, FileMode.Open))) {int pos = 0;int readLen = (int)b.BaseStream.Length;while (pos < readLen) {// Read the image data from the fileif (pos >= this.datastart) {// BMP format stored in 'data'int imgptr = 0;while (imgptr < this.imagesize) {this.data[imgptr++] = b.ReadByte();}//Console.WriteLine("Read " + imgptr.ToString() + " bytes");// Raw decoded data stored in 'bitdata'this.bitdata = new BitArray[this.height];int x = 0; // Cursor X positionint y = 0; // Cursor Y positionint i = 0; // Current byte position//Console.WriteLine("W:{0} H:{1}", img.width.ToString(), img.height.ToString());for (y = this.height - 1; y >= 0; y--) {this.bitdata[y] = new BitArray(this.width);x = 0;while (x < this.width) {if (x >= this.width)break;// Reverse the bit cause its stored back to front in bmp formatbyte br;br = this.data[i];br = (byte)((br * 0x0202020202 & 0x010884422010) % 1023);for (int bitidx = 0; bitidx < 8; bitidx++) {int bitpos = x + bitidx;if (bitpos >= this.width)break;int val = br >> bitidx & 0x01;//Console.WriteLine("X:{0} Y:{1}", x.ToString(), y.ToString());this.bitdata[y].Set(bitpos, Convert.ToBoolean(val));}x += 8;i++;}i += this.bytepad; // Account for the padding}break;}// Read the header data from the fileswitch (pos) {// Magic number header ("BM")case 0x00: {byte t1 = b.ReadByte();byte t2 = b.ReadByte();pos += 2;string text = ((char)t1).ToString();text += ((char)t2).ToString();}break;// The size of the image filecase 0x02: {this.filesize = (int)b.ReadUInt32();pos += 4;if (this.filesize != b.BaseStream.Length)Console.WriteLine("Size mismatch: " + this.filesize.ToString() + ":" + b.BaseStream.Length.ToString());elseConsole.WriteLine("Size: " + this.filesize.ToString());}break;// The start of image data locationcase 0x0a: {this.datastart = (int)b.ReadUInt32();pos += 4;}break;// The DIB header file sizecase 0x0e: {//UInt32 dibhs = b.ReadUInt32();b.ReadUInt32();pos += 4;}break;// Bitmap width in pixelscase 0x12: {this.width = (int)b.ReadInt32();pos += 4;// Rows aligned to a DWORDint bitsOver = this.width % 32;if (bitsOver > 0) {this.bytepad = (32 - bitsOver) / 8;}}break;// Bitmap height in pixelscase 0x16: {this.height = (int)b.ReadInt32();pos += 4;}break;// Bitmap bytes per pixelcase 0x1c: {this.bpp = (int)b.ReadUInt16();pos += 2;}break;// Bitmap sizecase 0x22: {this.imagesize = (int)b.ReadUInt32();pos += 4;}break;// Not an important piece of data; dump itdefault:b.ReadByte();pos++;break;}}}return 0;}}public class BitImage {public BitArray[] bitdata;public int width;public int height;public BitImage(int width, int height) {this.width = width;this.height = height;this.bitdata = new BitArray[this.height];for (int i = 0; i < this.height; i++) {this.bitdata[i] = new BitArray(this.width);}}public BitImage(BitArray[] matrix) {this.width = matrix[0].Length;this.height = matrix.Length;this.bitdata = BitImage.copy(matrix);}public BitImage(BmpImage bmp) {this.width = bmp.width;this.height = bmp.height;this.bitdata = BitImage.copy(bmp.bitdata);}public BitImage(BitImage bit) {this.width = bit.width;this.height = bit.height;this.bitdata = BitImage.copy(bit.bitdata);}public BitImage(Bitmap bmp) {//Bitmap bmp = new Bitmap(nitdcscore.Properties.Resources.flap_bg);//BitImage bi = new BitImage(new Bitmap(Resources.flap_needle));this.width = bmp.Width;this.height = bmp.Height;this.bitdata = new BitArray[this.height];for (int y = 0; y < this.height; y++) {this.bitdata[y] = new BitArray(this.width);for (int x = 0; x < this.height; x++) {Color c = bmp.GetPixel(x, y);if (c.GetBrightness() == 0)this.bitdata[y].Set(x, false);elsethis.bitdata[y].Set(x, true);}}}public void fillAll(bool color) {for (int i = 0; i < this.height; i++) {this.bitdata[i].SetAll(color);}}public void drawPixel(int x, int y, bool color) {if (x < 0 || y < 0 || x >= this.width || y >= this.height)return;this.bitdata[y].Set(x, color);}public void drawVLine(int x, int y, int h, bool color) {if (x < 0 || x >= this.width)return;if (y < 0) {h += y;y = 0;}if ((y + h) > this.height)h = this.height - y;if (h <= 0)return;for (int i = y; i < y + h; i++) {this.bitdata[i].Set(x, color);}}public void drawHLine(int x, int y, int w, bool color) {if (y < 0 || y >= this.height)return;if (x < 0) {w += x;x = 0;}if ((x + w) > this.width)w = this.width - x;if (w <= 0)return;for (int i = x; i < x + height; i++) {this.bitdata[y].Set(i, color);}}public void drawLine(int x0, int y0, int x1, int y1, bool color) {bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);if (steep) {swap(ref x0, ref y0);swap(ref x1, ref y1);}if (x0 > x1) {swap(ref x0, ref x1);swap(ref y0, ref y1);}int dx, dy;dx = x1 - x0;dy = Math.Abs(y1 - y0);int err = dx / 2;int ystep;if (y0 < y1)ystep = 1;elseystep = -1;for (; x0 <= x1; x0++) {if (steep)drawPixel(y0, x0, color);elsedrawPixel(x0, y0, color);err -= dy;if (err < 0) {y0 += ystep;err += dx;}}}public void drawRect(int x, int y, int w, int h, bool color) {drawHLine(x, y, w, color);drawHLine(x, y + h - 1, w, color);drawVLine(x, y, h, color);drawVLine(x + w - 1, y, h, color);}public void fillRect(int x, int y, int w, int h, bool color) {for (int i = x; i < x + w; i++) {drawVLine(i, y, h, color);}}public void drawCircle(int x0, int y0, int r, bool color) {int f = 1 - r;int ddF_x = 1;int ddF_y = -2 * r;int x = 0;int y = r;drawPixel(x0, y0 + r, color);drawPixel(x0, y0 - r, color);drawPixel(x0 + r, y0, color);drawPixel(x0 - r, y0, color);while (x < y) {if (f >= 0) {y--;ddF_y += 2;f += ddF_y;}x++;ddF_x += 2;f += ddF_x;drawPixel(x0 + x, y0 + y, color);drawPixel(x0 - x, y0 + y, color);drawPixel(x0 + x, y0 - y, color);drawPixel(x0 - x, y0 - y, color);drawPixel(x0 + y, y0 + x, color);drawPixel(x0 - y, y0 + x, color);drawPixel(x0 + y, y0 - x, color);drawPixel(x0 - y, y0 - x, color);}}public void fillCircle(int x0, int y0, int r, bool color) {drawVLine(x0, y0 - r, 2 * r + 1, color);fillCircleHelper(x0, y0, r, 3, 0, color);}public void fillCircleHelper(int x0, int y0, int r, int corner, int delta, bool color) {int f = 1 - r;int ddF_x = 1;int ddF_y = -2 * r;int x = 0;int y = r;while (x < y) {if (f >= 0) {y--;ddF_y += 2;f += ddF_y;}x++;ddF_x += 2;f += ddF_x;if ((corner & 0x01) > 0) {drawVLine(x0 + x, y0 - y, 2 * y + 1 + delta, color);drawVLine(x0 + y, y0 - x, 2 * x + 1 + delta, color);}if ((corner & 0x02) > 0) {drawVLine(x0 - x, y0 - y, 2 * y + 1 + delta, color);drawVLine(x0 - y, y0 - x, 2 * x + 1 + delta, color);}}}public void drawTriangle(int x0, int y0, int x1, int y1, int x2, int y2, bool color) {drawLine(x0, y0, x1, y1, color);drawLine(x1, y1, x2, y2, color);drawLine(x2, y2, x0, y0, color);}public void drawPoly(Point[] points, bool color) {int idx = 1;int c = points.Length;while (idx < c) {drawLine(points[idx - 1].X, points[idx - 1].Y, points[idx].X, points[idx].Y, color);idx++;}drawLine(points[c - 1].X, points[c - 1].Y, points[0].X, points[0].Y, color);}public void drawChar(int x, int y, byte c, bool color, int size) {for (int i = 0; i < 6; i++) {byte line;if (i < 5)line = Font.classic[c * 5 + i];elseline = 0x00;for (int j = 0; j < 8; j++, line >>= 1) {if ((line & 0x01) > 0) {if (size == 1)drawPixel(x + i, y + j, color);elsefillRect(x + (i * size), y + (j * size), size, size, color);}/*} else {if (size == 1)drawPixel(x + i, y + j, !color);elsefillRect(x+i*size, y+j*size, size, size, !color);}*/}}}public void write(string text, int x, int y, bool color, int size) {Point cur = new Point(x, y);foreach (byte c in text) {if (c == '\n') {cur.Y += size * 8;cur.X = x;} else if (c == '\r') {} else if (c == ' ') {// Quicker then calling drawChar functioncur.X += size * 6;} else {drawChar(cur.X, cur.Y, c, color, size);cur.X += size * 6;}}}public static void swap(ref int i, ref int j) {int t = i; i = j; j = t;}/// <summary>/// Copies the provided image onto the objects image, at position specified/// by the ox and oy parms. Only copies lit bits (not dark)/// </summary>/// <param name="bit">The bit image to paste onto this image</param>/// <param name="ox">The X origin</param>/// <param name="oy">The Y origin</param>public void blit(BitImage bit, int ox, int oy) {int x = 0;int y = 0;for (y = 0; y < bit.height; y++) {for (x = 0; x < bit.width; x++) {if (bit.bitdata[y].Get(x)) {this.bitdata[oy + y].Set(ox + x, true);}}}}/// <summary>/// Rotate the image by the specified degrees./// </summary>/// <param name="degrees">Degrees to rotate</param>public void rotate(int degrees) {this.bitdata = (BitArray[])BitImage.rotateMatrix(this.bitdata, degrees).bitdata;this.width = this.bitdata[0].Length;this.height = this.bitdata.Length;}public byte[] toByteArray() {return BitImage.toByteArray(this.bitdata);}public static BitArray[] copy(BitArray[] ba) {int width = ba[0].Length;int height = ba.Length;BitArray[] newba = new BitArray[height];for (int y = 0; y < height; y++) {newba[y] = new BitArray(width);for (int x = 0; x < width; x++) {if (ba[y].Get(x)) {newba[y].Set(x, true);}}}return newba;}public static byte[] toByteArray(BitArray[] ba) {int width = ba[0].Length;int height = ba.Length;int size = width * height / 8;byte[] buffer = new byte[size];if (size % 8 != 0) {Console.WriteLine("toByteArray only supports mod 8 array (size: {0}, misalinged by {1})", size, size % 8);return null;}for (int y = 0; y < ba.Length; y++) {byte[] bytes = new byte[ba[0].Length / 8];ba[y].CopyTo(bytes, 0);for (int i = 0; i < bytes.Length; i++) {buffer[y * bytes.Length + i] = bytes[i];}}return buffer;}/// <summary>/// Rotates a matrix by provided degrees. Note that the size of the/// image may change with this process/// </summary>/// <returns>A matrix with the rotated elements</returns>/// <param name="matrix">The BitArray matrix to be rotated</param>/// <param name="degrees">The degress to rotate the matrix by</param>public static BitImage rotateMatrix(BitArray[] matrix, int degrees) {// Widths of the matrixint oldwidth = matrix[0].Length;int oldheight = matrix.Length;// If no rotation nessecary, just return a new BitImageif (degrees == 0 || degrees == 360) {BitImage bit = new BitImage(oldwidth, oldheight);bit.bitdata = (BitArray[])matrix;return bit;}// Calc the new image meta datadouble rads = degrees * Math.PI / 180;double tcos = Math.Cos(rads);double tsin = Math.Sin(rads);Point p1 = new Point((int)(-oldheight * tsin), (int)(oldheight * tcos));Point p2 = new Point((int)(oldwidth * tcos - oldheight * tsin),(int)(oldheight * tcos + oldwidth * tsin));Point p3 = new Point((int)(oldwidth * tcos), (int)(oldwidth * tsin));Point min = new Point(Math.Min(0, Math.Min(p1.X, Math.Min(p2.X, p3.X))),Math.Min(0, Math.Min(p1.Y, Math.Min(p2.Y, p3.Y))));Point max = new Point(Math.Max(p1.X, Math.Max(p2.X, p3.X)),Math.Max(p1.Y, Math.Max(p2.Y, p3.Y)));Point size = new Point(max.X - min.X, max.Y - min.Y);// Prepopulate the bitarrayBitArray[] bitmatrix = new BitArray[size.Y];for (int y = 0; y < size.Y; y++) {bitmatrix[y] = new BitArray(size.X);}// Transform pixel by pixelfor (int y = 0; y < size.Y - 1; y++) {for (int x = 0; x < size.X - 1; x++) {int sourcex = (int)((x + min.X) * tcos + (y + min.Y) * tsin);int sourcey = (int)((y + min.Y) * tcos - (x + min.X) * tsin);if (sourcex < 0 || sourcex > oldwidth - 1 || sourcey < 0 || sourcey > oldheight - 1)continue;if (x < 0 || x > size.X - 1 || y < 0 || y > size.Y - 1)continue;bitmatrix[y].Set(x, matrix[sourcey].Get(sourcex));}}BitImage bi = new BitImage(bitmatrix[0].Length, bitmatrix.Length);bi.bitdata = (BitArray[])bitmatrix;return bi;}}public struct Point {private int x;private int y;public int X {get {return this.x;}set {this.x = value;}}public int Y {get {return this.y;}set {this.y = value;}}public Point(int x, int y) {this.x = x;this.y = y;}}public class Font {public Font() {}public static byte[] classic = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00,0x3E, 0x5B, 0x4F, 0x5B, 0x3E,0x3E, 0x6B, 0x4F, 0x6B, 0x3E,0x1C, 0x3E, 0x7C, 0x3E, 0x1C,0x18, 0x3C, 0x7E, 0x3C, 0x18,0x1C, 0x57, 0x7D, 0x57, 0x1C,0x1C, 0x5E, 0x7F, 0x5E, 0x1C,0x00, 0x18, 0x3C, 0x18, 0x00,0xFF, 0xE7, 0xC3, 0xE7, 0xFF,0x00, 0x18, 0x24, 0x18, 0x00,0xFF, 0xE7, 0xDB, 0xE7, 0xFF,0x30, 0x48, 0x3A, 0x06, 0x0E,0x26, 0x29, 0x79, 0x29, 0x26,0x40, 0x7F, 0x05, 0x05, 0x07,0x40, 0x7F, 0x05, 0x25, 0x3F,0x5A, 0x3C, 0xE7, 0x3C, 0x5A,0x7F, 0x3E, 0x1C, 0x1C, 0x08,0x08, 0x1C, 0x1C, 0x3E, 0x7F,0x14, 0x22, 0x7F, 0x22, 0x14,0x5F, 0x5F, 0x00, 0x5F, 0x5F,0x06, 0x09, 0x7F, 0x01, 0x7F,0x00, 0x66, 0x89, 0x95, 0x6A,0x60, 0x60, 0x60, 0x60, 0x60,0x94, 0xA2, 0xFF, 0xA2, 0x94,0x08, 0x04, 0x7E, 0x04, 0x08,0x10, 0x20, 0x7E, 0x20, 0x10,0x08, 0x08, 0x2A, 0x1C, 0x08,0x08, 0x1C, 0x2A, 0x08, 0x08,0x1E, 0x10, 0x10, 0x10, 0x10,0x0C, 0x1E, 0x0C, 0x1E, 0x0C,0x30, 0x38, 0x3E, 0x38, 0x30,0x06, 0x0E, 0x3E, 0x0E, 0x06,0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x5F, 0x00, 0x00,0x00, 0x07, 0x00, 0x07, 0x00,0x14, 0x7F, 0x14, 0x7F, 0x14,0x24, 0x2A, 0x7F, 0x2A, 0x12,0x23, 0x13, 0x08, 0x64, 0x62,0x36, 0x49, 0x56, 0x20, 0x50,0x00, 0x08, 0x07, 0x03, 0x00,0x00, 0x1C, 0x22, 0x41, 0x00,0x00, 0x41, 0x22, 0x1C, 0x00,0x2A, 0x1C, 0x7F, 0x1C, 0x2A,0x08, 0x08, 0x3E, 0x08, 0x08,0x00, 0x80, 0x70, 0x30, 0x00,0x08, 0x08, 0x08, 0x08, 0x08,0x00, 0x00, 0x60, 0x60, 0x00,0x20, 0x10, 0x08, 0x04, 0x02,0x3E, 0x51, 0x49, 0x45, 0x3E,0x00, 0x42, 0x7F, 0x40, 0x00,0x72, 0x49, 0x49, 0x49, 0x46,0x21, 0x41, 0x49, 0x4D, 0x33,0x18, 0x14, 0x12, 0x7F, 0x10,0x27, 0x45, 0x45, 0x45, 0x39,0x3C, 0x4A, 0x49, 0x49, 0x31,0x41, 0x21, 0x11, 0x09, 0x07,0x36, 0x49, 0x49, 0x49, 0x36,0x46, 0x49, 0x49, 0x29, 0x1E,0x00, 0x00, 0x14, 0x00, 0x00,0x00, 0x40, 0x34, 0x00, 0x00,0x00, 0x08, 0x14, 0x22, 0x41,0x14, 0x14, 0x14, 0x14, 0x14,0x00, 0x41, 0x22, 0x14, 0x08,0x02, 0x01, 0x59, 0x09, 0x06,0x3E, 0x41, 0x5D, 0x59, 0x4E,0x7C, 0x12, 0x11, 0x12, 0x7C,0x7F, 0x49, 0x49, 0x49, 0x36,0x3E, 0x41, 0x41, 0x41, 0x22,0x7F, 0x41, 0x41, 0x41, 0x3E,0x7F, 0x49, 0x49, 0x49, 0x41,0x7F, 0x09, 0x09, 0x09, 0x01,0x3E, 0x41, 0x41, 0x51, 0x73,0x7F, 0x08, 0x08, 0x08, 0x7F,0x00, 0x41, 0x7F, 0x41, 0x00,0x20, 0x40, 0x41, 0x3F, 0x01,0x7F, 0x08, 0x14, 0x22, 0x41,0x7F, 0x40, 0x40, 0x40, 0x40,0x7F, 0x02, 0x1C, 0x02, 0x7F,0x7F, 0x04, 0x08, 0x10, 0x7F,0x3E, 0x41, 0x41, 0x41, 0x3E,0x7F, 0x09, 0x09, 0x09, 0x06,0x3E, 0x41, 0x51, 0x21, 0x5E,0x7F, 0x09, 0x19, 0x29, 0x46,0x26, 0x49, 0x49, 0x49, 0x32,0x03, 0x01, 0x7F, 0x01, 0x03,0x3F, 0x40, 0x40, 0x40, 0x3F,0x1F, 0x20, 0x40, 0x20, 0x1F,0x3F, 0x40, 0x38, 0x40, 0x3F,0x63, 0x14, 0x08, 0x14, 0x63,0x03, 0x04, 0x78, 0x04, 0x03,0x61, 0x59, 0x49, 0x4D, 0x43,0x00, 0x7F, 0x41, 0x41, 0x41,0x02, 0x04, 0x08, 0x10, 0x20,0x00, 0x41, 0x41, 0x41, 0x7F,0x04, 0x02, 0x01, 0x02, 0x04,0x40, 0x40, 0x40, 0x40, 0x40,0x00, 0x03, 0x07, 0x08, 0x00,0x20, 0x54, 0x54, 0x78, 0x40,0x7F, 0x28, 0x44, 0x44, 0x38,0x38, 0x44, 0x44, 0x44, 0x28,0x38, 0x44, 0x44, 0x28, 0x7F,0x38, 0x54, 0x54, 0x54, 0x18,0x00, 0x08, 0x7E, 0x09, 0x02,0x18, 0xA4, 0xA4, 0x9C, 0x78,0x7F, 0x08, 0x04, 0x04, 0x78,0x00, 0x44, 0x7D, 0x40, 0x00,0x20, 0x40, 0x40, 0x3D, 0x00,0x7F, 0x10, 0x28, 0x44, 0x00,0x00, 0x41, 0x7F, 0x40, 0x00,0x7C, 0x04, 0x78, 0x04, 0x78,0x7C, 0x08, 0x04, 0x04, 0x78,0x38, 0x44, 0x44, 0x44, 0x38,0xFC, 0x18, 0x24, 0x24, 0x18,0x18, 0x24, 0x24, 0x18, 0xFC,0x7C, 0x08, 0x04, 0x04, 0x08,0x48, 0x54, 0x54, 0x54, 0x24,0x04, 0x04, 0x3F, 0x44, 0x24,0x3C, 0x40, 0x40, 0x20, 0x7C,0x1C, 0x20, 0x40, 0x20, 0x1C,0x3C, 0x40, 0x30, 0x40, 0x3C,0x44, 0x28, 0x10, 0x28, 0x44,0x4C, 0x90, 0x90, 0x90, 0x7C,0x44, 0x64, 0x54, 0x4C, 0x44,0x00, 0x08, 0x36, 0x41, 0x00,0x00, 0x00, 0x77, 0x00, 0x00,0x00, 0x41, 0x36, 0x08, 0x00,0x02, 0x01, 0x02, 0x04, 0x02,0x3C, 0x26, 0x23, 0x26, 0x3C,0x1E, 0xA1, 0xA1, 0x61, 0x12,0x3A, 0x40, 0x40, 0x20, 0x7A,0x38, 0x54, 0x54, 0x55, 0x59,0x21, 0x55, 0x55, 0x79, 0x41,0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut0x21, 0x55, 0x54, 0x78, 0x40,0x20, 0x54, 0x55, 0x79, 0x40,0x0C, 0x1E, 0x52, 0x72, 0x12,0x39, 0x55, 0x55, 0x55, 0x59,0x39, 0x54, 0x54, 0x54, 0x59,0x39, 0x55, 0x54, 0x54, 0x58,0x00, 0x00, 0x45, 0x7C, 0x41,0x00, 0x02, 0x45, 0x7D, 0x42,0x00, 0x01, 0x45, 0x7C, 0x40,0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut0xF0, 0x28, 0x25, 0x28, 0xF0,0x7C, 0x54, 0x55, 0x45, 0x00,0x20, 0x54, 0x54, 0x7C, 0x54,0x7C, 0x0A, 0x09, 0x7F, 0x49,0x32, 0x49, 0x49, 0x49, 0x32,0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut0x32, 0x4A, 0x48, 0x48, 0x30,0x3A, 0x41, 0x41, 0x21, 0x7A,0x3A, 0x42, 0x40, 0x20, 0x78,0x00, 0x9D, 0xA0, 0xA0, 0x7D,0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut0x3D, 0x40, 0x40, 0x40, 0x3D,0x3C, 0x24, 0xFF, 0x24, 0x24,0x48, 0x7E, 0x49, 0x43, 0x66,0x2B, 0x2F, 0xFC, 0x2F, 0x2B,0xFF, 0x09, 0x29, 0xF6, 0x20,0xC0, 0x88, 0x7E, 0x09, 0x03,0x20, 0x54, 0x54, 0x79, 0x41,0x00, 0x00, 0x44, 0x7D, 0x41,0x30, 0x48, 0x48, 0x4A, 0x32,0x38, 0x40, 0x40, 0x22, 0x7A,0x00, 0x7A, 0x0A, 0x0A, 0x72,0x7D, 0x0D, 0x19, 0x31, 0x7D,0x26, 0x29, 0x29, 0x2F, 0x28,0x26, 0x29, 0x29, 0x29, 0x26,0x30, 0x48, 0x4D, 0x40, 0x20,0x38, 0x08, 0x08, 0x08, 0x08,0x08, 0x08, 0x08, 0x08, 0x38,0x2F, 0x10, 0xC8, 0xAC, 0xBA,0x2F, 0x10, 0x28, 0x34, 0xFA,0x00, 0x00, 0x7B, 0x00, 0x00,0x08, 0x14, 0x2A, 0x14, 0x22,0x22, 0x14, 0x2A, 0x14, 0x08,0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block0x00, 0x00, 0x00, 0xFF, 0x00,0x10, 0x10, 0x10, 0xFF, 0x00,0x14, 0x14, 0x14, 0xFF, 0x00,0x10, 0x10, 0xFF, 0x00, 0xFF,0x10, 0x10, 0xF0, 0x10, 0xF0,0x14, 0x14, 0x14, 0xFC, 0x00,0x14, 0x14, 0xF7, 0x00, 0xFF,0x00, 0x00, 0xFF, 0x00, 0xFF,0x14, 0x14, 0xF4, 0x04, 0xFC,0x14, 0x14, 0x17, 0x10, 0x1F,0x10, 0x10, 0x1F, 0x10, 0x1F,0x14, 0x14, 0x14, 0x1F, 0x00,0x10, 0x10, 0x10, 0xF0, 0x00,0x00, 0x00, 0x00, 0x1F, 0x10,0x10, 0x10, 0x10, 0x1F, 0x10,0x10, 0x10, 0x10, 0xF0, 0x10,0x00, 0x00, 0x00, 0xFF, 0x10,0x10, 0x10, 0x10, 0x10, 0x10,0x10, 0x10, 0x10, 0xFF, 0x10,0x00, 0x00, 0x00, 0xFF, 0x14,0x00, 0x00, 0xFF, 0x00, 0xFF,0x00, 0x00, 0x1F, 0x10, 0x17,0x00, 0x00, 0xFC, 0x04, 0xF4,0x14, 0x14, 0x17, 0x10, 0x17,0x14, 0x14, 0xF4, 0x04, 0xF4,0x00, 0x00, 0xFF, 0x00, 0xF7,0x14, 0x14, 0x14, 0x14, 0x14,0x14, 0x14, 0xF7, 0x00, 0xF7,0x14, 0x14, 0x14, 0x17, 0x14,0x10, 0x10, 0x1F, 0x10, 0x1F,0x14, 0x14, 0x14, 0xF4, 0x14,0x10, 0x10, 0xF0, 0x10, 0xF0,0x00, 0x00, 0x1F, 0x10, 0x1F,0x00, 0x00, 0x00, 0x1F, 0x14,0x00, 0x00, 0x00, 0xFC, 0x14,0x00, 0x00, 0xF0, 0x10, 0xF0,0x10, 0x10, 0xFF, 0x10, 0xFF,0x14, 0x14, 0x14, 0xFF, 0x14,0x10, 0x10, 0x10, 0x1F, 0x00,0x00, 0x00, 0x00, 0xF0, 0x10,0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xF0, 0xF0, 0xF0, 0xF0, 0xF0,0xFF, 0xFF, 0xFF, 0x00, 0x00,0x00, 0x00, 0x00, 0xFF, 0xFF,0x0F, 0x0F, 0x0F, 0x0F, 0x0F,0x38, 0x44, 0x44, 0x38, 0x44,0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta0x7E, 0x02, 0x02, 0x06, 0x06,0x02, 0x7E, 0x02, 0x7E, 0x02,0x63, 0x55, 0x49, 0x41, 0x63,0x38, 0x44, 0x44, 0x3C, 0x04,0x40, 0x7E, 0x20, 0x1E, 0x20,0x06, 0x02, 0x7E, 0x02, 0x02,0x99, 0xA5, 0xE7, 0xA5, 0x99,0x1C, 0x2A, 0x49, 0x2A, 0x1C,0x4C, 0x72, 0x01, 0x72, 0x4C,0x30, 0x4A, 0x4D, 0x4D, 0x30,0x30, 0x48, 0x78, 0x48, 0x30,0xBC, 0x62, 0x5A, 0x46, 0x3D,0x3E, 0x49, 0x49, 0x49, 0x00,0x7E, 0x01, 0x01, 0x01, 0x7E,0x2A, 0x2A, 0x2A, 0x2A, 0x2A,0x44, 0x44, 0x5F, 0x44, 0x44,0x40, 0x51, 0x4A, 0x44, 0x40,0x40, 0x44, 0x4A, 0x51, 0x40,0x00, 0x00, 0xFF, 0x01, 0x03,0xE0, 0x80, 0xFF, 0x00, 0x00,0x08, 0x08, 0x6B, 0x6B, 0x08,0x36, 0x12, 0x36, 0x24, 0x36,0x06, 0x0F, 0x09, 0x0F, 0x06,0x00, 0x00, 0x18, 0x18, 0x00,0x00, 0x00, 0x10, 0x10, 0x00,0x30, 0x40, 0xFF, 0x01, 0x01,0x00, 0x1F, 0x01, 0x01, 0x1E,0x00, 0x19, 0x1D, 0x17, 0x12,0x00, 0x3C, 0x3C, 0x3C, 0x3C,0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP};}}