nielssp.dk

There isn't much to say about this one. It started out as a desire to play Yukon in a terminal – I could only find a few implementations of Klondike. So I created yuk, a simple ncurses-based Yukon implementation in C. I then realized that most of the code could easily be reused to implement other games, such as Klondike and Freecell. The result was csol.

csol
A game of Yukon in csol.

At the moment, csol includes 5 different solitaire games: Yukon, Klondike, Freecell, Eight Off (very similar to Frecell), and Russian Solitaire (very similar to Yukon). They are implemented in a simple declarative language I designed for csol. It should be possible to implement a lot more games using it, but unfortunately I don't know that many different solitaire games. csol also has support for different themes using the same declarative language.

Some more screenshots of games and themes, as well as the source code, are available on the github repository. As usual, I've also created an aur package.

csol
csol running in DOS 6.22 on an i486 Toshiba laptop from the mid-'90s.

I'm not sure how the thought entered my mind, but I was suddenly curious about how easy it would be to get a somewhat simple ncurses application like csol to run on DOS. Aside from ncurses, I knew csol didn't really have any dependencies other than a C compiler, so I searched for “DOS curses” and PDCurses (Public Domain Curses) showed up.

Helpfully, the PDCurses github repository contains a list of C compilers for DOS. At first I tried to get DJGPP up and running in DOSBox, but eventually ended up using Open Watcom instead because the installation was simpler. After compiling PDCurses my new DOS development environment was ready. To compile csol with Open Watcom and PDCurses I had to make a number of changes to the source:

From C99 to ANSI C: The first step was to remove the use of C99 features from the source code. One such feature is the ability to declare variable anywhere in a block, whereas in ANSI C all declarations must be at the top of the block. This was rather easy to fix by running each source file through gcc -c -ansi -pedantic which helpfully lists all incompatibilities.

From ncurses to pdcurses: Rather unexpectedly it was enough to just include curses.h instead of ncurses.h and change a single occurrence of getmouse(&mouse) to nc_getmouse(&mouse).

From POSIX to DOS: The csol configuration file format has support for including entire directories (e.g. the games and themes directories). Unfortunately standard C doesn't have any concept of “directories” so in order to get the contents of a directory I had used the dirent.h header which is part of the C POSIX library. No such header is provided by Open Watcom, but I was able to recreate the functionality using the functions _dos_findfirst() and _dos_findnext() which are part of the dos.h header.

Similarly I had used getopt_long() from getopt.h (a GNU header) to parse command line options. I replaced this with getopt() from unistd.h (which Open Watcom does include). Unfortunately this means that long options are not currently supported.

From Unicode to Code page 437: The default csol theme uses several Unicode characters to draw cards and suits. Since DOS doesn't support Unicode I created a new default theme based on Code page 437 which happens to include the exact same characters I was using in the Unicode theme.

The modified source code is available on github. I've also uploaded a zip-file containing the compiled EXE and configuration files. It works in DOSBox, and I was also able to run it directly from a 3.5″ floppy on my Toshiba T2130CS with a 486. It should also work on older 386 and 286 machines.

For a while I'd wanted to take the actual site generator and template language from TEXTSTEP and spin it out into its own project. I was hoping this would be a simple task, and that I could quickly cobble together something in C. Why C? Familiarity and performance. In hindsight, some tasks were probably way more time consuming than they would have been if I had chosen to use something other than C, and overall everything took a lot longer than I had originally anticipated.

I initially named this project tsc (“the TEXTSTEP compiler”), but when I later realized that “tsc” is actually the TypeScript compiler, I renamed it to Plet (derived from the word “templet”, an archaic form of the word “template”). Thus Plet is now the name of the static site generator I've built, as well as the programming language used for writing Plet templates and scripts.

The Plet source code is available on GitHub and the documentation (still work in progress) is available on docs.plet.info (automatically deployed from the Plet repository using Plet and GitHub Actions). There are currently only two examples of sites created using Plet: This blog, and the Plet documentation.

Some of the features currently offered by Plet are:

  • Automatically resizes images using ImageMagick
  • Pagination
  • Built-in web server that compiles pages on demand and automatically reloads when changes are detected
  • High level of flexibility via built-in programming language

The flexibility comes at the cost of usability since at the moment you pretty much have to learn a new programming language before you can put together a website. I'm hoping that in the future I'll be able to improve this with a set of premade themes as well as commands for quickly setting up common site structures without having to worry about anything other than typing the actual content of the website in Markdown. Plet also at the moment only compiles on Linux (mostly because of the low-level APIs used for the built-in web server) which is something I'd also like to fix at some point.