How to generate star fields

I recently needed a texture for the skybox in a 3D space game.

I used this ImageMagick one-liner to generate a dotted canvas with some grey and white pixels. It displays well if the texture will be stretched.

convert -size 1600x900 xc: +noise Random -channel R -threshold 0.5% \
        -negate -channel RG -separate +channel \
        -compose multiply -composite stars.png

Alternative style

With a simple modification, the bright stars are made bigger, and the dull ones are made smaller, with only black and white used. This works well if the texture will be shrunk for display.

convert -size 800x450 xc: +noise Random -channel R -threshold 0.5% \
        -negate -channel RG -separate +channel \
        -compose multiply -composite -resize 200% \
        -threshold 10% stars-rounded.png

Full process

Although these are great one-liners, the actual process is a bit hard to follow without some smaller steps.

Here, we will generate a 150×90 star field in several steps. I’ve scaled each of these pictures to 200% of their original size and converted them to PNG for display on the web. I’ve used BMP in the commands only because it saves some plumbing around colour spaces.

Start with a blank canvas:

convert -size 150x90 xc: stars-01.bmp

Add random RGB noise:

convert stars-01.bmp +noise Random stars-02.bmp

In the red channel of the image, apply a black/white threshold: If the red channel is greter than 0.5%, it is set to the maximum, otherwise it is set to the minimum.

Mostly the red channel is now 100%, with random dots of 0%. The blue and green channels are still completely random:

convert stars-02.bmp -channel R -threshold 0.5% stars-03.bmp

Negate the image, so that the red channel is mostly 0%, with dots of 100%:

convert stars-03.bmp -negate stars-04.bmp

Extract the red channel and green channel.

convert stars-04.bmp -channel RG -separate +channel stars-05.bmp

The red channel will be dots of white:

The green channel will be random:

Multiply the channels together, so that the white dots become grey dots, each with a random brightness:

convert stars-05-0.bmp stars-05-1.bmp -compose multiply -composite stars-06.bmp

For the alternative style, scale the image up, then apply a new threshold. Brighter dots will appear as larger patches of white, while dull stars will be smaller or invisible:

convert stars-06.bmp -resize 200% -threshold 10% stars-06-rounded.bmp

On running deployments via GitHub

TL;DR; – GitHub can be pretty unreliable, depend on it at your peril.

GitHub was down for about 20 minutes today. I happened to be logged in so I’ll share a few screen captures.

The status page and twitter showed no activity for the first nine minutes of the outage, but were then updated with erroneous information.

Meanwhile, the website started displaying unicorns.

If you are logged into GitHub regularly, you might know that this is not a rare event. I don’t have any data on how often GitHub is actually broken, but based on that status page, I’m not sure that know either.

Why I don’t deploy via GitHub

Around May 2013, a website that I maintained started rendering incorrectly because of a bug in my code: I had made some MySQL fields TEXT type, which have a limited size, and part of the application had exceeded the limit, resulting in truncated pages.

This app is written in PHP, and my deployment workflow at the time involved pushing up a change to GitHub, then then triggering a git pull on the server, which ran an update script to bring everything up to speed.

In this case, I was on mobile internet, so I diagnosed the problem and prepared a hotfix on my laptop. When I tried to push it to GitHub, it was offline. I ended up logging in and running a few ALTER TABLE statements over SSH, which is a long shot from the robust deployment pipeline I had envisaged.

There are some emerging SaaS products that offer to deploy directly from GitHub. For example, I use Travis CI extensively for open source, and you can hook it up with deployment keys.

This stuff seems really cool, but I imagine that an error message containing rainbow unicorns would not be very funny if you wanted to fix something in a hurry. This particular app is still deployed with a git pull, but I’ve started to avoid mixing deployment with version control, so that I can run a build and deploy anywhere in case of emergency.

How to use a Radeon graphics card on Debian 9

I have previously blogged about Radeon graphics cards on different Debian installs.

ATI has now released a new free driver which works brilliantly on Debian. In the past, Debian users had to choose between using the community-provided free software driver, or the proprietary one. Generally the proprietary driver was more feature-rich, but the free driver worked more reliably across upgrades. So now, you can safely ignore old guides and start using it.

Here’s how:

Upgrade

Make sure you are on Debian 9 (Stretch) or newer.

These steps apply to a fresh install.

Identify

You should use lspci to confirm that you have an ATI card.

$ lspci | grep Radeon
01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X]

Install firmware

You need to install a package called firmware-linux-free to get the driver working at all. If you want decent graphics performance, you will need firmware-linux-nonfree as well, which involves adding non-free sources:

nano /etc/apt/sources.list

Add the words “contrib non-free” to the end of your mirror:

deb http://.../debian/debian/ stretch main contrib non-free

Add the packages:

apt-get update
apt-get install firmware-linux-free firmware-linux-nonfree

And reboot:

reboot

What, that’s it?

Well, yes, for a fresh install that’s it. If your install is old, you might also have to remove old drivers or install the xserver-xorg-video-amdgpu and xserver-xorg-video-ati packages (in my case, these were already installed).

The Debian Wiki AtiHowto contains some more detailed information, most of which is not relevant for a simple desktop setup.

How to assemble a Linux software RAID array on a different computer

With Linux software RAID, if you ever toast your computer, you can retrieve the disks and open up the array on a different computer.

They appear as “Linux Software RAID Member” in the disk utility.

Simply install mdadm, and scan for arrays:

$ sudo apt-get install mdadm
$ sudo mdadm --assemble --scan
mdadm: /dev/md/0 has been started with 2 drives.

The array will then appear as a new disk, which can be formatted, mounted, or cloned via the usual tools.

Crowd-sourced POS printer compatibility site is online

 

Point-of-sale (POS) printers are all different, so the implementation of the more advanced ESC/POS  features varies considerably between vendors and models.

Some months ago I extracted compatibility information out of the escpos-php library, so that it could be used by the python-escpos team as well. We’re still in the early stages, but both of these projects now have similar compatibility features.

You can the new shared database on GitHub as receipt-print-hq/escpos-printer-db, and I’m beginning to add it to some printing projects that need it.

Today I’m blogging a few screen captures from the new web viewer for this database that has come out today, hosted here (source code here).

escpos-printer-db landing page

escpos-printer-db landing page

Character encodings

escpos-printer-db character encoding list

escpos-printer-db character encoding list

escpos-printer-db character encoding detail

escpos-printer-db character encoding detail

Vendors

escpos-printer-db vendor list

escpos-printer-db vendor list

escpos-printer-db vendor detail

escpos-printer-db vendor detail

Printer profiles

escpos-printer-db printer profile list

escpos-printer-db printer profile list

escpos-printer-db printer profile detail

escpos-printer-db printer profile detail

Tech used

I’ve used materialize.css with backbone.js and jQuery. This is the first time I’ve attempted using materialize – I’m normally a bootstrap.css user.

The back-end data is generated with Python, but the actual site is served as a single-page application, with static JSON files hosting the data.

escpos-php 1.6 released

Another update to the open source receipt printing library escpos-php has been released today. For composer users, it is available as mike42/escpos-php

This is expected to be the final release in the 1.x series. Newer versions will drop support for some end-of-life PHP versions.

The v1.6 release notes detail the changes and lists 13 additional printers tested out by the user base.

Please direct any bug reports to the issue tracker on GitHub. The escpos-php tag on this blog has some tips and examples.

I’ll also call out some related projects that I’ve been involved with, which you should consider contributing to if you are working with thermal receipt printers:

  • escpos-printer-db – Crowd-sourced database of printer support. Add your printer for better support in open source drivers!
  • escpos-tools – Tools to work with ESC/POS binary, including text or image extraction, HTML conversion.
  • chrome-raw-print – A browser plugin to access local printers from a web-page.

mdcheckr: Practical testing for Markdown files

If you are a continuous integration enthusiast, you might be annoyed by preventable errors in project documentation.

I recently found a broken link in one project’s documentation, and a syntax error in an example on another project. I quickly wrote up a simple tool to detect this type of issue, solving the problem for me.

$ mdcheckr README.md
Checking README.md ..
- Code block starting line 21 (language: bash) [ OK ]
- Link https://travis-ci.org/receipt-print-hq/escpos-tools [ OK ]
- Link https://getcomposer.org/ [ OK ]
- Link doc/esc2text.md [ OK ]
- Link doc/esc2html.md [ OK ]
- Link doc/escimages.md [ OK ]
- Link CONTRIBUTING.md [ OK ]
- Link LICENSE.md [ OK ]
- Image https://travis-ci.org/receipt-print-hq/escpos-tools.svg?branch=master [ OK ]

I disregarded some existing “linter” tools. I don’t believe that it is necessarily productive for small projects to enforce a style-based quality gate for Markdown, but you may be able to configure these tools to be less pedantic. My goal here was to simply churn out a script which could reject objectively broken Markdown files.

I’ve posted this project to GitHub as mdcheckr. It is available as a package for Debian, Ubuntu, and RHEL/CentOS. Travis CI users may be interested to check out this pull request, where mdcheckr is added to the project’s build.

How to access a raw network printer as a file on Linux

I got this interesting question on my blog post ‘Setting up an Epson receipt printer‘:

Wondering if you had an idea on how to map a linux device to the netcat command so that I could “convert” the printer to be a local one? -Marco

I have previously written about the opposite use case: How to use a Raspberry Pi as a print server, where I used netcat to pass data to a local USB printer.

The setup

In this setup, I will assume that you have a working Ethernet printer, which accepts raw data on port 9100.

diagram

The aim is to make this appear as a file, so that you can print to it as if it were a local USB printer:

diagram2

Before you begin

Make sure you have netcat. It’s not used for the real setup, but you will need it for testing. There are a few versions of this tool around, the one used here is:

apt-get install netcat

Verify that your printer accepts text on port 9100 via netcat:

echo "Hello world" | nc -q 1 192.168.x.y 9100

Set up a fake printer on localhost, and leave it running:

nc -klp 9100

Now, test that your fake printer shows output when you send it:

echo "Hello world" | nc -q 1 127.0.0.1 9100

Why I’m not using..

/dev/tcp

If you search for how to redirect data to a TCP socket, a common suggestion is:

echo "Hello world" > /dev/tcp/127.0.0.1/9100

This is a bash built-in, so unless your use case involves printing from bash, read on.

CUPS

CUPS does not expose the printer as a file, which is the aim here. It also takes a few seconds to print, so we get much faster results if we remove CUPS from the loop and speak to the printer directly.

Use socat to move data

Socat is capable of making a FIFO file (‘pipe’), and writing this out over the network.

apt-get install socat

Redirect /tmp/my-printer to localhost:9100:

socat PIPE:/tmp/my-printer TCP:localhost:9100

Next, test that you can see the printer file and write to it. This line should appear on your local netcat “fake printer”:

echo "Hello world" > /tmp/my-printer

This file is a “pipe”, so it behaves very similarly to a character device.

If the connection is dropped, socat will exit, and the file will be deleted.

There are some big problems though:

  • If your printer is offline, and you try to print, you will create a regular file at “/tmp/my-printer”, breaking it.
  • This is not a self-restarting service, nor does it start on boot
  • Only the user who runs the command can print

Setting this up as a proper service

The usblp driver allows anybody from the lp group to print, so we will try to do something similar, and get a group-writable pipe:

$ ls /dev/usb/lp0  -Ahl
crw-rw---- 1 root lp 180, 0 Jun 12 12:51 /dev/usb/lp0

We don’t need to run socat as root, so make a new user called fileprint who is in the lp group.

useradd --groups lp fileprint

Add yourself to the lp group as well:

usermod -a -G lp mike

Next, write this systemd service file to /etc/systemd/system/fileprint.service

[Unit]
Description=fileprint
After=network.target

[Service]
User=fileprint
Group=lp
ExecStartPre=/usr/bin/mkfifo -m '0664' /var/run/fileprint/printer
ExecStart=/usr/bin/socat PIPE:/var/run/fileprint/printer TCP:127.0.0.1:9100
Restart=always
RuntimeDirectory=fileprint

What’s going on here?

  • Runs as user fileprint and group lp
  • Manages a runtime directory at /var/run/fileprint
  • Creates a pipe that is group-writeable at /var/run/fileprint/printer
  • Forwards traffic to 127.0.0.1:9100
  • Re-starts automatically

Load and start the service:

systemctl daemon-reload
systemctl start fileprint
systemctl status fileprint

Test out printing to your local netcat “fake printer”:

echo "Test" > /var/run/fileprint/printer

Note that if you are not in the lp group (check with groups command), you should expect a permission error here — just the same as usblp.

Next, replace 127.0.0.1 with your real printer IP, reload systemd, and restart the service:

nano /etc/systemd/system/fileprint.service
systemctl daemon-reload
systemctl restart fileprint
systemctl status fileprint

Test it again, and your actual printer should print a line of text this time:

echo "Test" > /var/run/fileprint/printer

Finally, enable on boot:

systemctl enable fileprint

When the printer is unplugged, the /var/run/fileprint directory will vanish, so that you can see the missing printer as a “File Not Found” error — just the same as usblp.

Drawbacks

This will hold a connection open at all times, which (depending on your printer) may prevent other computers from using it.

The 5890 printer does not support barcodes

I haven’t been able to print barcodes on the 5890 model thermal receipt printer, and it looks like other developers can’t either.

The same printer is sold by several companies. As far as I can tell (mainly from bug reports to escpos-php), these are all the same printer, and could have this issue:

  • AGPtEK SC35-5890F
  • EC Line 5890
  • Gainscha GP-5890
  • HSPOS HS-589C
  • POS-5890
  • WinBond 5890
  • Zjiang ZJ-5890 or POS-5890

In my case, I have a Zjiang POS-5890C, which list the barcode command GS k in its documentation, but does not actually respond to the command.

Separately, a developer has contacted the company and confirmed that this

A few bookmarks for reference:

Testing for barcode support in USB printers

Get yourself a Linux computer or VM, set up the printer with usblp, and run this command:

echo -e '\x1d\x6b\x04000\x00' > /dev/usb/lp0

This command prints a CODE39 barcode containing ‘000’ on printers which support barcodes, and prints garbage on printers which do not.

See also:

libgdx 3D particle effects in HTML

2017-03-flame

It is not immediately obvious in libgdx why the 3D particle effects don’t work in a HTML target. I’m sharing this snippet for future readers.

In short, the “reflection cache” that is created from the Java code does not include everything required, since many of the classes are only referenced at runtime, when the particle definition is loaded.

These class names are visible in the saved files from the 3D effects editor:

$ cat engine.p | fold -w 80
{unique:{billboardBatch:{class:com.badlogic.gdx.graphics.g3d.particles.ResourceD
ata$SaveData,data:{cfg:{class:com.badlogic.gdx.graphics.g3d.particles.batches.Bi
llboardParticleBatch$Config,mode:Screen}},indices:[0]}},data:[],assets:[{filenam
e:"pre_particle.png",type:com.badlogic.gdx.graphics.Texture}],resource:{class:co
....

At runtime, this message is displayed on the web page:

GwtApplication: exception: com.badlogic.gdx.utils.GdxRuntimeException: Could not submit AsyncTask: Error reading file: (filename)
com.badlogic.gdx.utils.GdxRuntimeException: Could not submit AsyncTask: Error reading file: (filename)
Could not submit AsyncTask: Error reading file: (filename)
Error reading file: (filename)
Couldn't find Type for class 'com.badlogic.gdx.graphics.g3d.particles.batches.BillboardParticleBatch$Config'

The reflection is documented on the libgdx Wiki here, and notes that-

  • *.gwt.xml files store this data
  • dependencies defined in the Java are loaded automatically
  • inner classes are also loaded automatically, no need to add them separately

With this in mind, I added the following two lines to the root element in a file called GdxDefinition.gwt.xml

<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.g3d.particles.batches.BillboardParticleBatch" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.g3d.particles.ParticleShader" />

This did the trick, and the 3D particle feature does indeed work in the libgdx HTML target.