C# – XBox 360 Controller library with a sample application

Created an easy to use XBox 360 Controller library in C# (with a sample application) using the SharpDX.XInput managed .NET wrapper of the DirectX API.

 https://github.com/okmer/XBoxController

Screenshot of the sample application.
Screenshot of the sample application.

A BUG in SharpDX.XInput ci-ci217, resulting in issues with the  left Thumb Stick, Left Trigger, and Right Trigger! Please stick to SharpDX.XInput v4.1.0-ci184 for now.

using System;

using Com.Okmer.GameController;
 
namespace XBoxSampleConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            XBoxController controller = new XBoxController();

            //Connection
            controller.Connection.StateChanged += (s, e) => Console.WriteLine($"Connection state: {e.State}");
 
            //Battery
            controller.Battery.LevelChanged += (s, e) => Console.WriteLine($"Battery level: {e.Level}");
 
            //Buttons A, B
            controller.A.StateChanged += (s, e) => Console.WriteLine($"A state: {e.State}");
            controller.B.StateChanged += (s, e) => Console.WriteLine($"B state: {e.State}");
            
            //Buttons D-Pad Up, Down, Left, Right
            controller.Up.StateChanged += (s, e) => Console.WriteLine($"Up state: {e.State}");
            controller.Down.StateChanged += (s, e) => Console.WriteLine($"Down state: {e.State}");

            //Thumb Positions Left, Right
            controller.LeftThumb.PositionsChanged += (s, e) => Console.WriteLine($"Left thumb X: {e.X}, Y: {e.Y}");
            controller.RightThumb.PositionsChanged += (s, e) => Console.WriteLine($"Right thumb X: {e.X}, Y: {e.Y}");
 
            //Rumble at the speed of the trigger position
            controller.LeftTrigger.PositionChanged += (s, e) => controller.LeftRumble.Speed = e.Position;
            controller.RightTrigger.PositionChanged += (s, e) => controller.RightRumble.Speed = e.Position;
 
            //Wait on ENTER to exit...
            Console.ReadLine();
        }
    }
}

Around the world in 90 days

Traveling around the world in 90 days with my pregnant wife 🙂 See you later alligator!

AMS-LHR, LHR-YVR, YVR-LAX, LAX-HNL, HNL-NRT, NRT-TPE, TPE-HKG, HKG-PNH, REP-KUL, KUL-SYD, SYD-CNS, ASP-CNS, CNS-HKG, HKG-AMS
AMS-LHR, LHR-YVR, YVR-LAX, LAX-HNL, HNL-NRT, NRT-TPE, TPE-HKG, HKG-PNH, REP-KUL, KUL-SYD, SYD-CNS, ASP-CNS, CNS-HKG, HKG-AMS

Canada, Hawaii, Japan, Taiwan, Cambodia, Malaysia, and Australia…

AMS LHR 258° (W) 256° (W) 371 km
LHR YVR 324° (NW) 324° (NW) 7,601 km
YVR LAX 165° (S) 149° (SE) 1,739 km
LAX HNL 261° (W) 249° (W) 4,113 km
HNL NRT 299° (NW) 290° (W) 6,146 km
NRT TPE 242° (SW) 250° (W) 2,182 km
TPE HKG 249° (W) 254° (W) 807 km
HKG PNH 220° (SW) 223° (SW) 1,533 km
REP KUL 191° (S) 192° (S) 1,202 km
KUL SYD 133° (SE) 133° (SE) 6,579 km
SYD CNS 343° (N) 330° (NW) 1,966 km
ASP CNS 060° (NE) 056° (NE) 1,454 km
CNS HKG 320° (NW) 314° (NW) 5,553 km
HKG AMS 324° (NW) 327° (NW) 9,290 km

Total: 50,537 km

Duck Hunt VR (for the HTC Vive)

My first little Unity 3D Virtual Reality project, inspired by my old friend the Nintendo Entertainment System. Please keep in mind the I have never used Unity 3D before, so this is my first sandbox application…

Download link to DuckHuntVR Alpha 04: http://tinyurl.com/hb3u42x

This Alpha 04 release incorporated a lot of used feedback from the Vive subreddit: https://www.reddit.com/r/Vive/

In particular the feedback gathered during this live coding session: https://www.reddit.com/r/Vive/comments/4pbx4x/duck_hunt_vr_for_the_htc_vive_alpha_03_this_is_a/

C# – MutableWhen Extension for the Task Parallel Library (TPL)

This is a little playful MutableWhenAny and MutableWhenAll extension for the Task Parallel Library (TPL), using a ObservableCollection.

The extension makes it possible to add or removed tasks to/from an ObservableCollection<Task> while the MutableWhenAny or MutableWhenAll is used to wait on the tasks in this (mutable) collection.

 https://github.com/okmer/MutableWhen

It’s not super useful in practice, but a nice little exercise that combines to cool C# features into a fun asynchronous “magic” trick.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Threading;
using System.Threading.Tasks;
 
namespace Com.Okmer.Extensions.ObservableCollectionOfTask
{
    public static class ObservableCollectionOfTaskExtention
    {
        private const int INFINITE = -1;
 
        public static async Task MutableWhenAll(this ObservableCollection<Task> collection)
        {
            await MutableWhenSomething(collection, Task.WhenAll);
        }
 
        public static async Task MutableWhenAny(this ObservableCollection<Task> collection)
        {
            await MutableWhenSomething(collection, Task.WhenAny);
        }
 
        private static async Task MutableWhenSomething(this ObservableCollection<Task> collection, Func<IEnumerable<Task>, Task> whenSomething)
        {
            Task waitAllTask = null;
            Task helperTask = null;
 
            bool isCollectionChanged = false;
 
            do
            {
                //Cancellation on collection changed event
                var cts = new CancellationTokenSource();
                var cancelActionHandler = (sender, arg) => cts.Cancel(false);
                collection.CollectionChanged += cancelActionHandler;
 
                //Current collection
                waitAllTask = whenSomething(collection);
 
                //Wait on current collection or collection changed event
                try
                {
                    helperTask = Task.Delay(INFINITE, cts.Token);
                    await Task.WhenAny(waitAllTask, helperTask);
                }
                finally
                {
                    isCollectionChanged = cts.IsCancellationRequested;
                    cts.Cancel(false);
                    cts.Dispose();
                    collection.CollectionChanged -= cancelActionHandler;
                }
            }
            while (isCollectionChanged);
 
            //Return the WaitAll on collection results
            await waitAllTask;
        }
    }
}

A simple example application that demonstrates the MutableWhenAll extension on an observable collection of tasks. The longest running task is added to the observable collection after MutableWhenAll is called, but the MutableWhenAll will complete only when all tasks (included this longest running task) are completed.

using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
 
using Com.Okmer.Extensions.ObservableCollectionOfTask;
 
namespace MutableWhenAllTest
{
    class Program
    {
        static void Main(string[] args)
        {
            ObservableCollection<Task> tasks = new ObservableCollection<Task>();
 
            Task t1 = Task.Run(async () => { await Task.Delay(1000); Console.WriteLine("t1"); });
            Task t2 = Task.Run(async () => { await Task.Delay(2000); Console.WriteLine("t2"); });
            Task t3 = Task.Run(async () => { await Task.Delay(3000); Console.WriteLine("t3"); });
 
            tasks.Add(t1);
            tasks.Add(t2);
 
            Task a1 = tasks.MutableWhenAll();
 
            tasks.Add(t3);
 
            a1.ContinueWith(t =>
            {
                if (t.IsCanceled)
                {
                    Console.WriteLine("Canceled");
                }
 
                if (t.IsFaulted)
                {
                    Console.WriteLine("Faulted");
                }
 
                if (t.IsCompleted)
                {
                    Console.WriteLine("Completed");
                }
            });
 
            a1.Wait();
 
            Console.ReadLine();
        }
 
    }
}

EvilDir, create an EVIL named directory in Windows

A little “fun” Qt5 console application to create a directory (a.k.a. folder) ending with a space character (” “). This directory can not be removed with standard Windows tools, including most console applications.

#include <QCoreApplication>
#include <QDir>

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);

  QString evil_dir_name("Remko is a little Evil !!! ");

  for(int i=1; i<a.arguments().count(); i++)
  {
    if(a.arguments().at(i).compare("-d", Qt::CaseInsensitive) != 0)
    {
      evil_dir_name = a.arguments().at(i);
      evil_dir_name.append(" ");
      break;
    }
  }

  if(a.arguments().contains("-d"))
  {
    if(QDir(evil_dir_name).exists())
    {
      QDir().rmdir(evil_dir_name);
    }
  }
  else
  {
    QDir().mkdir(evil_dir_name);
  }
 
  return 0;
}

Color Picker 1.1

I build a simple Color Picker 1.1 application that samples the pixel color under the mouse cursor point (because I needed it). The application is a stand alone (static build) Qt5 application with some minor Win32 API stuff, to sample the color at the cursor position.

ColorPicker 1.1

The application supports a number of RGB based color formats and formating formats. The application can run in the background, and used the CTRL+1, CTRL+2, and CTRL+3 hotkey combinations to sample a color in one of its three sample slots. The CTRL+SHIFT+1, CTRL+SHIFT+2, and CTRL+SHIFT+3 hotkey combinations can be used to copy the sample slot content to the clibboard. This enables easy copy and paste access to the sampled color values.