Miix 2, Cheap BT Keyboard and AHK
Sunday 20th of July 2014 10:35:33 PM

I recently decided to replace my creaky old Acer Aspire One netbook with a brand new Lenovo Miix 2 8". So far I'm pretty happy with it, despite a couple of minor niggles. Having a full Windows desktop available in such a compact form is rather convenient. This convenience is marred however by a lack of physical keys, so I decided to search for an external keyboard solution.

What I settled for is one of these IVSO keyboard cases from Amazon. This keyboard has quite a few things I like about it. Firstly, it's quite cheap. Secondly the keyboard is held in place by a magnet which means it can be removed quite easily if you want a table form factor. Pairing with the device is a doddle, and I've been really impressed with the battery life. Finally the shape of the keyboard reminds me of a 48k Spectrum.

It's not all good however. Firstly the layout is rather cramped (and also an American one). As I type this I'm still getting used to using the Fn key to toggle certain symbols (like ' and @). This I accept, as every compact keyboard will have an associated learning curve. The biggest annoyance I had with it is that I was seemingly unable to use the Alt-F4 combo to close a window; one of my most used short-cuts. Fortunately I've found a solution in the form of a piece of software called Auto Hot Key

I've only started to scratch the surface with this fantastic piece of software. Using the key history feature of AHK I was able to diagnose that when I was hitting the Alt key, it was actually registering as a Ctrl-RAlt combo thus rendering the Alt-F4 combo useless. Using the following script I change Ctrl-RAlt-F4 to send an Alt-F4 combo:

^>!F4::
Send !{F4}
return
	

As I use the keyboard more I'm sure I'll find other ways of making it more usable through the use of AHK scripts.

Critically Damped Springs
Saturday 11th of May 2013 10:36:59 AM

This class is one I turn to it again and again, especially when animating OSD components or creating camera controllers.

What it does is update an object's position and velocity towards a target destination over an arbitrary amount of time. The spring velocity will be damped over time meaning it slows down as it reaches its target.

To use it as a camera spring create one for the camera position and another for the target and update these values every frame, then call Update() passing the frame delta.

using Microsoft.Xna.Framework;

namespace Utils
{
    public class CriticallyDampedSpring
    {
        public CriticallyDampedSpring()
        {
            SmoothTime = 100.0f;
        }

        public float SmoothTime { get; set; }
        public Vector3 Current { get; set; }
        public Vector3 SpringVelocity { get; set; }
        public Vector3 Target
        {
            get { return mValTo; }
            set
            {
                mValFrom = Current;
                mValTo = value;
            }
        }

        public void Update(float frameTime)
        {
            Vector3 diff, temp;
            float omega, rX, expo;

            omega = 2.0f / SmoothTime;
            rX = omega * frameTime;
            expo = 1.0f /
                (1.0f + rX +
                (kQuadraticCoef * rX * rX) +
                (kCubicCoef * rX * rX * rX));

            diff = mValFrom - mValTo;
            temp = (SpringVelocity + (diff * omega)) * frameTime;
            SpringVelocity = (SpringVelocity - (temp * omega)) * expo;

            Current = mValTo + ((diff + temp) * expo);
        }

        // Start position of spring head
        private Vector3 mValFrom = Vector3.Zero;
        
        // Target position of spring head
        private Vector3 mValTo = Vector3.Zero;     

        private const float kQuadraticCoef = 0.48f;
        private const float kCubicCoef = 0.235f;

    }
}
    
Devil's Dyke at Night
Sunday 27th of January 2013 02:43:13 AM

I've been meaning to experiment with very long exposures for some time now. When a friend suggested we head up to Devil's Dyke to do some night photography I thought it was a great idea. We probably should have chosen a night with better weather; it was incredibly windy and there were several moments where the wind nearly knocked my tripod over.

Unfortunately I forgot to bring the remote for my camera, so the only exposures I could get were 30 second ones, but we got some nice results. You can see the images here.

The Devil Makes Work...
Saturday 30th of June 2012 11:22:48 AM

Boredom's a terrible thing but the website Dinosaur Comics is not. So when, in the midst of holiday boredom I stumbled across this comic I decided have a go at implementing it.

I don't often get to use PHP so I decided it'd be a good excercise for me to use the language. There's a few implementations of this online but mine's the only one I've seen which handles the "[goto panel two and play recursively] / [choose any ol' noun from the dictionary]" block.

You can see it in action here.

<?php
function RandomBool()
{
    return 0.01 * rand(0, 100) >= 0.5;
}

function RandomLine($filename)
{
    $lines = file($filename);
    return $lines[array_rand($lines)];
}

function GetPrefix($noun)
{
    $vowels = array("a", "e", "i", "o", "u");

    if(in_array(strtolower($noun[0]), $vowels))
    {
        return "an";
    }
    else
    {
        return "a";
    }
}

function RandomNoun()
{
    return trim(RandomLine("../protected/data/nouns.txt"));
}

function RandomFromArray($array)
{
    $key = array_rand($array);
    return $array[$key];
}

function CharacterType($index)
{
    $adjectives = array(
        array("meat", "robot", "urban", "silver", "animal",
            "sex", "fruit", "adult", "child", "famed",
            "licensed", "problem"),
        array("meaty", "famous", "infamous", "wide-eyed",
            "sullen", "attractive", "competing", "powerful",
            "space", "hairy", "social"));

    $nouns = array(
        array("stylist", "engineer", "astronaut", "ecologist",
            "planner", "model", "smith", "dancer", "producer",
            "lawyer", "loner", "priest", "criminal", "prodigy",
            "terrorist", "dinosaur", "clone", "athelete",
            "head of state"),
        array("teen", "doctor", "ghost", "artist", "surgeon",
            "corsetièr", "superhero", "cartoonist",
            "spouse", "dog", "religion",
            "medical health professional", "senior", "telepath",
            "jerk", "family"));

    $adj = RandomFromArray($adjectives[$index]);
    $noun = RandomFromArray($nouns[$index]);
    $prefix = GetPrefix($adj);

    return $prefix . " " . $adj . " " . $noun;
}

function BuildCharacter()
{
    $verbs = array("create", "destroy", "get over", "bewitch",
        "unmask", "sex up", "steal", "hug", "give birth to",
        "team up with", "profit from");

    $result = CharacterType(0);

    $result = $result . " who wants to " . RandomFromArray($verbs) .
        " " . CharacterType(1);
    $result = $result . " but is blocked in this desire by ";

    if (RandomBool())
    {
        $result = $result . BuildCharacter();
    }
    else
    {
        $noun = RandomNoun();
        $prefix = GetPrefix($noun);
        $result = $result . $prefix . " " . $noun . ".";
    }

    return $result;
}

echo BuildCharacter();
?>
    
Crush 3D Released
Tuesday 13th of March 2012 04:37:56 PM

Today marks the launch of Crush 3D. This is an updated version of the celebrated PSP game Crush which we developed back in 2007 for Sega.

Crush is a mind-bending puzzle platformer which revolves around a clever mechanic which allows you to 'crush' the world from 3D into 2D. This allows you to overcome obstacles which would otherwise prevent you collecting in game items, ultimately unlocking the level's exit.

Crush 3D has been updated for the new Nintendo 3DS platform to take advantage of the system's exclusive features, such as Street Pass and stereoscopic 3D. It's also been given a colourful new facelift and art which takes advantage of the systems graphics capabilities.

Here's the info from Nintendo.