Battle Isle

Battle Isle 93 You can download Battle Isle 1 (Moon of Chromos) free of charge at Abandonia and you can run it under GNU/Linux using DOSBox (update: DOSBox also runs on Windows and MacOS). Battle Isle is a turn-based strategy game. The game can be played against the computer as well as against another human player. It always runs in split-screen mode. I.e. each player specifies the moves using half of the screen.

Here’s how to run the game (under GNU/Linux) after downloading it

unzip 'Battle Isle 93 - The Moon of Chromos.zip'
cd BI193
dosbox MOON.EXE -exit
cd ..
  • First player keys
    • '⇦', '⇨', '⇩', and '⇧' to move the cursor
    • '⏎' and cursor movement to select action
  • Second player keys
    • 'x', 'v', 'c', and 'd' to move the cursor
    • 'ctrl' and cursor movement to select action

Here’s a gameplay video of the Amiga version of the game.

See also:

Kubuntu 10.04

I finally decided to update my laptop to Kubuntu 10.04 (a distribution of GNU/Linux based on Debian). As usual I used the Live DVD to just rename the /home folder to /old, delete everything else, and mount the partitions in the advanced setup without formatting them (although like this I wasn’t able to make use of the new EXT4 file system). For new users there is an article how to do a graphical installation of Kubuntu.

KDE4 really has some nice eye candy. Also there are themes for many things and you can just download them using the configuration dialogs. Here’s a screenshot of the Kubuntu Spotlight theme I chose for the login manager. Kubuntu Spotlight KDM

For the boot splash animation I used the Spectrum theme. Spectrum Splash Screen

And here is a screenshot of the desktop in action. Kubuntu 10.04 Lucid Lynx (LTS)

The distribution can be downloaded free of charge at http://www.kubuntu.org/. There are few issues with the HP Compaq nx7400 notebook I am using. So far I’ve found the following problems:

  • NetworkManager disables itself before going into standby and doesn’t come back when disconnecting power during standby mode (one needs to edit the file /var/lib/NetworkManager/NetworkManager.state). Also when using another tool such as pppoeconfig, NetworkManager will disable itself using another configuration file (one needs to edit the file /etc/NetworkManager/nm-system-settings.conf).
  • VoIP settings: One needs to switch everything in Twinkle to ALSA/Default.
  • When not terminated properly, Amarok gives the error message “Amarok is already running!” even though it is not running.
  • Sometimes one needs to restart Amarok because it stops playing after every song.
  • The Shoutcast list is not included in Amarok any more but there is an Amarok script for adding Shoutcast to Amarok.
  • I had to install msn-pecan because Pidgin’s default implementation for MSN has issues.
  • Pidgin won’t connect to ICQ unless Use clientLogin is checked in the advanced account settings.
  • The waste bin has become a plasma widget which is not on the desktop by default.
  • As usual one needs to fetch additional codecs and libdvdcss from the Medibuntu repository in order to be able to play videos using patent-encumbered codecs and DVDs.
  • The file associations for PDF documents are configured to prefer the proprietary Acrobat Reader over the Okular free software.
  • WPA2 wireless keeps disconnecting (iwl3945 driver, deauthenticating by local choice (reason=3)). Installing install the linux backports modules doesn’t seem to help either at this point in time.
  • The default output device for mplayer is xmga. You need to change it to xv.
  • One of the ALSA volume controls for the microphone seems to be mislabelled as the ‘Digital’ input.

Update:

I posted about listing manually selected packages with aptitude on the Ubuntu Forum. This is very useful for generating the command line for installing the same set of packages on a new machine (e.g. my new HP G56-108SA ;)). One can list the manually selected packages as follows:

aptitude search '!~M ~i' -F '%p'

I.e. you can run the following command on one machine:

echo aptitude install `aptitude search '!~M ~i' -F '%p'` > install.sh

Then you copy the resulting file install.sh to the target machine and run

sh ./install.sh

Basically !~M selects not automatically selected packages and ~i selects installed packages. See content of package aptitude-doc-en for more information.

Note that you might have to manually modify the file install.sh if the package names on the target system are different (e.g. 32-bit vs. 64-bit, other proprietary wireless driver, …).

Update:

Here’s a nice example of a dual-screen desktop running the same Kubuntu version.

See also:

Talk at Sheffield Ruby User Group

Machine Vision made easy with Ruby

I am going to give a presentation about Hornetseye at the Sheffield Ruby User Group (ShRUG). The meeting is on Monday June 14th from 7pm to 9pm at the GIST Lab in Sheffield Workstation. For more details see corresponding page on ShRUG website. Please register here if you want to attend.

I hope people will find the GIST lab. It’s the first side entrance to the Workstation when you walk down the small alley to the right of the building (as seen from Brown street). Also see Google Streetview.

Here is the source code of the main program

#!/usr/bin/env ruby
require 'hornetseye'
require 'x11test'
include Hornetseye
SHAPE = [ 320, 240 ]
DISPLAY = [ 320, 240 ]
SIZE = SHAPE[ 0 ] * SHAPE[ 1 ]
SIGMA = 1.5
ERROR = 1.0 / 32.0
THRESHOLD = 10
SKIP = 10
CAPTION = [ 'pointer' ]
RANGE = 0.001 .. 0.25
TIME = 0.3
ACCEL = 5
SPEED0 = 4
SPEED1 = 20
old_x, old_y = nil, nil
display = X11Display.new
output = ( 0 ... CAPTION.size ).collect { XImageOutput.new }
window = output.collect { |out| X11Window.new display, out, *DISPLAY }
window.zip( CAPTION ).each { |win,cap| win.title = cap }
window.each { |win| win.show }
input = DC1394Input.new '', 0, 0,
        DC1394Input::FORMAT_VGA_NONCOMPRESSED,
        DC1394Input::MODE_320x240_YUV422
index = MultiArray.int( *SHAPE ).indgen!
x, y = index % SHAPE[ 0 ], index / SHAPE[ 0 ]
border = MultiArray.int( *SHAPE ).fill! 1
border[ 1 ... SHAPE[ 0 ] - 1, 1 ... SHAPE[ 1 ] - 1 ] = 0
SKIP.times { input.read }
bg = input.read_sint
t_on, t_off = 0, 0
a = 0
while display.status?
  img = input.read_ubyte
  binary = img - bg <= THRESHOLD
  components = binary.components
  n_components = components.max + 1
  area = components.hist n_components
  mask_area = area.between? RANGE.min * SIZE,
                            RANGE.max * SIZE
  mask_border = components.
    hist_weighted( n_components, border ).eq 0
  mask = mask_area.and mask_border
  map = mask.to_ubyte.integral * mask.to_ubyte
  target = components.map map
  output[ 0 ].write target.normalise( 0 .. 127 ) + img / 2
  n_targets = target.max + 1
  t = Time.new.to_f
  if n_targets == 2
    sum_target = target.sum.to_f
    x_target = x.mask( target.to_bool ).sum / sum_target
    y_target = y.mask( target.to_bool ).sum / sum_target
    if old_x and old_y
      d_x, d_y = old_x - x_target, old_y - y_target
      if d_x.abs + d_y.abs < ACCEL
        d_x *= SPEED0
        d_y *= SPEED0
      else
        d_x *= SPEED1
        d_y *= SPEED1
      end
      display.
        fake_relative_motion_event d_x.to_i, d_y.to_i, 0
    else
      t_on = t
    end
    if t_off + TIME >= t
      display.fake_button_event 1, true, 0
      t_off = -1
    end
  else
    x_target, y_target = nil, nil
    if old_x and old_y
      display.fake_button_event 1, false, 0 if t_off == -1
      t_off = t
    end
    if t_on + TIME >= t
      display.fake_button_event 1, true, 0
      display.fake_button_event 1, false, 100
      t_on = 0
    end
  end
  old_x, old_y = x_target, y_target
  display.processEvents
end

And below follows the source code of the Ruby extension for adding pointer control to the HornetsEye library

#include <X11/extensions/XTest.h>
#define HAVE_X11
#include "rubytools.hh"
#include "x11display.hh"

using namespace Hornetseye;

VALUE wrapFakeButtonEvent( VALUE rbSelf,
                           VALUE rbButton,
                           VALUE rbPress,
                           VALUE rbDelay )
{
  Display *display = XOpenDisplay( NULL );
  XTestFakeButtonEvent( display, NUM2INT( rbButton ),
                        rbPress != Qfalse ? True : False,
                        NUM2INT( rbDelay ) );
  XCloseDisplay( display );
  return rbSelf;
}

VALUE wrapFakeRelativeMotionEvent( VALUE rbSelf,
                                   VALUE rbX,
                                   VALUE rbY,
                                   VALUE rbDelay )
{
  Display *display = XOpenDisplay( NULL );
  XTestFakeRelativeMotionEvent( display,
                                NUM2INT( rbX ),
                                NUM2INT( rbY ),
                                NUM2INT( rbDelay ) );
  XCloseDisplay( display );
  return rbSelf;
}

extern "C" {

  void Init_x11test(void)
  {
    rb_require( "hornetseye" );
    VALUE mHornetseye = rb_define_module( "Hornetseye" );
    VALUE cX11Display =
      rb_define_class_under( mHornetseye, "X11Display", rb_cObject );
    rb_define_method( cX11Display, "fake_button_event",
                      RUBY_METHOD_FUNC( wrapFakeButtonEvent ), 3 );
    rb_define_method( cX11Display, "fake_relative_motion_event",
                      RUBY_METHOD_FUNC( wrapFakeRelativeMotionEvent ),
                      3 );
  }

}

See also:

Patent Absurdity

Patent Absurdity movie poster

The Free Software Foundation has released a short film about software patents called Patent Absurdity. The film features interviews with Eben Moglen, Karen Sandler, Richard Stallman, Jesse Vincent, and other people involved with the Bilski case.

The Bilski case hopefully will help putting a stop to the rampant practise of patenting applications of mathematics, algorithms, and other abstract concepts to real life problems. To freely quote Bruce Perens (panel discussion at WSIS in Tunis): Mathematics is a field that is discovered - not invented!

See also:

Using Twinkle for VoIP

Twinkle is my favourite software for making VoIP calls (under GNU/Linux). Here is how you configure it if you have an account with VoIPTalk.

Configuring the user

Enter your user details. Note that the SIP password is different from the password to log in on the VoIPTalk website. Log in on the VoIPTalk website and click on VoIPtalk ID to view VoIPtalk (SIP) password. User

SIP server

Here you enter the details for the outbound proxy. SIP server

NAT

For firewall traversal you need to specify a STUN server. NAT

Alternatively you can set up port forwarding on your router. Then you don’t need to specify a STUN server. In any case make sure that your firewall doesn’t block SIP traffic. You can call sip:905@voiptalk.org in order to test whether the configuration works.

I recommend using G.711 u-law as preferred audio codec.

Update:

In Kubuntu 10.04 you have to set all audio devices (input, output, and ringtone) to ALSA/Default.

There is a freeware VoIP client for Microsoft Windows called X-Lite.

See also: