├── ImageConverter.exe ├── README.md ├── Terminal.cs ├── VGAColor.cs ├── VGADriverII.cs ├── VGAFont.cs ├── VGAGraphics.cs └── VGAImage.cs /ImageConverter.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/napalmtorch/CosmosVGA/7bd37a2c109076d60922491484ee07f7fbe4125c/ImageConverter.exe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CosmosVGA 2 | Custom Cosmos VGA Driver 3 | 4 | # Features 5 | - Supports 4 modes 6 | - 80x25x4 Text 7 | - 80x50x4 Text 8 | - 90x60x4 Text 9 | - 320x200x8 Pixel 10 | - 320x200x8 Pixel(Double Buffered) 11 | - VGA BIOS font rendering(text and pixel mode) 12 | - Custom Image format(4-byte header for width and height, remainder is 8bit pixels) 13 | - Loading from disk 14 | - Resize by factor 15 | - Tool to convert 32-bit JPEG/PNG/BMP to custom PIC format 16 | - Custom palettes(defined in VGADriverII.cs) 17 | 18 | # Usage 19 | To use this driver, simply add all the .cs files that start with "VGA" to your project. 20 | Once the files are in your project, you can use Cosmos.HAL to access the driver and 21 | Cosmos.System.Graphics to access its features. The first thing you need to do is initialize 22 | the driver and set the mode using Cosmos.HAL.VGADriverII.Initialize(VGAMode mode); 23 | Once you've set the mode, you can use the functions in Cosmos.System.Graphics.VGAGraphics 24 | to do various drawing commands, or just use the VGADriverII class for direct access to the 25 | VGA device. When using 320x200 double buffered mode, remember to use VGAGraphics.Display() 26 | after drawing to swap buffers. 27 | 28 | # The default Console Class will no longer work 29 | You will need to use Terminal.cs, please read the file to view all of its features! 30 | Its not very complicated 31 | 32 | # Example 33 | ![vgatut](https://user-images.githubusercontent.com/55903118/111919703-b8186780-8a61-11eb-968c-2b3bc14a401f.png) 34 | -------------------------------------------------------------------------------- /Terminal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Cosmos.HAL; 5 | using Cosmos.System.Graphics; 6 | 7 | namespace Cosmos.HAL 8 | { 9 | public static class Terminal 10 | { 11 | // cursor 12 | public static int CursorX { get; private set; } 13 | public static int CursorY { get; private set; } 14 | 15 | // colors 16 | public static ConsoleColor BackColor = ConsoleColor.Black; 17 | public static ConsoleColor TextColor = ConsoleColor.White; 18 | 19 | // clear the screen 20 | public static void Clear() 21 | { 22 | VGADriverII.Clear((byte)BackColor); 23 | SetCursorPos(0, 0); 24 | } 25 | 26 | // draw character to position on screen 27 | public static unsafe void PutCharacter(int x, int y, char c, ConsoleColor fg, ConsoleColor bg) 28 | { 29 | uint index = (uint)(x + (y * VGADriverII.Width)) * 2; 30 | VGADriverII.Buffer[index] = (byte)c; 31 | VGADriverII.Buffer[index + 1] = ToAttribute((VGAColor)fg, (VGAColor)bg); 32 | } 33 | 34 | // print character to next position 35 | public static void WriteChar(char c, ConsoleColor fg, ConsoleColor bg) 36 | { 37 | if (c == '\n') { NewLine(); } 38 | else 39 | { 40 | PutCharacter(CursorX, CursorY, c, fg, bg); 41 | CursorX++; 42 | if (CursorX >= VGADriverII.Width) { NewLine(); } 43 | UpdateCursor(); 44 | } 45 | } 46 | public static void WriteChar(char c, ConsoleColor fg) { WriteChar(c, fg, BackColor); } 47 | public static void WriteChar(char c) { WriteChar(c, TextColor, BackColor); } 48 | 49 | // print string to next position 50 | public static void Write(string text, ConsoleColor fg, ConsoleColor bg) 51 | { 52 | for (int i = 0; i < text.Length; i++) 53 | { 54 | WriteChar(text[i], fg, bg); 55 | } 56 | } 57 | public static void Write(string text, ConsoleColor fg) { Write(text, fg, BackColor); } 58 | public static void Write(string text) { Write(text, TextColor, BackColor); } 59 | 60 | // print line to next positoin 61 | public static void WriteLine(string text, ConsoleColor fg, ConsoleColor bg) { Write(text + "\n", fg, bg); } 62 | public static void WriteLine(string text, ConsoleColor fg) { WriteLine(text, fg, BackColor); } 63 | public static void WriteLine(string text) { WriteLine(text, TextColor, BackColor); } 64 | 65 | // backspace input 66 | private static void Backspace() 67 | { 68 | if (CursorX > 0) 69 | { 70 | SetCursorX(CursorX - 1); 71 | PutCharacter(CursorX, CursorY, ' ', TextColor, BackColor); 72 | } 73 | else if (CursorY > 0) 74 | { 75 | SetCursorPos(VGADriverII.Width - 1, CursorY - 1); 76 | PutCharacter(CursorX, CursorY, ' ', TextColor, BackColor); 77 | } 78 | } 79 | 80 | // read line of input 81 | public static string ReadLine() 82 | { 83 | string input = ""; 84 | while (true) 85 | { 86 | ConsoleKeyInfo key = Console.ReadKey(true); 87 | // character 88 | if (key.KeyChar >= 32 && key.KeyChar <= 126) { WriteChar(key.KeyChar); input += key.KeyChar; } 89 | // backspace 90 | else if (key.Key == ConsoleKey.Backspace) 91 | { 92 | if (input.Length > 0) 93 | { 94 | input = input.Remove(input.Length - 1, 1); 95 | Backspace(); 96 | } 97 | } 98 | // enter 99 | else if (key.Key == ConsoleKey.Enter) { WriteChar('\n'); break; } 100 | } 101 | return input; 102 | } 103 | 104 | // generate new line 105 | public static void NewLine() 106 | { 107 | CursorY++; 108 | if (CursorY >= VGADriverII.Height) 109 | { 110 | Scroll(); 111 | SetCursorPos(0, VGADriverII.Height - 1); 112 | } 113 | else { SetCursorPos(0, CursorY); } 114 | } 115 | 116 | // scroll by one line 117 | private static unsafe void Scroll() 118 | { 119 | VGADriverII.MemoryCopy(VGADriverII.Buffer + (VGADriverII.Width * 2), VGADriverII.Buffer, (VGADriverII.Width * (VGADriverII.Height - 1)) * 2); 120 | for (int i = 0; i < VGADriverII.Width; i++) { PutCharacter(i, VGADriverII.Height - 1, ' ', TextColor, BackColor); } 121 | } 122 | 123 | // set cursor position 124 | public static unsafe void SetCursorPos(int x, int y) 125 | { 126 | VGADriverII.SetCursorPos((ushort)x, (ushort)y); 127 | CursorX = x; CursorY = y; 128 | VGADriverII.Buffer[((x + (y * VGADriverII.Width)) * 2) + 1] = ToAttribute((VGAColor)TextColor, (VGAColor)BackColor); 129 | } 130 | public static void SetCursorX(int x) { SetCursorPos(x, CursorY); } 131 | public static void SetCursorY(int y) { SetCursorPos(CursorX, y); } 132 | public static void UpdateCursor() { SetCursorPos(CursorX, CursorY); } 133 | public static void DisableCursor() { VGADriverII.DisableCursor(); } 134 | 135 | // convert colors to attribute 136 | public static byte ToAttribute(VGAColor fg, VGAColor bg) { return (byte)((byte)fg | (byte)bg << 4); } 137 | 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /VGAColor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Cosmos.System.Graphics 6 | { 7 | public enum VGAColor 8 | { 9 | Black = 0, 10 | SlateBlue1, 11 | SlateBlue2, 12 | SlateBlue3, 13 | SlateBlue4, 14 | SlateBlue5, 15 | SlateBlue6, 16 | SlateBlue7, 17 | SlateBlue8, 18 | SlateBlue9, 19 | SlateBlue10, 20 | SlateBlue11, 21 | SlateBlue12, 22 | SlateBlue13, 23 | SlateBlue14, 24 | SlateBlue, 25 | Black2, 26 | PaleGreen1, 27 | PaleGreen2, 28 | PaleGreen3, 29 | PaleGreen4, 30 | PaleGreen5, 31 | PaleGreen6, 32 | PaleGreen7, 33 | PaleGreen8, 34 | PaleGreen9, 35 | PaleGreen10, 36 | PaleGreen11, 37 | PaleGreen12, 38 | PaleGreen13, 39 | PaleGreen14, 40 | PaleGreen, 41 | Black3, 42 | Coral1, 43 | Coral2, 44 | Coral3, 45 | Coral4, 46 | Coral5, 47 | Coral6, 48 | Coral7, 49 | Coral8, 50 | Coral9, 51 | Coral10, 52 | Coral11, 53 | Coral12, 54 | Coral13, 55 | Coral14, 56 | Coral, 57 | Black4, 58 | SkyBlue1, 59 | SkyBlue2, 60 | SkyBlue3, 61 | SkyBlue4, 62 | SkyBlue5, 63 | SkyBlue6, 64 | SkyBlue7, 65 | SkyBlue8, 66 | SkyBlue9, 67 | SkyBlue10, 68 | SkyBlue11, 69 | SkyBlue12, 70 | SkyBlue13, 71 | SkyBlue14, 72 | SkyBlue, 73 | Black5, 74 | Purple1, 75 | Purple2, 76 | Purple3, 77 | Purple4, 78 | Purple5, 79 | Purple6, 80 | Purple7, 81 | Purple8, 82 | Purple9, 83 | Purple10, 84 | Purple11, 85 | Purple12, 86 | Purple13, 87 | Purple14, 88 | Purple, 89 | Black6, 90 | Mint1, 91 | Mint2, 92 | Mint3, 93 | Mint4, 94 | Mint5, 95 | Mint6, 96 | Mint7, 97 | Mint8, 98 | Mint9, 99 | Mint10, 100 | Mint11, 101 | Mint12, 102 | Mint13, 103 | Mint14, 104 | Mint, 105 | Black7, 106 | LawnGreen1, 107 | LawnGreen2, 108 | LawnGreen3, 109 | LawnGreen4, 110 | LawnGreen5, 111 | LawnGreen6, 112 | LawnGreen7, 113 | LawnGreen8, 114 | LawnGreen9, 115 | LawnGreen10, 116 | LawnGreen11, 117 | LawnGreen12, 118 | LawnGreen13, 119 | LawnGreen14, 120 | LawnGreen, 121 | Black8, 122 | Pink1, 123 | Pink2, 124 | Pink3, 125 | Pink4, 126 | Pink5, 127 | Pink6, 128 | Pink7, 129 | Pink8, 130 | Pink9, 131 | Pink10, 132 | Pink11, 133 | Pink12, 134 | Pink13, 135 | Pink14, 136 | Pink, 137 | Black9, 138 | Orange1, 139 | Orange2, 140 | Orange3, 141 | Orange4, 142 | Orange5, 143 | Orange6, 144 | Orange7, 145 | Orange8, 146 | Orange9, 147 | Orange10, 148 | Orange11, 149 | Orange12, 150 | Orange13, 151 | Orange14, 152 | Orange, 153 | Black10, 154 | Magenta1, 155 | Magenta2, 156 | Magenta3, 157 | Magenta4, 158 | Magenta5, 159 | Magenta6, 160 | Magenta7, 161 | Magenta8, 162 | Magenta9, 163 | Magenta10, 164 | Magenta11, 165 | Magenta12, 166 | Magenta13, 167 | Magenta14, 168 | Magenta, 169 | Black11, 170 | Cyan1, 171 | Cyan2, 172 | Cyan3, 173 | Cyan4, 174 | Cyan5, 175 | Cyan6, 176 | Cyan7, 177 | Cyan8, 178 | Cyan9, 179 | Cyan10, 180 | Cyan11, 181 | Cyan12, 182 | Cyan13, 183 | Cyan14, 184 | Cyan, 185 | Black12, 186 | Yellow1, 187 | Yellow2, 188 | Yellow3, 189 | Yellow4, 190 | Yellow5, 191 | Yellow6, 192 | Yellow7, 193 | Yellow8, 194 | Yellow9, 195 | Yellow10, 196 | Yellow11, 197 | Yellow12, 198 | Yellow13, 199 | Yellow14, 200 | Yellow, 201 | Black13, 202 | Blue1, 203 | Blue2, 204 | Blue3, 205 | Blue4, 206 | Blue5, 207 | Blue6, 208 | Blue7, 209 | Blue8, 210 | Blue9, 211 | Blue10, 212 | Blue11, 213 | Blue12, 214 | Blue13, 215 | Blue14, 216 | Blue, 217 | Black14, 218 | Green1, 219 | Green2, 220 | Green3, 221 | Green4, 222 | Green5, 223 | Green6, 224 | Green7, 225 | Green8, 226 | Green9, 227 | Green10, 228 | Green11, 229 | Green12, 230 | Green13, 231 | Green14, 232 | Green, 233 | Black15, 234 | Red1, 235 | Red2, 236 | Red3, 237 | Red4, 238 | Red5, 239 | Red6, 240 | Red7, 241 | Red8, 242 | Red9, 243 | Red10, 244 | Red11, 245 | Red12, 246 | Red13, 247 | Red14, 248 | Red, 249 | Black16, 250 | Gray1, 251 | Gray2, 252 | Gray3, 253 | Gray4, 254 | Gray5, 255 | Gray6, 256 | Gray, 257 | Silver1, 258 | Silver2, 259 | Silver3, 260 | Silver4, 261 | Silver5, 262 | Silver6, 263 | Silver, 264 | White, 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /VGADriverII.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Cosmos.Core; 5 | using Cosmos.System.Graphics; 6 | 7 | namespace Cosmos.HAL 8 | { 9 | // vga mode identifiers 10 | public enum VGAMode 11 | { 12 | Text80x25, 13 | Text80x50, 14 | Text90x60, 15 | Pixel320x200, 16 | Pixel320x200DB, 17 | } 18 | 19 | // vga mode register dumps 20 | public static class VGAModeRegisters 21 | { 22 | // text 80x25 23 | public static byte[] Mode80x25_Text = new byte[] 24 | { 25 | /* MISC */ 26 | 0x67, 27 | /* SEQ */ 28 | 0x03, 0x00, 0x03, 0x00, 0x02, 29 | /* CRTC */ 30 | 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 31 | 0x00, 0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0x50, 32 | 0x9C, 0x0E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3, 33 | 0xFF, 34 | /* GC */ 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 36 | 0xFF, 37 | /* AC */ 38 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 39 | 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 40 | 0x0C, 0x00, 0x0F, 0x08, 0x00 41 | }; 42 | 43 | // text 80x50 44 | public static byte[] Mode80x50_Text = new byte[] 45 | { 46 | /* MISC */ 47 | 0x67, 48 | /* SEQ */ 49 | 0x03, 0x00, 0x03, 0x00, 0x02, 50 | /* CRTC */ 51 | 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 52 | 0x00, 0x47, 0x06, 0x07, 0x00, 0x00, 0x01, 0x40, 53 | 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3, 54 | 0xFF, 55 | /* GC */ 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 57 | 0xFF, 58 | /* AC */ 59 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 60 | 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 61 | 0x0C, 0x00, 0x0F, 0x08, 0x00, 62 | }; 63 | 64 | // text 90x60 65 | public static byte[] Mode90x60_Text = new byte[] 66 | { 67 | /* MISC */ 68 | 0xE7, 69 | /* SEQ */ 70 | 0x03, 0x01, 0x03, 0x00, 0x02, 71 | /* CRTC */ 72 | 0x6B, 0x59, 0x5A, 0x82, 0x60, 0x8D, 0x0B, 0x3E, 73 | 0x00, 0x47, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 74 | 0xEA, 0x0C, 0xDF, 0x2D, 0x08, 0xE8, 0x05, 0xA3, 75 | 0xFF, 76 | /* GC */ 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 78 | 0xFF, 79 | /* AC */ 80 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 81 | 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 82 | 0x0C, 0x00, 0x0F, 0x08, 0x00, 83 | }; 84 | 85 | // pixel 320x200x256 86 | public static byte[] Mode320x200x256_Pixel = new byte[] 87 | { 88 | /* MISC */ 89 | 0x63, 90 | /* SEQ */ 91 | 0x03, 0x01, 0x0F, 0x00, 0x0E, 92 | /* CRTC */ 93 | 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 94 | 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 | 0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3, 96 | 0xFF, 97 | /* GC */ 98 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 99 | 0xFF, 100 | /* AC */ 101 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 102 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 103 | 0x41, 0x00, 0x0F, 0x00, 0x00 104 | }; 105 | } 106 | 107 | // vga controller class 108 | public static unsafe class VGADriverII 109 | { 110 | // data ports 111 | private static readonly IOPort PORT_SEQ_DATA = new IOPort(0x3C5); 112 | private static readonly IOPort PORT_GC_DATA = new IOPort(0x3CF); 113 | private static readonly IOPort PORT_CRTC_DATA = new IOPort(0x3D5); 114 | private static readonly IOPort PORT_MASK_DATA = new IOPort(0x3DA); 115 | private static readonly IOPort PORT_DAC_DATA = new IOPort(0x3C9); 116 | 117 | // write ports 118 | private static readonly IOPortWrite PORT_AC_WRITE = new IOPortWrite(0x3C0); 119 | private static readonly IOPortWrite PORT_MISC_WRITE = new IOPortWrite(0x3C2); 120 | private static readonly IOPortWrite PORT_SEQ_WRITE = new IOPortWrite(0x3C4); 121 | private static readonly IOPortWrite PORT_DAC_WRITE = new IOPortWrite(0x3C8); 122 | private static readonly IOPortWrite PORT_GC_WRITE = new IOPortWrite(0x3CE); 123 | private static readonly IOPortWrite PORT_CRTC_WRITE = new IOPortWrite(0x3D4); 124 | 125 | // read ports 126 | private static readonly IOPortRead PORT_AC_READ = new IOPortRead(0x3C1); 127 | private static readonly IOPortRead PORT_DAC_READ = new IOPortRead(0x3C7); 128 | private static readonly IOPortRead PORT_INSTAT_READ = new IOPortRead(0x3DA); 129 | 130 | // mode properties 131 | public static ushort Width { get; private set; } 132 | public static ushort Height { get; private set; } 133 | public static byte Depth { get; private set; } 134 | public static bool IsTextMode { get; private set; } 135 | public static bool IsDoubleBuffered { get; private set; } 136 | public static VGAMode ModeID { get; private set; } 137 | 138 | // buffer 139 | public static byte* Buffer; 140 | private static MemoryBlock BackBuffer = new MemoryBlock(0x60000, 0x10000); 141 | 142 | // color palette - 8 bit 143 | public static uint[] Palette256 = new uint[256] 144 | { 145 | 0x000000, 0x010103, 0x030306, 0x040409, 0x06060C, 0x07070F, 0x090913, 0x0B0B16, 0x0C0C19, 0x0E0E1C, 0x0F0F1F, 0x111123, 0x131326, 0x141429, 0x16162C, 0x17172F, 146 | 0x000000, 0x010301, 0x030603, 0x040904, 0x060C06, 0x070F07, 0x091309, 0x0B160B, 0x0C190C, 0x0E1C0E, 0x0F1F0F, 0x112311, 0x132613, 0x142914, 0x162C16, 0x172F17, 147 | 0x000000, 0x030101, 0x060303, 0x090404, 0x0C0606, 0x0F0707, 0x130909, 0x160B0B, 0x190C0C, 0x1C0E0E, 0x1F0F0F, 0x231111, 0x261313, 0x291414, 0x2C1616, 0x2F1717, 148 | 0x000000, 0x000103, 0x000306, 0x000409, 0x00060C, 0x00070F, 0x000913, 0x000B16, 0x000C19, 0x000E1C, 0x000F1F, 0x001123, 0x001326, 0x001429, 0x00162C, 0x00172F, 149 | 0x000000, 0x010003, 0x030006, 0x040009, 0x06000C, 0x07000F, 0x090013, 0x0B0016, 0x0C0019, 0x0E001C, 0x0F001F, 0x110023, 0x130026, 0x140029, 0x16002C, 0x17002F, 150 | 0x000000, 0x000301, 0x000603, 0x000904, 0x000C06, 0x000F07, 0x001309, 0x00160B, 0x00190C, 0x001C0E, 0x001F0F, 0x002311, 0x002613, 0x002914, 0x002C16, 0x002F17, 151 | 0x000000, 0x010300, 0x030600, 0x040900, 0x060C00, 0x070F00, 0x091300, 0x0B1600, 0x0C1900, 0x0E1C00, 0x0F1F00, 0x112300, 0x132600, 0x142900, 0x162C00, 0x172F00, 152 | 0x000000, 0x030001, 0x060003, 0x090004, 0x0C0006, 0x0F0007, 0x130009, 0x16000B, 0x19000C, 0x1C000E, 0x1F000F, 0x230011, 0x260013, 0x290014, 0x2C0016, 0x2F0017, 153 | 0x000000, 0x030100, 0x060300, 0x090400, 0x0C0600, 0x0F0700, 0x130900, 0x160B00, 0x190C00, 0x1C0E00, 0x1F0F00, 0x231100, 0x261300, 0x291400, 0x2C1600, 0x2F1700, 154 | 0x000000, 0x030003, 0x060006, 0x090009, 0x0C000C, 0x0F000F, 0x130013, 0x160016, 0x190019, 0x1C001C, 0x1F001F, 0x230023, 0x260026, 0x290029, 0x2C002C, 0x2F002F, 155 | 0x000000, 0x000303, 0x000606, 0x000909, 0x000C0C, 0x000F0F, 0x001313, 0x001616, 0x001919, 0x001C1C, 0x001F1F, 0x002323, 0x002626, 0x002929, 0x002C2C, 0x002F2F, 156 | 0x000000, 0x030300, 0x060600, 0x090900, 0x0C0C00, 0x0F0F00, 0x131300, 0x161600, 0x191900, 0x1C1C00, 0x1F1F00, 0x232300, 0x262600, 0x292900, 0x2C2C00, 0x2F2F00, 157 | 0x000000, 0x000003, 0x000006, 0x000009, 0x00000C, 0x00000F, 0x000013, 0x000016, 0x000019, 0x00001C, 0x00001F, 0x000023, 0x000026, 0x000029, 0x00002C, 0x00002F, 158 | 0x000000, 0x000300, 0x000600, 0x000900, 0x000C00, 0x000F00, 0x001300, 0x001600, 0x001900, 0x001C00, 0x001F00, 0x002300, 0x002600, 0x002900, 0x002C00, 0x002F00, 159 | 0x000000, 0x030000, 0x060000, 0x090000, 0x0C0000, 0x0F0000, 0x130000, 0x160000, 0x190000, 0x1C0000, 0x1F0000, 0x230000, 0x260000, 0x290000, 0x2C0000, 0x2F0000, 160 | 0x000000, 0x030303, 0x060606, 0x090909, 0x0C0C0C, 0x0F0F0F, 0x131313, 0x161616, 0x191919, 0x1C1C1C, 0x1F1F1F, 0x232323, 0x262626, 0x292929, 0x2C2C2C, 0x2F2F2F, 161 | }; 162 | 163 | // color palette - 4 bit 164 | public static uint[] Palette16 = new uint[16] 165 | { 0x000000, 0x00001F, 0x001F00, 0x001F1F, 0x1F0000, 0x1F001F, 0x2F1F00, 0x2F2F2F, 0x1F1F1F, 0x00103F, 0x003F00, 0x003F3F, 0x3F0000, 0x3F003F, 0x3F3F00, 0x3F3F3F, }; 166 | 167 | // initialization 168 | public static void Initialize(VGAMode mode) 169 | { 170 | SetMode(mode); 171 | } 172 | 173 | #region Graphics Handling 174 | 175 | // clear screen 176 | public static void Clear(byte color) 177 | { 178 | uint i = 0; 179 | // text mode 180 | if (IsTextMode) { for (i = 0; i < (Width * Height) * 2; i += 2) { Buffer[i] = 0x20; Buffer[i + 1] = color; } } 181 | // graphics mode 182 | else if (!IsTextMode && !IsDoubleBuffered) { for (i = 0; i < Width * Height; i++) { Buffer[i] = color; } } 183 | // double buffered graphics mode 184 | else if (!IsTextMode && IsDoubleBuffered) { BackBuffer.Fill(color); } 185 | } 186 | 187 | // draw pixel 188 | public static void DrawPixel(ushort x, ushort y, byte color) 189 | { 190 | if (x >= Width || y >= Height) { return; } 191 | if (IsTextMode) { return; } 192 | uint offset = (uint)(x + (y * Width)); 193 | 194 | // double buffered 195 | if (IsDoubleBuffered) { BackBuffer.Bytes[offset] = color; } 196 | // direct 197 | else { Buffer[offset] = color; } 198 | } 199 | 200 | // swap back buffer 201 | public static void Display() 202 | { 203 | // check mode 204 | if (ModeID != VGAMode.Pixel320x200DB) { return; } 205 | 206 | byte* src = (byte*)BackBuffer.Base; 207 | 208 | for (uint i = 0; i < Width * Height; i++) 209 | { 210 | if (*(Buffer + i) != *(src + i)) 211 | { 212 | *(Buffer + i) = *(src + i); 213 | } 214 | } 215 | } 216 | 217 | // set text-mode cursor position 218 | public static void SetCursorPos(ushort x, ushort y) 219 | { 220 | if (!IsTextMode) { return; } 221 | uint offset = (uint)(x + (y * Width)); 222 | PORT_CRTC_WRITE.Byte = 14; 223 | PORT_CRTC_DATA.Byte = (byte)((offset & 0xFF00) >> 8); 224 | PORT_CRTC_WRITE.Byte = 15; 225 | PORT_CRTC_DATA.Byte = (byte)(offset & 0x00FF); 226 | } 227 | 228 | // enable cursor 229 | public static void EnableCursor(byte start, byte end) 230 | { 231 | PORT_CRTC_WRITE.Byte = 0x0A; 232 | PORT_CRTC_DATA.Byte = (byte)((PORT_CRTC_DATA.Byte & 0xC0) | start); 233 | PORT_CRTC_WRITE.Byte = 0x0B; 234 | PORT_CRTC_DATA.Byte = (byte)((PORT_CRTC_DATA.Byte & 0xE0) | end); 235 | } 236 | 237 | // disable cursor 238 | public static void DisableCursor() 239 | { 240 | PORT_CRTC_WRITE.Byte = 0x0A; 241 | PORT_CRTC_DATA.Byte = 0x20; 242 | } 243 | 244 | #endregion 245 | 246 | #region Hardware Control 247 | 248 | // set current video mode properties 249 | private static void SetModeProperties(ushort w, ushort h, byte depth, bool text, bool db) 250 | { 251 | Width = w; Height = h; Depth = depth; 252 | IsTextMode = text; 253 | IsDoubleBuffered = db; 254 | } 255 | 256 | // set current video mode 257 | public static void SetMode(VGAMode mode) 258 | { 259 | // set mode id 260 | ModeID = mode; 261 | 262 | // set mode 263 | switch (mode) 264 | { 265 | // 80x25 text mode 266 | case VGAMode.Text80x25: 267 | { 268 | SetModeProperties(80, 25, 4, true, false); 269 | fixed (byte* ptr = VGAModeRegisters.Mode80x25_Text) { WriteRegisters(ptr); } 270 | SetFont(VGAFontData.Font8x16_Data, 16); 271 | SetColorPalette(Palette16); 272 | break; 273 | } 274 | // 80x50 text mode 275 | case VGAMode.Text80x50: 276 | { 277 | SetModeProperties(80, 50, 4, true, false); 278 | fixed (byte* ptr = VGAModeRegisters.Mode80x50_Text) { WriteRegisters(ptr); } 279 | SetFont(VGAFontData.Font8x8_Data, 8); 280 | SetColorPalette(Palette16); 281 | break; 282 | } 283 | // 90x60 text mode 284 | case VGAMode.Text90x60: 285 | { 286 | SetModeProperties(90, 60, 4, true, false); 287 | fixed (byte* ptr = VGAModeRegisters.Mode90x60_Text) { WriteRegisters(ptr); } 288 | SetFont(VGAFontData.Font8x8_Data, 8); 289 | SetColorPalette(Palette16); 290 | break; 291 | } 292 | // 320x200 graphics mode 293 | case VGAMode.Pixel320x200: 294 | { 295 | SetModeProperties(320, 200, 8, false, false); 296 | fixed (byte* ptr = VGAModeRegisters.Mode320x200x256_Pixel) { WriteRegisters(ptr); } 297 | ClearColorPalette(); 298 | SetColorPalette(Palette256); 299 | break; 300 | } 301 | // 320x200 double buffered graphics mode 302 | case VGAMode.Pixel320x200DB: 303 | { 304 | SetModeProperties(320, 200, 8, false, true); 305 | fixed (byte* ptr = VGAModeRegisters.Mode320x200x256_Pixel) { WriteRegisters(ptr); } 306 | ClearColorPalette(); 307 | SetColorPalette(Palette256); 308 | break; 309 | } 310 | // default to 80x25 text mode 311 | default: { break; } 312 | } 313 | 314 | // clear the screen 315 | Clear(0); 316 | } 317 | 318 | // get frame buffer segment 319 | private static byte* GetFrameBufferSegment() 320 | { 321 | PORT_GC_WRITE.Byte = 0x06; 322 | byte segNum = (byte)(PORT_GC_DATA.Byte & (3 << 2)); 323 | switch (segNum) 324 | { 325 | default: 326 | case 0 << 2: return (byte*)0x00000; 327 | case 1 << 2: return (byte*)0xA0000; 328 | case 2 << 2: return (byte*)0xB0000; 329 | case 3 << 2: return (byte*)0xB8000; 330 | } 331 | } 332 | 333 | // write data to vga registers 334 | private static void WriteRegisters(byte* regs) 335 | { 336 | // misc 337 | PORT_MISC_WRITE.Byte = *(regs++); 338 | 339 | // sequencer 340 | for (byte i = 0; i < 5; i++) { PORT_SEQ_WRITE.Byte = i; PORT_SEQ_DATA.Byte = *(regs++); } 341 | 342 | // crtc 343 | PORT_CRTC_WRITE.Byte = 0x03; 344 | PORT_CRTC_DATA.Byte = (byte)(PORT_CRTC_DATA.Byte | 0x80); 345 | PORT_CRTC_WRITE.Byte = 0x11; 346 | PORT_CRTC_DATA.Byte = (byte)(PORT_CRTC_DATA.Byte | ~0x80); 347 | 348 | // registers 349 | regs[0x03] = (byte)(regs[0x03] | 0x80); 350 | regs[0x11] = (byte)(regs[0x11] & ~0x80); 351 | for (byte i = 0; i < 25; i++) { PORT_CRTC_WRITE.Byte = i; PORT_CRTC_DATA.Byte = *(regs++); } 352 | 353 | // graphics controller 354 | for (byte i = 0; i < 9; i++) { PORT_GC_WRITE.Byte = i; PORT_GC_DATA.Byte = *(regs++); } 355 | 356 | // attribute controller 357 | byte val = 0; 358 | for (byte i = 0; i < 21; i++) 359 | { 360 | val = PORT_INSTAT_READ.Byte; 361 | PORT_AC_WRITE.Byte = i; 362 | PORT_AC_WRITE.Byte = *(regs++); 363 | } 364 | 365 | val = PORT_INSTAT_READ.Byte; 366 | PORT_AC_WRITE.Byte = 0x20; 367 | 368 | 369 | // set buffer address 370 | Buffer = GetFrameBufferSegment(); 371 | } 372 | 373 | // set plane data 374 | private static void SetPlane(byte ap) 375 | { 376 | // calculate 377 | byte pmask; 378 | ap &= 3; 379 | pmask = (byte)(1 << ap); 380 | 381 | // set read plane 382 | PORT_GC_WRITE.Byte = 4; 383 | PORT_GC_DATA.Byte = ap; 384 | 385 | // set write plane 386 | PORT_SEQ_WRITE.Byte = 2; 387 | PORT_SEQ_DATA.Byte = pmask; 388 | } 389 | 390 | // set font 391 | private static void SetFont(byte[] font, byte height) 392 | { 393 | byte seq2, seq4, gc4, gc5, gc6; 394 | 395 | // sequencer 396 | PORT_SEQ_WRITE.Byte = 2; 397 | seq2 = PORT_SEQ_DATA.Byte; 398 | PORT_SEQ_WRITE.Byte = 4; 399 | seq4 = PORT_SEQ_DATA.Byte; 400 | PORT_SEQ_DATA.Byte = (byte)(seq4 | 0x04); 401 | 402 | // gc 403 | PORT_GC_WRITE.Byte = 4; 404 | gc4 = PORT_GC_DATA.Byte; 405 | PORT_GC_WRITE.Byte = 5; 406 | gc5 = PORT_GC_DATA.Byte; 407 | PORT_GC_DATA.Byte = (byte)(gc5 & ~0x10); 408 | PORT_GC_WRITE.Byte = 6; 409 | gc6 = PORT_GC_DATA.Byte; 410 | PORT_GC_DATA.Byte = (byte)(gc6 & ~0x02); 411 | 412 | // write font to plane 4 413 | SetPlane(2); 414 | 415 | // write font 416 | byte* seg = GetFrameBufferSegment(); 417 | for (uint i = 0; i < 256; i++) 418 | { for (uint j = 0; j < height; j++) { seg[(i * 32) + j] = font[(i * height) + j]; } } 419 | 420 | // restore registers 421 | PORT_SEQ_WRITE.Byte = 2; 422 | PORT_SEQ_DATA.Byte = seq2; 423 | PORT_SEQ_WRITE.Byte = 4; 424 | PORT_SEQ_DATA.Byte = seq4; 425 | PORT_GC_WRITE.Byte = 4; 426 | PORT_GC_DATA.Byte = gc4; 427 | PORT_GC_WRITE.Byte = 5; 428 | PORT_GC_DATA.Byte = gc5; 429 | PORT_GC_WRITE.Byte = 6; 430 | PORT_GC_DATA.Byte = gc6; 431 | } 432 | 433 | // set color palette 434 | public static void SetColorPalette(uint[] colors) 435 | { 436 | for (uint i = 0; i < colors.Length; i++) 437 | { 438 | if (!IsTextMode) { PORT_MASK_DATA.Byte = 0xFF; } else { PORT_MASK_DATA.Byte = 0x0F; } 439 | PORT_DAC_WRITE.Byte = (byte)i; 440 | PORT_DAC_DATA.Byte = (byte)((colors[i] & 0xFF0000) >> 16); 441 | PORT_DAC_DATA.Byte = (byte)((colors[i] & 0x00FF00) >> 8); 442 | PORT_DAC_DATA.Byte = (byte)(colors[i] & 0x0000FF); 443 | } 444 | } 445 | 446 | // clear color palette 447 | private static void ClearColorPalette() 448 | { 449 | for (uint i = 0; i < 256; i++) 450 | { 451 | if (!IsTextMode) { PORT_MASK_DATA.Byte = 0xFF; } else { PORT_MASK_DATA.Byte = 0x0F; } 452 | PORT_DAC_WRITE.Byte = (byte)i; 453 | PORT_DAC_DATA.Byte = 0; 454 | PORT_DAC_DATA.Byte = 0; 455 | PORT_DAC_DATA.Byte = 0; 456 | } 457 | } 458 | 459 | #endregion 460 | } 461 | } 462 | -------------------------------------------------------------------------------- /VGAFont.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Cosmos.System.Graphics 6 | { 7 | public enum VGAFont 8 | { 9 | Font3x5, 10 | Font8x8, 11 | Font8x16, 12 | } 13 | 14 | public static class VGAFontData 15 | { 16 | 17 | // convert byte to bit address 18 | public static bool ConvertByteToBitAddress(byte toConvert, int toReturn) 19 | { 20 | int mask = 1 << (toReturn - 1); 21 | return (toConvert & mask) != 0; 22 | } 23 | 24 | // 3x5 font data 25 | public static readonly byte[] Font3x5_Data = new byte[] 26 | { 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, // space 60 | 0x02, 0x02, 0x02, 0x00, 0x02, // ! 61 | 0x05, 0x05, 0x00, 0x00, 0x00, // " 62 | 0x05, 0x07, 0x05, 0x07, 0x05, // # 63 | 0x03, 0x06, 0x03, 0x06, 0x02, // $ 64 | 0x04, 0x01, 0x02, 0x04, 0x01, // % 65 | 0x06, 0x06, 0x07, 0x05, 0x03, // & 66 | 0x02, 0x02, 0x00, 0x00, 0x00, // ' 67 | 0x01, 0x02, 0x02, 0x02, 0x01, // ( 68 | 0x04, 0x02, 0x02, 0x02, 0x04, // ) 69 | 0x05, 0x02, 0x05, 0x00, 0x00, // * 70 | 0x00, 0x02, 0x07, 0x02, 0x00, // + 71 | 0x00, 0x00, 0x00, 0x01, 0x02, // , 72 | 0x00, 0x00, 0x07, 0x00, 0x00, // - 73 | 0x00, 0x00, 0x00, 0x00, 0x02, // . 74 | 0x01, 0x01, 0x02, 0x04, 0x04, // / 75 | 0x03, 0x05, 0x05, 0x05, 0x06, // 0 76 | 0x02, 0x06, 0x02, 0x02, 0x02, // 1 77 | 0x06, 0x01, 0x02, 0x04, 0x07, // 2 78 | 0x06, 0x01, 0x02, 0x01, 0x06, // 3 79 | 0x05, 0x05, 0x07, 0x01, 0x01, // 4 80 | 0x07, 0x04, 0x06, 0x01, 0x06, // 5 81 | 0x03, 0x04, 0x07, 0x05, 0x07, // 6 82 | 0x07, 0x01, 0x02, 0x04, 0x04, // 7 83 | 0x07, 0x05, 0x07, 0x05, 0x07, // 8 84 | 0x07, 0x05, 0x07, 0x01, 0x06, // 9 85 | 0x00, 0x02, 0x00, 0x02, 0x00, // : 86 | 0x00, 0x02, 0x00, 0x02, 0x04, // ; 87 | 0x01, 0x02, 0x04, 0x02, 0x01, // < 88 | 0x00, 0x07, 0x00, 0x07, 0x00, // = 89 | 0x04, 0x02, 0x01, 0x02, 0x04, // > 90 | 0x07, 0x01, 0x02, 0x00, 0x02, // ? 91 | 0x02, 0x05, 0x07, 0x04, 0x03, // @ 92 | 0x02, 0x05, 0x07, 0x05, 0x05, // A 93 | 0x06, 0x05, 0x06, 0x05, 0x06, // B 94 | 0x03, 0x04, 0x04, 0x04, 0x03, // C 95 | 0x06, 0x05, 0x05, 0x05, 0x06, // D 96 | 0x07, 0x04, 0x07, 0x04, 0x07, // E 97 | 0x07, 0x04, 0x07, 0x04, 0x04, // F 98 | 0x03, 0x04, 0x07, 0x05, 0x03, // G 99 | 0x05, 0x05, 0x07, 0x05, 0x05, // H 100 | 0x07, 0x02, 0x02, 0x02, 0x07, // I 101 | 0x01, 0x01, 0x01, 0x05, 0x02, // J 102 | 0x05, 0x05, 0x06, 0x05, 0x05, // K 103 | 0x04, 0x04, 0x04, 0x04, 0x07, // L 104 | 0x05, 0x07, 0x07, 0x05, 0x05, // M 105 | 0x05, 0x07, 0x07, 0x07, 0x05, // N 106 | 0x02, 0x05, 0x05, 0x05, 0x02, // O 107 | 0x06, 0x05, 0x06, 0x04, 0x04, // P 108 | 0x02, 0x05, 0x05, 0x07, 0x03, // Q 109 | 0x06, 0x05, 0x07, 0x06, 0x05, // R 110 | 0x03, 0x04, 0x02, 0x01, 0x06, // S 111 | 0x07, 0x02, 0x02, 0x02, 0x02, // T 112 | 0x05, 0x05, 0x05, 0x05, 0x03, // U 113 | 0x05, 0x05, 0x05, 0x02, 0x02, // V 114 | 0x05, 0x05, 0x07, 0x07, 0x05, // W 115 | 0x05, 0x05, 0x02, 0x05, 0x05, // X 116 | 0x05, 0x05, 0x02, 0x02, 0x02, // Y 117 | 0x07, 0x01, 0x02, 0x04, 0x07, // Z 118 | 0x07, 0x04, 0x04, 0x04, 0x07, // [ 119 | 0x00, 0x04, 0x02, 0x01, 0x00, // \ 120 | 0x07, 0x01, 0x01, 0x01, 0x07, // ] 121 | 0x02, 0x05, 0x00, 0x00, 0x00, // ^ 122 | 0x00, 0x00, 0x00, 0x00, 0x07, // _ 123 | 0x04, 0x02, 0x00, 0x00, 0x00, // ` 124 | 0x00, 0x07, 0x03, 0x05, 0x07, // a 125 | 0x04, 0x06, 0x05, 0x05, 0x06, // b 126 | 0x00, 0x03, 0x04, 0x04, 0x03, // c 127 | 0x01, 0x03, 0x05, 0x05, 0x03, // d 128 | 0x00, 0x03, 0x05, 0x06, 0x03, // e 129 | 0x01, 0x02, 0x07, 0x02, 0x02, // f 130 | 0x03, 0x05, 0x07, 0x01, 0x02, // g 131 | 0x04, 0x06, 0x05, 0x05, 0x05, // h 132 | 0x02, 0x00, 0x02, 0x02, 0x02, // i 133 | 0x01, 0x00, 0x01, 0x05, 0x02, // j 134 | 0x04, 0x05, 0x06, 0x06, 0x05, // k 135 | 0x06, 0x02, 0x02, 0x02, 0x07, // l 136 | 0x00, 0x07, 0x07, 0x07, 0x05, // m 137 | 0x00, 0x06, 0x05, 0x05, 0x05, // n 138 | 0x00, 0x02, 0x05, 0x05, 0x02, // o 139 | 0x00, 0x06, 0x06, 0x04, 0x04, // p 140 | 0x00, 0x03, 0x03, 0x01, 0x01, // q 141 | 0x00, 0x03, 0x04, 0x04, 0x04, // r 142 | 0x00, 0x03, 0x06, 0x03, 0x06, // s 143 | 0x02, 0x07, 0x02, 0x02, 0x03, // t 144 | 0x00, 0x05, 0x05, 0x05, 0x03, // u 145 | 0x00, 0x05, 0x05, 0x07, 0x02, // v 146 | 0x00, 0x05, 0x07, 0x07, 0x07, // w 147 | 0x00, 0x05, 0x02, 0x02, 0x05, // x 148 | 0x00, 0x05, 0x07, 0x01, 0x02, // y 149 | 0x00, 0x07, 0x03, 0x06, 0x07, // z 150 | 0x03, 0x02, 0x04, 0x02, 0x03, // { 151 | 0x02, 0x02, 0x02, 0x02, 0x02, // | 152 | 0x06, 0x02, 0x01, 0x02, 0x06, // } 153 | 0x03, 0x06, 0x00, 0x00, 0x00, // ~ 154 | }; 155 | 156 | // font memory blocks 157 | public static readonly byte[] Font8x8_Data = new byte[2048] 158 | { 159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 160 | 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, 161 | 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 162 | 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 163 | 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 164 | 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, 165 | 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, 166 | 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 167 | 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 168 | 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 169 | 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 170 | 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, 171 | 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 172 | 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, 173 | 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, 174 | 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, 175 | 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 176 | 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, 177 | 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, 178 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, 179 | 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, 180 | 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, 181 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 182 | 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, 183 | 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 184 | 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 185 | 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 186 | 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 187 | 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 188 | 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 189 | 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, 190 | 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, 191 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 192 | 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, 193 | 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 194 | 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 195 | 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, 196 | 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, 197 | 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, 198 | 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 199 | 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 200 | 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 201 | 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 202 | 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 203 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 204 | 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 206 | 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 207 | 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, 208 | 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, 209 | 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, 210 | 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, 211 | 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 212 | 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, 213 | 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, 214 | 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, 215 | 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, 216 | 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, 217 | 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 218 | 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, 219 | 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 220 | 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 221 | 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 222 | 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, 223 | 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, 224 | 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, 225 | 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 226 | 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, 227 | 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 228 | 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 229 | 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 230 | 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, 231 | 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, 232 | 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 233 | 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 234 | 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 235 | 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 236 | 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 237 | 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 238 | 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 239 | 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 240 | 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, 241 | 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 242 | 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, 243 | 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 244 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, 245 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 246 | 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, 247 | 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 248 | 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, 249 | 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 250 | 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 251 | 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 252 | 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 253 | 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 254 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 255 | 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 256 | 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 257 | 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, 258 | 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, 259 | 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 260 | 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 261 | 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, 262 | 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 263 | 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 264 | 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 265 | 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 266 | 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, 267 | 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 268 | 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, 269 | 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 270 | 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 271 | 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 272 | 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, 273 | 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, 274 | 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, 275 | 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, 276 | 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 277 | 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 278 | 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, 279 | 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 280 | 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 281 | 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 282 | 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, 283 | 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 284 | 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, 285 | 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 286 | 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 287 | 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, 288 | 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 289 | 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 290 | 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, 291 | 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 292 | 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 293 | 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 294 | 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, 295 | 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 296 | 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 297 | 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 298 | 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 299 | 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 300 | 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 301 | 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 302 | 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, 303 | 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, 304 | 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, 305 | 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, 306 | 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 307 | 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 308 | 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 309 | 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 310 | 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 311 | 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 312 | 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, 313 | 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 314 | 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, 315 | 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, 316 | 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, 317 | 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, 318 | 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, 319 | 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 320 | 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 321 | 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 322 | 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 323 | 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, 324 | 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, 325 | 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 326 | 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 327 | 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, 328 | 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, 329 | 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 330 | 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, 331 | 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, 332 | 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 333 | 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, 334 | 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, 335 | 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 336 | 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 337 | 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 338 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 339 | 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 340 | 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 341 | 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 342 | 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 343 | 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 344 | 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 345 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 346 | 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 347 | 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 348 | 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 349 | 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 350 | 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 351 | 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 352 | 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 353 | 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 354 | 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 355 | 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 356 | 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 357 | 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 358 | 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 359 | 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 360 | 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 361 | 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 362 | 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 363 | 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 364 | 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 365 | 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 366 | 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 367 | 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 368 | 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 369 | 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 370 | 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 371 | 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 372 | 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 373 | 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 374 | 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 375 | 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 376 | 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 377 | 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 378 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 379 | 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 380 | 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 381 | 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 382 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 383 | 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, 384 | 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, 385 | 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 386 | 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 387 | 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, 388 | 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 389 | 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 390 | 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, 391 | 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 392 | 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, 393 | 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 394 | 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, 395 | 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 396 | 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, 397 | 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, 398 | 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 399 | 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 400 | 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, 401 | 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 402 | 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, 403 | 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 404 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 405 | 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 406 | 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 407 | 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 408 | 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 409 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 410 | 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 411 | 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 412 | 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, 413 | 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 414 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 415 | }; 416 | 417 | public static readonly byte[] Font8x16_Data = new byte[4096] 418 | { 419 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 420 | 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 421 | 0x00, 0x00, 0x7c, 0xfe, 0xfe, 0xd6, 0xfe, 0xfe, 0xba, 0xc6, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00, 422 | 0x00, 0x00, 0x00, 0x6c, 0xee, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 423 | 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 424 | 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x10, 0x6c, 0xee, 0x6c, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 425 | 0x00, 0x00, 0x10, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0xfe, 0x6c, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 426 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 427 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 428 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 429 | 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0x99, 0x99, 0x99, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 430 | 0x00, 0x00, 0x1e, 0x0e, 0x1e, 0x36, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 431 | 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 432 | 0x00, 0x00, 0x1e, 0x1a, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x78, 0xf8, 0x70, 0x00, 0x00, 0x00, 0x00, 433 | 0x00, 0x00, 0x3e, 0x36, 0x3e, 0x36, 0x36, 0x76, 0xf6, 0x66, 0x0e, 0x1e, 0x0c, 0x00, 0x00, 0x00, 434 | 0x00, 0x00, 0x18, 0xdb, 0x7e, 0x3c, 0x66, 0x66, 0x3c, 0x7e, 0xdb, 0x18, 0x00, 0x00, 0x00, 0x00, 435 | 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf0, 0xfc, 0xfe, 0xfc, 0xf0, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 436 | 0x00, 0x00, 0x00, 0x02, 0x0e, 0x3e, 0x7e, 0xfe, 0x7e, 0x3e, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 437 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 438 | 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 439 | 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 440 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x7c, 0xf6, 0xde, 0x7c, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 441 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 442 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 443 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 444 | 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 445 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0e, 0xff, 0x0e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 446 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0xfe, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 447 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 448 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 449 | 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 450 | 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 451 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 452 | 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 453 | 0x00, 0x36, 0x36, 0x36, 0x36, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 454 | 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 455 | 0x00, 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0x78, 0x3c, 0x06, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 456 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00, 0x00, 457 | 0x00, 0x00, 0x38, 0x6c, 0x38, 0x30, 0x76, 0x7e, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 458 | 0x00, 0x0c, 0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 459 | 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 460 | 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 461 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 462 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 463 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 464 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 465 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 466 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 467 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 468 | 0x00, 0x00, 0x18, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 469 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 470 | 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 471 | 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 472 | 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 473 | 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 474 | 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 475 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 476 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 477 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 478 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 479 | 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 480 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 481 | 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 482 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 483 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 484 | 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 485 | 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, 486 | 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 487 | 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 488 | 0x00, 0x00, 0xfe, 0x66, 0x60, 0x64, 0x7c, 0x64, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 489 | 0x00, 0x00, 0xfe, 0x66, 0x60, 0x64, 0x7c, 0x64, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 490 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xce, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 491 | 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 492 | 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 493 | 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 494 | 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 495 | 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 496 | 0x00, 0x00, 0xc6, 0xc6, 0xee, 0xee, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 497 | 0x00, 0x00, 0xc6, 0xc6, 0xe6, 0xe6, 0xf6, 0xde, 0xce, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 498 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 499 | 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 500 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0x7c, 0x06, 0x00, 0x00, 0x00, 501 | 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 502 | 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0x70, 0x1c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 503 | 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 504 | 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 505 | 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 506 | 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 507 | 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 508 | 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 509 | 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 510 | 0x00, 0x00, 0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x00, 0x00, 0x00, 0x00, 511 | 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 512 | 0x00, 0x00, 0x7c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7c, 0x00, 0x00, 0x00, 0x00, 513 | 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 514 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 515 | 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 516 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 517 | 0x00, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, 518 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 519 | 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00, 520 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 521 | 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 522 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xce, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 523 | 0x00, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 524 | 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 525 | 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 526 | 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 527 | 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x00, 0x00, 0x00, 0x00, 528 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 529 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 530 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 531 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 532 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 533 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 534 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x7c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 535 | 0x00, 0x00, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 536 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 537 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 538 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 539 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 540 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x06, 0xc6, 0x7c, 0x00, 0x00, 541 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x86, 0x0c, 0x18, 0x30, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00, 542 | 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, 543 | 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 544 | 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 545 | 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 546 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 547 | 0x00, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0xc6, 0x66, 0x3c, 0x18, 0x0c, 0xcc, 0x38, 0x00, 0x00, 548 | 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, 0x00, 549 | 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 550 | 0x00, 0x30, 0x78, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 551 | 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 552 | 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 553 | 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 554 | 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x6c, 0x38, 0x00, 0x00, 555 | 0x00, 0x30, 0x78, 0xcc, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 556 | 0x00, 0x00, 0xcc, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 557 | 0x00, 0x30, 0x18, 0x0c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 558 | 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 559 | 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 560 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 561 | 0x00, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 562 | 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 563 | 0x0c, 0x18, 0x30, 0x00, 0xfe, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x00, 564 | 0x00, 0x00, 0x00, 0x00, 0x66, 0xdb, 0x1b, 0x7f, 0xd8, 0xd8, 0xdf, 0x76, 0x00, 0x00, 0x00, 0x00, 565 | 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xfe, 0xd8, 0xd8, 0xd8, 0xde, 0x00, 0x00, 0x00, 0x00, 566 | 0x00, 0x30, 0x78, 0xcc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 567 | 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 568 | 0x00, 0x30, 0x18, 0x0c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 569 | 0x00, 0x30, 0x78, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, 0x00, 570 | 0x00, 0x60, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x76, 0x00, 0x00, 0x00, 0x00, 571 | 0x00, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 572 | 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 573 | 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 574 | 0x00, 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 575 | 0x00, 0x38, 0x6c, 0x60, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x66, 0xf6, 0x6c, 0x00, 0x00, 0x00, 0x00, 576 | 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 577 | 0x00, 0x00, 0x3e, 0x63, 0x63, 0x30, 0x1c, 0x06, 0x63, 0x63, 0x3e, 0x00, 0x1c, 0x00, 0x00, 0x00, 578 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x38, 0x0e, 0x63, 0x3e, 0x00, 0x1c, 0x00, 0x00, 0x00, 579 | 0x00, 0x0c, 0x18, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 580 | 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 581 | 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 582 | 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 583 | 0x00, 0x00, 0x76, 0xdc, 0x00, 0xbc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 584 | 0x00, 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 585 | 0x00, 0x21, 0x1e, 0x00, 0x1e, 0x33, 0x60, 0x60, 0x67, 0x63, 0x33, 0x1d, 0x00, 0x00, 0x00, 0x00, 586 | 0x00, 0x42, 0x3c, 0x00, 0x3b, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 587 | 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 588 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 589 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 590 | 0x00, 0x60, 0x60, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x60, 0xdc, 0x36, 0x0c, 0x18, 0x3e, 0x00, 0x00, 591 | 0x00, 0x60, 0x60, 0x62, 0x66, 0x6c, 0x18, 0x36, 0x6e, 0xde, 0x36, 0x7e, 0x06, 0x06, 0x00, 0x00, 592 | 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 593 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 594 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 595 | 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 596 | 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 597 | 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 598 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 599 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 600 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 601 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 602 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 603 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 604 | 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 605 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 606 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 607 | 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 608 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 609 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 610 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 611 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 612 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 613 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 614 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 615 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 616 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 617 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 618 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 619 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 620 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 621 | 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 622 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 623 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 624 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 625 | 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 626 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 627 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 628 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 629 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 630 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 631 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 632 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 633 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 634 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 635 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 636 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 637 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 638 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 639 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 640 | 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 641 | 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 642 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 643 | 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 644 | 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xd8, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, 645 | 0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 646 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 647 | 0x00, 0x00, 0xfe, 0xc6, 0x62, 0x30, 0x18, 0x18, 0x30, 0x62, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 648 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xcc, 0xcc, 0xcc, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 649 | 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 650 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 651 | 0x00, 0x00, 0xfe, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0xfe, 0x00, 0x00, 0x00, 0x00, 652 | 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 653 | 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, 654 | 0x00, 0x00, 0x3e, 0x60, 0x60, 0x3c, 0x66, 0xc6, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 655 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 656 | 0x00, 0x00, 0x02, 0x06, 0x7c, 0xce, 0xde, 0xf6, 0xf6, 0x7c, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 657 | 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 658 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 659 | 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 660 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 661 | 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 662 | 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 663 | 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1e, 0x1a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 664 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x58, 0x78, 0x30, 0x00, 0x00, 0x00, 665 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 666 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 667 | 0x00, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 668 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 669 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 670 | 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x78, 0x38, 0x18, 0x00, 0x00, 0x00, 671 | 0x00, 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 672 | 0x00, 0x00, 0x70, 0xd8, 0x18, 0x30, 0x60, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 673 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 674 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 675 | }; 676 | } 677 | } 678 | -------------------------------------------------------------------------------- /VGAGraphics.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using vga = Cosmos.HAL.VGADriverII; 5 | 6 | namespace Cosmos.System.Graphics 7 | { 8 | // this class is used to store vga-related graphical functions 9 | public static class VGAGraphics 10 | { 11 | private static int fontHeight = 16; 12 | 13 | // clear the screen 14 | public static void Clear(VGAColor color) { vga.Clear((byte)color); } 15 | 16 | // swap back buffer if able 17 | public static void Display() { vga.Display(); } 18 | 19 | // draw pixel 20 | public static void DrawPixel(int x, int y, VGAColor color) { vga.DrawPixel((ushort)x, (ushort)y, (byte)color); } 21 | 22 | // draw filled rectangle 23 | public static void DrawFilledRect(int x, int y, int w, int h, VGAColor color) 24 | { 25 | for (int i = 0; i < h; i++) 26 | { 27 | for (int j = 0; j < w; j++) { DrawPixel(x + j, y + i, color); } 28 | } 29 | } 30 | 31 | // draw horizontal line 32 | public static void DrawLineX(int x, int y, int w, VGAColor color) 33 | { 34 | for (int i = 0; i < w; i++) { DrawPixel(x + i, y, color); } 35 | } 36 | 37 | // draw vertical line 38 | public static void DrawLineY(int x, int y, int h, VGAColor color) 39 | { 40 | for (int i = 0; i < h; i++) { DrawPixel(x, y + i, color); } 41 | } 42 | 43 | // draw point-to-point line 44 | public static void DrawLine(int x0, int y0, int x1, int y1, VGAColor color) 45 | { 46 | // calculate 47 | int xx = x0, yy = y0; 48 | var dx = Math.Abs(x1 - x0); 49 | var dy = Math.Abs(y1 - y0); 50 | var sx = (x0 < x1) ? 1 : -1; 51 | var sy = (y0 < y1) ? 1 : -1; 52 | var err = dx - dy; 53 | 54 | while (true) 55 | { 56 | // draw pixel 57 | DrawPixel(xx, yy, color); 58 | 59 | // increment 60 | if ((x0 == x1) && (y0 == y1)) break; 61 | var e2 = 2 * err; 62 | if (e2 > -dy) { err -= dy; xx += (int)sx; } 63 | if (e2 < dx) { err += dx; yy += (int)sy; } 64 | } 65 | } 66 | 67 | // draw character with transparent background 68 | public static void DrawChar(int x, int y, char c, VGAColor fg, VGAFont font) 69 | { 70 | // determine font size 71 | fontHeight = 8; 72 | if (font == VGAFont.Font8x8) { fontHeight = 8; } 73 | else if (font == VGAFont.Font8x16) { fontHeight = 16; } 74 | int p = fontHeight * (byte)c; 75 | 76 | // vertical 77 | for (int cy = 0; cy < fontHeight; cy++) 78 | { 79 | // horizontal 80 | for (byte cx = 0; cx < 8; cx++) 81 | { 82 | // 8x8 83 | if (font == VGAFont.Font8x8) 84 | { 85 | // convert to position and draw 86 | if (VGAFontData.ConvertByteToBitAddress(VGAFontData.Font8x8_Data[p + cy], cx + 1)) 87 | { DrawPixel(x + (8 - cx), y + cy, fg); } 88 | } 89 | // 8x16 90 | else if (font == VGAFont.Font8x16) 91 | { 92 | // convert to position and draw 93 | if (VGAFontData.ConvertByteToBitAddress(VGAFontData.Font8x16_Data[p + cy], cx + 1)) 94 | { DrawPixel(x + (8 - cx), y + cy, fg); } 95 | } 96 | } 97 | } 98 | } 99 | 100 | // draw character with background color 101 | public static void DrawChar(int x, int y, char c, VGAColor fg, VGAColor bg, VGAFont font) 102 | { 103 | // determine font size 104 | fontHeight = 8; 105 | if (font == VGAFont.Font8x8) { fontHeight = 8; } 106 | else if (font == VGAFont.Font8x16) { fontHeight = 16; } 107 | int p = fontHeight * (byte)c; 108 | 109 | // vertical 110 | for (int cy = 0; cy < fontHeight; cy++) 111 | { 112 | // horizontal 113 | for (byte cx = 0; cx < 8; cx++) 114 | { 115 | // 8x8 116 | if (font == VGAFont.Font8x8) 117 | { 118 | // convert to position and draw 119 | if (VGAFontData.ConvertByteToBitAddress(VGAFontData.Font8x8_Data[p + cy], cx + 1)) 120 | { DrawPixel(x + (8 - cx), y + cy, fg); } else { DrawPixel(x + (8 - cx), y + cy, bg); } 121 | } 122 | // 8x16 123 | else if (font == VGAFont.Font8x16) 124 | { 125 | // convert to position and draw 126 | if (VGAFontData.ConvertByteToBitAddress(VGAFontData.Font8x16_Data[p + cy], cx + 1)) 127 | { DrawPixel(x + (8 - cx), y + cy, fg); } else { DrawPixel(x + (8 - cx), y + cy, bg); } 128 | } 129 | } 130 | } 131 | } 132 | 133 | // draw string with transparent background 134 | public static void DrawString(int x, int y, string text, VGAColor fg, VGAFont font) 135 | { 136 | // determine font size 137 | fontHeight = 8; 138 | if (font == VGAFont.Font8x8) { fontHeight = 8; } 139 | else if (font == VGAFont.Font8x16) { fontHeight = 16; } 140 | 141 | int xx = x, yy = y; 142 | for (int i = 0; i < text.Length; i++) 143 | { 144 | // new line 145 | if (text[i] == '\n') { xx = x; yy += fontHeight; } 146 | // character 147 | else { DrawChar(xx, yy, text[i], fg, font); xx += 8; } 148 | } 149 | } 150 | 151 | // draw string with background color 152 | public static void DrawString(int x, int y, string text, VGAColor fg, VGAColor bg, VGAFont font) 153 | { 154 | // determine font size 155 | fontHeight = 8; 156 | if (font == VGAFont.Font8x8) { fontHeight = 8; } 157 | else if (font == VGAFont.Font8x16) { fontHeight = 16; } 158 | 159 | int xx = x, yy = y; 160 | for (int i = 0; i < text.Length; i++) 161 | { 162 | // new line 163 | if (text[i] == '\n') { xx = x; yy += fontHeight; } 164 | // character 165 | else { DrawChar(xx, yy, text[i], fg, bg, font); xx += 8; } 166 | } 167 | } 168 | 169 | // draw custom image format 170 | public static void DrawImage(int x, int y, VGAImage image) 171 | { 172 | for (int yy = 0; yy < image.Height; yy++) 173 | { 174 | for (int xx = 0; xx < image.Width; xx++) 175 | { 176 | DrawPixel(x + xx, y + yy, (VGAColor)image.Data[xx + (yy * image.Width)]); 177 | } 178 | } 179 | } 180 | 181 | // draw custom image format with transparency key 182 | public static void DrawImage(int x, int y, VGAColor transKey, VGAImage image) 183 | { 184 | for (int yy = 0; yy < image.Height; yy++) 185 | { 186 | for (int xx = 0; xx < image.Width; xx++) 187 | { 188 | if (image.Data[xx + (yy * image.Width)] != (byte)transKey) 189 | { DrawPixel(x + xx, y + yy, (VGAColor)image.Data[xx + (yy * image.Width)]); } 190 | } 191 | } 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /VGAImage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Cosmos.System.Graphics 7 | { 8 | public class VGAImage 9 | { 10 | // properties 11 | public int Width { get; private set; } 12 | public int Height { get; private set; } 13 | public byte[] Data { get; private set; } 14 | 15 | // constructor - new 16 | public VGAImage(int w, int h) 17 | { 18 | this.Width = w; 19 | this.Height = h; 20 | this.Data = new byte[w * h]; 21 | } 22 | 23 | // constructor - load 24 | public VGAImage(string file) 25 | { 26 | this.FromFile(file); 27 | } 28 | 29 | // set data 30 | public void LoadData(int w, int h, byte[] data) 31 | { 32 | this.Width = w; 33 | this.Height = h; 34 | this.Data = data; 35 | } 36 | 37 | // load from file system 38 | public bool FromFile(string file) 39 | { 40 | if (File.Exists(file)) 41 | { 42 | byte[] data = File.ReadAllBytes(file); 43 | return ParseData(data); 44 | } 45 | else { return false; } 46 | } 47 | 48 | // shrink image by multiple 49 | public void Shrink(int mult) 50 | { 51 | byte[] data = new byte[(Width * Height) / mult]; 52 | for (int yy = 0; yy < Height; yy++) 53 | { 54 | int yyScaled = yy / mult; 55 | for (int xx = 0; xx < Width; xx++) 56 | { 57 | int xxScaled = xx / mult; 58 | data[(xxScaled + (yyScaled * (Width / mult)))] = Data[xx + (yy * Width)]; 59 | } 60 | } 61 | 62 | this.Width = (int)(Width / mult); 63 | this.Height = (int)(Height / mult); 64 | this.Data = data; 65 | } 66 | 67 | // expand image by multiple 68 | public void Expand(int mult) 69 | { 70 | byte[] data = new byte[(Width * Height) * mult]; 71 | for (int yy = 0; yy < Height; yy++) 72 | { 73 | int yyScaled = yy * mult; 74 | for (int xx = 0; xx < Width; xx++) 75 | { 76 | int xxScaled = xx * mult; 77 | data[(xxScaled + (yyScaled * (Width * mult)))] = Data[xx + (yy * Width)]; 78 | } 79 | } 80 | 81 | this.Width = (int)(Width * mult); 82 | this.Height = (int)(Height * mult); 83 | this.Data = data; 84 | } 85 | 86 | // parse data 87 | public bool ParseData(byte[] data) 88 | { 89 | // valid file 90 | if (data.Length > 4) 91 | { 92 | Width = (ushort)((data[0] << 8) | data[1]); 93 | Height = (ushort)((data[2] << 8) | data[3]); 94 | this.Data = new byte[Width * Height]; 95 | // pixel count is valid 96 | if (data.Length - 4 == Width * Height) 97 | { 98 | // loop through data 99 | for (int i = 0; i < Width * Height; i++) 100 | { 101 | // copy data(4 is width and height offset) 102 | Data[i] = data[i + 4]; 103 | } 104 | return true; 105 | } 106 | // pixel count doesn't match image size 107 | else { return false; } 108 | } 109 | // invalid file type - too small 110 | else { return false; } 111 | } 112 | } 113 | } 114 | --------------------------------------------------------------------------------