Discworld Noir

25 Oct, 2016

Last week I did something I never expected to have to do ever again. I installed Windows 98. The reason? To play Discworld Noir (1999).

Thankfully Simon McVittie has done all the heavy lifting in figuring out how to set up Qemu (and especially get sound working satisfactory). I'm very grateful for his HOWTO.

I did not have legal version of the operating system, so that was handily provided by WinWorld. That version needed a boot floppy which was also provided by WinWorld. The serial key on that page did not work, but there's plenty to choose from here.

Discworld Noir is an odd title. It does not work in Wine, it's problematic (to say the least) to run on a modern Windows system, and it was never considered enough of a classic to have been reverse engineered like the first two Discworld games.

Was it worth the effort? Oh yes, the interface may be clunky, the graphics and animation obviously dated, but it is well written, funny and a joy to finally be able to play through. (With a little help!)

Bike workshop

22 May, 2016

I got an idea to spruce up my bicycle workshop with some decorations.

Google provides a very good search interfaces for patents, complete with images in reasonably high resolutions. I picked out a few important bicycle patents with illustrations and printed them out on A4 card stock. The frames are the cheapest ones from IKEA that take A4 format (RIBBA?).

The patents pictured are:

There are so many important inventions (with patents) in the MTB and bicycle world, but not an unlimited space on my walls. On the other hand it's easy to just print new "artwork" should I get bored looking at the above patents.

As for the trophy... I replaced the handlebar on my racer to get a more upright riding position but didn't want to get rid of the old stuff (Cinelli stem, Titan handlebar, Campy levers...) so I decided to mount the old stuff on the wall!

The pen holder is an old F&S Torpedo hub shell, both decorative and useful for the time being while I find spare parts to rebuild it.

Notes about working with curses

21 May, 2016

A few notes on working with curses (on Python) as I seem to have to rediscover this for every new project.

Curses work with Y, X coordinates, upper left corner is 0, 0. X is horizontal, Y vertical.

Zero based naturally, so on a normal 24x80 terminal the last positions are 23, 79 (lower right corner).

Curses coordinates

getch() is normally blocking so if you update curses in a loop and want to check for input you need to set timeout(n) for the screen.

If you don't need a cursor (for input) disabling it with curs_set(0) seems to get less flicker when redrawing the screen.

Each successive call to addstr() is relative to previous call by default.

Some keys, like Escape (and Alt and arrow keys) send two keycodes. To handle this you need to check for key 27, then immediately after make another call to getch() and check for the next keycode. In the case of Escape there is no second. (If you use timeout() for non-blocking input, you can disable it with nodelay() and afterwards enable it again).

Escape has a delay by default, to disable it set the environment variable ESCDELAY to a suitable value. In Python this is as easy as

import os

To handle UTF-8 input, use get_wch()

Color pair 0 can't be used, it's always white text on black background.
Color pair is foreground (text), background.

Python best practices

04 May, 2016

A short list of suggested reading about Python style and best practices:

Old routers

02 May, 2016

I'm pretty impressed by this thing:

Asus WL500gP

It's an Asus WL-500g Premium I bought new in 2008. This little machine have been through the router equivalent of a heart transplant and a couple of brain surgeries.

At first I used it with the stock Asus firmware at, and later flashed it to use the now defunct FreeWRT.

It worked very well for a long time, then developed peculiar problem: the wall warts kept breaking. At first I suspected a freak lightning strike for having overloaded it. But it kept breaking them. Over a couple of years think I replaced the power supply three or four times.

Then the router itself gave up the ghost and I replaced it with a TP-Link running OpenWRT.

Before recycling the Asus however, I decided to have a peek inside. I discovered that most of the capacitors had gone bad. I'm not sure if that was the cause of the failing PSU:s.

Anyway, I replaced the capacitors, and it fired up right away. OpenWRT still supports this model so if I just could reflash it I might get some use out of it. There was no upgrade path from FreeWRT to OpenWRT that I could find, so eventually I reflashed the old Asus firmware and then reflashed again to Chaos Calmer.

Not bad for cheap hardware that is eight years old.

Dark theme in Emacs

01 May, 2016

GNOME and GTK+ supports using a dark theme that's quite easy on the eyes. This is usually an opt-in for applications, but you can also force it. The easiest way to do this is to enable global dark themes in gnome-tweak-tool.

There is however another (admittedly hacky) way to do this on a per application basis and quite easy to make it work well in Emacs:

Emacs with dark theme

A dark Emacs goes very well with the Tango color theme by Julien Barnier.

The first step is to launch emacs with the 'GTK_THEME' set to dark, like so: ´GTK_THEME=Adwaita:dark´ . Just wrap it in a simple shell script.

Launching Emacs like that will however give an unsightly non-dark window manager. We can use the xprop utility to force a dark variant.

xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark"

You could even wrap that in a shell function that uses wmctrl to get the window id instead of clicking on the emacs window each time.

A neater way to accomplish the same is to run it within emacs. We can even have it run each time a new frame is created:

WARNING: Some really ugly Elisp follows, be gentle, it's my first time...

(defun set-dark-wm-theme (frame)
  (select-frame frame) ;; this is important!
  (when (display-graphic-p)
      (when (file-exists-p "/usr/bin/xprop")
      (defvar winid nil)
      (setq winid (frame-parameter frame 'outer-window-id))
      (call-process "xprop" nil nil nil "-f" "_GTK_THEME_VARIANT" "8u" "-set" "_GTK_THEME_VARIANT" "dark" "-id" winid))))))

(defun on-after-init ()
  (set-dark-wm-theme (selected-frame))
  (unless (display-graphic-p (selected-frame))
    (set-face-background 'default "unspecified-bg" (selected-frame))))

(add-hook 'window-setup-hook 'on-after-init)

(add-hook 'after-make-frame-functions 'set-dark-wm-theme)

This is a pretty convoluted setup, but was a fun excuse to poke around Emacs hooks and write some Elisp.