###>>>KWD Space Engineers Pixel Display, Space Engineers Font, Monospaced ###>>>DSC A Pixel precise Display for Space Engineers including a custom monospaced Font. # Monospaced Font and Pixel Display for Space Engineers

September 23, 2016

![](/images/Space-Engineers/Space-Engineers-Pixel-Display.png){.img-fluid .rounded alt="Closeup of standard Space Engineers LCD Panel, showing pink letters. Single Pixels can be determined." title="Pink is the color of passion"}
Standard LCD Panel displaying monospaced text.
## Pixel Precise Font For everyone suffering from the lack of monospaced fonts and pixel-based displays in Space Engineers here I share my simple, yet effective solution: A simple helper class in C#, which I wrote yesterday night to solve this particular problem. As a bonus this also enabled using the LCD Screens for arbitrary pixel-precise output, even with animations, as you will see later. Have fun and feel free to improve it! The class can be easily embedded in your programmable blocks and allows simulating pixel-precise displays on the LCD and Text Panels. The class also ships with a beautiful set of retro-style compile time mono-spaced fonts. First admire a few screenshot to get a first impression:
![](/images/Space-Engineers/Space-Engineers-ASCII-Bars.png){.img-fluid .rounded alt="A Space Engineers Console showcasing our Font. It displays some ASCII styled bars." title="The Monospaced Font in Action."}
Status bars showing normal and inverted font.
![](/images/Space-Engineers/Space-Engineers-LCD-Panels.png){.img-fluid .rounded alt="Two adjacent Space Engineers Consoles. One shows a sinus wave, demonstrating pixel precise output."}
The Display to the right demonstrates animated pixel precise output.
The class exposes the following public methods: * Screen constructor * pixelOn * draw_rect * put_letter * put_letter_inv // inverted single letter * put_text * put_text_inv // inverted text * update // updates lcd or text panel ## Pixel Display supports Animations
![](/images/Space-Engineers/Space-Engineers-Animated-Display-Setup.png){.img-fluid .rounded alt="Complete setup with 3 Panels a timer block and a programmable block"}
A complete Setup featuring 3 LCD Panels and supporting blocks.
With a timer block this approach can be used for beautiful animations too! The solution is based on emulating pixels using very small fonts ~0.2 on regular LCD Panels. I use ‘[‘ and ‘.’ here, since they both have the same widths and work quite well to emulate on/off pixels. Usage of the class is easy and straigth forward from your Main function: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.csharp .numberLines} // construct a new Screen class instace providing // the label of your panel and dimensions. Screen s = new Screen("Your_LCD_1",215,59,this); // put text on specified pixel coordinates s.put_text(10,10," Welcome to the Machine "); // refresh the LCD Panel s.update(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## C Sharp Class for the Space Engineers Font And this is the C# class behind it. You will have to copy it into your programmable blocks. (Let me know if there is a more elegant way?) Sidenote: If you wonder how I generated this numbers inside the letters array, you can read it in this seperate post about bitmap fonts generation. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.csharp .numberLines} class Screen { public int width; public int height; IMyTextPanel panel; char mark_pixel='['; char mark_empty='.'; static MyGridProgram programm; string output; public Screen(string panel_name, int _width, int _height, MyGridProgram programRef) { width=_width; height=_height; programm=programRef; panel=programm.GridTerminalSystem.GetBlockWithName(panel_name) as IMyTextPanel; output=new string(' ',0); for(int y=0;y=(letter & (int)Math.Pow(2,24-(i+j*5)) )) pixelOn(x+i,y+j); } public void update() { panel.WritePublicText(output, false); } // monospace fonts starting from 0x20 (space) static readonly int[] letters = { 0,4329476,10813440,11512810,16398526,17895697,6632015,4325376,2232450,8523912, 22483413,4357252,68,31744,4,1118480,15390382,4608142,15239320,31504446, 1841462,33060926,33062463,32540808,33095231,33094719,131200,131208,2236546, 1016800,8521864,32051204,15392270,33095217,32045630,33047071,32032318, 33061407,33062416,33050175,18415153,14815374,14748236,20673235,17318431,18732593,18667121, 15255086,32045584,15259213,32045779,33299071,32641156,18400814,18393412,18405233,18157905,18157700, 32575775,14950670,17043521,14747726,4539392,31,6389760,33095217,32045630, 33047071,32032318,33061407,33062416,33050175,18415153,14815374,14748236, 20673235,17318431,18732593,18667121,15255086,32045584,15259213,32045779,33299071, 32641156,18400814,18393412,18405233,18157905,18157700,32575775,2240642,4329604 8525960,14016, }; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Source Code used for Example Screenshots above ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.csharp .numberLines} static int cnt=0; // programm counter public void Main(string argument) { // increase programm counter cnt+=1; if (cnt>100) cnt= 0; // init our screen class: new 438x59 screen Screen s = new Screen("Miguel_LCD_1",(int)(438*1.5),(int)(59*1.5),this); // draw some rectangles s.draw_rect(0,0,s.width,s.height); s.draw_rect(2,2,s.width-4,s.height-4); //draw more rectangles (stress testing only) // for(int i=4; i<35; i+=2) // { // s.draw_rect(i,i,s.width-2*i,s.height-2*i); // } // write counter value s.put_text(8,5,"counter: "+cnt); // inverted text s.put_text_inv(8,12,"SOME INVERTED TEXT --- "); // paint a sinus wave for(int i=0;i200)s.pixelOn(i,(int)(s.height/2+s.height/3*Math.Sin((i+cnt)/25.0))); } // paint individual letters along a sinus string txt=new string(' ',0); txt="! software fools rules the waves!"; for(int i=0;i<=;'~^\n"+ " %#@!~?{}[]-+*&`.,:'"); s3.draw_rect(0,0,s3.width,s3.height); s3.draw_rect(2,2,s3.width-4,s3.height-4); s2.put_text(10,1, "Something......[|||||||||| ] 10%\n"+ "Foo............[||| ] 33%\n"+ "Bar............[||| ] 99%\n"+ "Something else.[||||||||||I ] 05%\n" ); s2.put_text_inv(10,35, "Something......[|||||||||| ] 10%\n"+ "Foo............[||| ] 33%\n"+ "Bar............[||| ] 99%\n"+ "Something else.[||||||||||I ] 05%\n" ); s2.put_text(10,65, "copyright by softwarefools.com" ); s2.update(); s3.update(); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Helpful Comment on improving Performance JR Raynal December 13, 2017 at 9:29 am Hi, I was playing with your script, and found it super slow… which is odd given the performances of other scripts out there. Turns out by switching the output from a string to a StringBuilder, you don’t need to copy them around as much. I assume this is the fix because I experienced a serious speed increase with that! Here is the rewritten snippet: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.csharp .numberLines} StringBuilder output; public Screen(string panel_name, int _width, int _height, MyGridProgram programRef) { width = _width; height = _height; programm = programRef; panel = programm.GridTerminalSystem.GetBlockWithName(panel_name) as IMyTextPanel; output = new StringBuilder(); for (int y = 0; y < height; y++) { output.Append(mark_empty, width); output.Append('\n'); } } public void pixelOn(int x, int y) { output[y * (width + 1) + x] = mark_pixel; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## TODOS cleanup and optimize code!!, move sources to git repo, use some kind of syntax highlihter on this post. allow other font-sets with other sizes and let the user adjust spacing, publish python font converter in another post.