Blog

HID Wiimote Gamepad 0.2.7.0

Rather small technical changes for HID Wiimote. First one is primary a fix for Unity3D, when you want to use the Wiimote as gamepad. Unity3D uses RawInput instead if DirectInput, when reading from generic non XInput Gamepads. It seems RawInput has some issues with axes that have a negative value range, e.g. -127 to 127. So the change is to simply use a value range from 0 to 255.

The support for the Balance Board and Guitar Hero Guitar are completely untested and therefore pure experimental. I do not have a Balance Board nor a Guitar, therefore i am not able to test it(i might get a Balance Board in February). So use on your own risk, but you are welcome to report any issues and i’ll attempt to fix them.

Downloads are available on the HID Wiimote page.

Changes

  • Fix RawInput not reading the primary axes correctly
  • Add experimental untested Balance Board support
  • Add experimental untested Guitar Hero Guitar support

Current State of Windows HIDAPI and Wiimotes

Introduction

This is a small follow up on my testings. Long time it was believed that the PlusInside Wiimotes (“-TR”) are not working with the default Bluetooth Windows Stack. Every program and library recommends the common Toshiba Bluetooth “hack” to get “-TR” Wiimotes and Wii U Pro controllers working on Windows. I did some research with the HIDAPI on Windows and came to the result, that on Windows 8 and above using the proper API Calls, “-TR” Wiimotes, as well as the Wii U Pro Controller is working perfectly fine.

I implemented and fixed the Wiimote Code in the Dolphin Project, which also lead to improved Wiimote Audio for “-TR” Wiimotes.

TLDR;

Using the proper API Calls the Toshiba Bluetooth Stack is not needed anymore on Windows 8 and above. Both Wiimotes types (TR & non-TR) and the Wii U Pro are working fine. Here is the code repository of my test program.

The following post is basically just a copy & paste of the Readme, as it got quite extensive.

Windows 7

The API Calls would also work fine on Windows 7, but there is a bug in the Microsoft HID Class Driver. This renders the “WriteFile”-Method unusable on Windows 7, therefore it is not possible to use the HIDAPI to send data to “-TR” Wiimotes.

HIDAPI

Sending & Receiving

Sending HID Reports:

Recieving HID Reports:

The MSDN Design Guides Sending HID Reports and Obtaining HID Reports are stating, that WriteFile and ReadFile are the preferred methods to send and recieve data from the device. Additionally sending data to a “-TR” Wiimote via WriteFile is working fine, whereas using HidD_SetOutputReport will result in the Wiimote turning off.

Issues with WriteFile

As the MSDN Desgin Guide Sending HID Reports by Kernel-Mode Drivers (WriteFile will send out an IRP_MJ_WRITE request to the driver interface) suggests, the output report buffers shall have the size of the largest output report supported by the device. In case of the Wiimote this is 22 Byte.

This seems to be currently enforced by the Microsoft HID Class Driver on Windows 7 and the Toshiba Bluetooth Stack, as they will fail WriteFile attempts with the error ERROR_INVALID_USER_BUFFER, when the buffer size is less.

On Windows 7 however more bytes than the acutal report are sent to the device, which produces an error on the Wiimote. It is unknown whether this is a bug or intented behaviour. The Toshiba Bluetooth Stack in contrast only sends the appropiate amount of bytes according to the used report to the device.

On Windows 8 and higher, the output report buffer can be arbitrary in size, as the given amount of byte are submitted to the device.

This results in the following table of compability.

Table of compability

x Toshiba Stack Win 7 Win 8.1 Win 10
WriteFile Largest Report Size +
WriteFile Acutal Report Size + +
SetOutputReport +* +* +*

* does not support “-TR” when connected via Bluetooth

Method Priority Order

This leads us to the following order of prioritized methods:

  1. Detect whether the Microsoft Stack or the Toshiba Stack is used for the Wii Remote.
  2. In case of Toshiba Stack, use WriteFile with the largest report size for the buffer
  3. In case of Microsoft Stack, try WriteFile with the actual report size
  4. If WriteFile fails, fall back to HidD_SetOutputReport

Detecting Stack

To detect the used stack for the Wiimote, the provider property of the used HID Class Driver is evaluated. As the enumerated Wiimote Devices are just raw PDO’s, that are acting as interfaces for the HID Class Driver and don’t have a driver directly associated with, it is neccessary to move one node up in the device tree to get to the device node that is associated with the HID Class Driver. To do so the PnP Configuration Manager API is used.

Why WriteFile supports “-TR”

It is believed, that the usage of HidD_SetOutputReport will result in sending the output report via the Control Channel. This is not supported by “-TR” Wiimotes, as they will immediately shut down. In contrast WriteFile seems to send the data to device via the Interrput/Data Channel.

DolphinBar

The Mayflash DolphinBar enumerates Wiimotes as USB Devices, resulting in using the Microsoft HID Class Driver. Therefore WriteFile won’t work on Windows 7 for Wiimotes connected through the DolphinBar either. However as the DolphinBar takes care of the Bluetooth communication and the outgoing data is send via USB to the DolphinBar, HidD_SetOutputReport does support “-TR” Wiimotes as long as they are connected through a DolphinBar.

HID Wiimote 0.2.6

New Year; i am back in Berlin and can continue to work on HID Wiimote. Yay!

Rather small update with just one and a half fix. Regarding the connectivity issue on Windows 10 Version 1511, i had no issues while testing. Therefore i assume either the updated WDK or another Windows update fixed it. If the problem persists, please report back, so i can take another look at it.

Direct Download Links: Gamepad, IR-Mouse, DPad-Mouse

Links have been replaced with Hotfix 0.2.6.1 0.2.6.2: The installer had some problems on non English Windows Systems (and then i messed up the installer config).

Changes

  • Fix #11: Improved Extension Controller detection
  • Package now includes EULA and Readme file
  • Replaced Multilingual Driver Package Installer with only-English one
  • Introduced proper versioning, starting with 0.2.6
  • Build with WDK 10.0.10586.15, to hopefully fix connectivity issues with Windows 10 Version 1511 (November Update)

Overgrowth – Sonen GameJam Fall 2015

Overgrowth is my game for the Sonen GameJam at University of Oslo in Fall 2015.
The Theme was “Abandoned”. It is a JavaScript HTML 5 game that can be played in the browser.

Synopsis: The map is wasteland like, that has been left and abandoned after some sort of catastrophe (let it be a nuclear disaster). The green stuff is kind of radiation empowered fauna. It grows quickly and aggressively. Your task is to reclaim the area, by activating the “Degenerator”.

Gameplay: You have towers (boxes with T inside) that can shoot lasers to remove the overgrowth. Those towers have an energy pool that gets drained when shooting the laser. The energy is replenished by connected generators (smaller boxes with G inside). When a building is covered by the green stuff up to a certain percentage, it stops working. So don’t forget to clean your buildings regularly. In the top right corner are three “skills”. The first one is the ordinary laser. The second and third one are construction skills, to place new towers and generators. Towers can be placed anywhere on the map (i think there is a but near the edges of the map). But remember that they are inactive when covered by green. Generators must be placed within a certain range to towers and automatically connect to the nearest tower.

Task: You main goal is to clean the “Degenerator” so it gets activated. It does not need any generators. When activated it starts working and clears the wasteland. You loose if your last tower is deactivated by the overgrowth.

The game can be played in the browser here: http://gamejam.julianloehr.de/sonen-15/
The source code is available on Github: https://github.com/jloehr/SonenGameJam-2015

 

HID Wiimote Windows 10 Builds

Nyhet!

HID Wiimote Windows 10 Builds

Some more information

From now on there will be a unified build for Windows Desktop systems. The new WDK 10 makes it possible and in return it means less mess with different packages.

This build has nothing new except that is has been rebuild with the newest Visual Studio 2015 and Windows Driver Kit 10. So for non Windows 10 users there is no urgent need to download/update it. But you can if you like to, just make sure to uninstall the previous/old driver.

This new build was tested on a Windows 10 system with a build-in Bluetooth adapter and a separate Bluetooth Dongle, as well as on a Windows 8.1 system with a Bluetooth Dongle. I wasn’t able to test it on Windows 7, because i have currently no Windows 7 system here around, so please report back if there is any issue.

Windows 10 Universal Driver: Coming Soon™

So this is a multi-system Desktop build and not an Universal Driver. I am going to provide an Universal Driver as well soon, but there is some work to be done. The driver compiles fine and without any error. The only issue is that i have to make an universal .inf file, which simply requires me to read through the MSDN documentation.  However, i am currently not able to test the Universal Driver on a Windows Phone nor on an IoT-System, so the build is going to be purely experimental and for people that just want to give it a try.

I am also not quite certain about the driver signing regarding the Universal Driver. I have no clue whether it is possible to deactivate the driver verification on Mobile and IoT-Systems and get an unsigned driver loaded. I would assume there is some way, because devs need the ability to test drivers on the device, but that might require additional test modes, which in turn may have side effects.

Changes

  • Windows 10 Desktop Build

8 Tips for People that have to deal with C all of a sudden

Back at my home university in Berlin, as well as here in Oslo and i assume also at other universities, students learn mainly Java. They may have a single C course about the language, but that is all. Not a big problem, because all other courses are featuring Java as language as well. Until at the end of their studies, sometimes in the master degree studies, they encounter a course that is focused on high performance highly optimized C code, with a lecturer that expects everyone to be well familiar with C.

So i am providing some tips for coding in C. They are not directly targeted for beginners, more for people coming from a higher language, that have to deal with C all of a sudden. But they may be still helpful for programming beginners.

Disclaimer: Other people may have other opinions about my points. I am not (yet) a C Expert, but this is my current “good advice” opinion. I am open for a discussion, so that i may learn and improve as well.


 

1. Use objects

You can still reassemble something like objects in C. Simply have a header and C file for your object type. In the header define a struct for the object type, that will hold the data of the object. All object methods are defined in its C file and must have a pointer of the object type as parameter. Thereby you can access the data of the object instance. Only methods declared in the header file will be visible to other files that include the header file, so you even have private and public methods. However the object data is all public (although there are also ways to make some variables private but that requires a little bit more afford).

Foo.h

typedef struct _FOO
{
  int Bar;
} FOO, * PFOO;

void DoSomethingWithFoo(PFOO this, int Value);

Foo.c

#include "Foo.h"

static void DoPrivateThingsWithFoo(PFOO this);

void DoSomethingWithFoo(PFOO this, int Value)
{
  DoPrivateThingsWithFoo(this);
  this->Bar = Value; 
}

static void DoPrivateThingsWithFoo(PFOO this)
{
  //Do private
}

2. Use Initialize and Finalize/Clean-Up functions for your objects

If you use objects, every object should have at least an Init-Method and if it deals with dynamic memory, contains another object, or must perform any other form of clean up, should have a Finalize/Clean-Up method too. These are basically the objects Constructor and Destructor, although you have to call them yourself (But that is C, you are in charge of everything). The Init method is important to initialize your variables, so they won’t contain garbage. Remember C does not initialize your variables to default values.

3. Dynamic Memory should have a parent object or should never survive its creating scope

When creating dynamic memory through malloc or calloc, that memory should be either freed in the same scope, or should have a parent object, that is in charge of freeing it. First you won’t create memory leaks so easily this way, because memory is either freed right away, or you have an object, that will free it for you when it is destroyed. Secondly this may help you keeping track of you dynamic memory and not getting confused by passing pointers through your program.

In addition you should not pass dynamic memory up your call stack, instead pass it downwards. Otherwise the risk to loose it is quite high. One exception would be an “Allocate” function, that will have to do some calculations for the allocation, but then the calling function is the scope that has to free it or has to assign it to a parent object.

4. Set invalid pointers to NULL, especially after freeing

More about pointers. Pointers that currently do not point to anything valid should always be set to NULL. This way you can check if they are valid and prevent other errors, like segfaults and double freeing. This goes especially for freeing dynamic memory. Set the pointer right after it to NULL, so you are not able to access it afterwards.

5. Use the <stdint.h> header for integer types

The <stdint.h> header defines several integer types with fixed lengths. The problem with the basic types are that their size depends on the compiler and the system. So other system and/or other compiler and your long is now 4 bytes instead of 8 bytes. Especially when dealing with 32 Bit vs 64 Bit this may be a problem.

So in order to have fixed size integers, the <stdint.h> header defines the following types:

int8_t, int16_t, int32_t, int64_t
uint8_t, uint16_t, uint32_t, uint64_t

The number is the size of the type in bits, and that is regardless of compiler or system.

6. Use the <stdbool.h> header for the bool type

C does not come with a native boolean type. The <stdbool.h> header defines a bool type, as well as the keywords true and false. The advantage of using this header instead of abusing a unsigned char is, that this bool type is somehow partly native and does take care of integer overflow.

7. Use the size_t and ptrdiff_t types for anything regarding memory and pointers.

size_t is an unsigned integral type that is used for sizes of objects and memory. Do NOT ever use int to store the size of a type, object or memory. The two important functions that use this type are sizeof, which will return the size of the type bytes, and malloc, which wants to know how many bytes shall be allocated.

ptrdiff_t, as its name suggests, is used when you want to store the difference of two pointers. Here again, do NOT ever use int to store a pointer difference, though most compilers are going to throw a warning.

Both types are guaranteed to have the appropriate size to store those information.

8. Pointers are increased by their type size

So this is a little more advanced but still somehow important. It is totally valid to increment and decrement pointers. This is especially useful to iterate over an array. But be aware that an increment/decrement of a pointer takes its type size into account. This means incrementing a pointer will not move it by one byte. Instead it will move it by X bytes, where X is the size of the type it is pointing to. So it will point to the next object next to the previous one. This is the reason why pointer arithmetic on void pointers are not valid. The type size is not known, therefore the compiler does not know how far it should move the pointer.


Hope this will eventually help someone. If you have something to add or complain, feel free to leave a comment.

My first impressions of Norway and Oslo

After two weeks here now, it’s time for some impressions and strange things about Norway, that i had not expected.

  1. Hotdogs at IKEA are cheaper than in Germany, but do not come with pickles and roasted onions.
  2. There seem to be more Döner Kebab bars than Hotdog bars. Moreover Döner Kebab all over the city (but not so much like in Berlin).
  3. Securitas! Securitas everywhere! Be it the security guard in the student dorm, security for office buildings, almost every residential house has a Securitas sticker. Even the ticket inspectors on the bus are Securitas people.
  4. NFC public transport tickets. Get a card at a ticket machine, charge it, and then activate your ticket by holding it to an terminal when entering the bus. Neat!
  5. Tickets at the bus driver are more expensive.
  6. Chilled, calm and friendly bus drivers. Never seen one in a hurry or furiously shouting. They are happily waiting for running people that want to catch that very bus.
  7. Very friendly car drivers. They wait very calmly on every zebra-cross, let public buses merge into roundabouts. Never heard a car honking yet.
  8. Overall a lot of roundabouts all over the place, feels a little bit like Britain. Only in the inner city are traffic lights.
  9. Same goes for zebra crossing/crosswalks. No pedestrian lights on the outer skirts, only in the inner city.
  10. Frozen mashed potatoes. We don’t have such in Germany.
  11. Free Bus Shuttles to IKEA with free WiFi.
  12. Free WiFi all over the place. Airplane, Metro, Museum, etc.
  13. Jogger, Cyclist and people in sports/jogging leggings everywhere. I mean i’ve heard they are very sporty, but that’s more than i expected.
  14. Norwegians seem to like Pizza and American Restaurants/Food.
  15. Lots of foreigners in Oslo.
  16. Plenty beggars. At almost every convenience store and every bigger train station. And they are quite active as they approach everyone.
  17. Fast Food restaurants like McDonalds and Burgerking have different prices depending on whether you eat there or take it away.
  18. Norway’s nature is much more beautiful than on pictures.
  19. Moreover the nature begins immediately behind the city boundary. Just one step from your house and you are in a forest.
  20. Stores on a shopping promenade have loudspeakers outside blasting music on the street.
  21. Digital price tags in convenience store.
  22. Separate streets for bicycles and pedestrians only. I’ve seen a bicycle four way intersection.
IMG_1089
Bicycle street in Oslo

HID Wiimote & Stream for the next 5 Months

Some may have wondered, others may have already seen my tweets. I’ve moved to Oslo for a 5 months student exchange program last week. So this means i have only my Laptop with me and that is unfortunately not powerful enough to stream. So for the next 5 months, until January, there won’t be any streams from me 🙁
Also i think i wouldn’t find the time for  streaming, since during student exchanges you have better things to do, like exploring the country and so on.

But when i do have some spare time i am going to try to get some work on HID Wiimote done. So at least i am trying to get official Windows 10 Builds done asap. Hopefully they will be available within the next weeks, but i need to find some spare time to install Windows 10 (twice, once on my Laptop and then a second time on a VM) and then setup my development environment, etc.

Until then you can use the Windows 8.1 builds on Windows 10. Someone mentioned they are working just fine. Just don’t forget to turn on the Testmode.

So at the end a photo i took of the wonderful and idyllic nature here in Norway 😀

Sognsvann
Sognsvann Lake near Oslo

HID Wiimote Source Code available

Wuhu! I have published the Source Code of HID Wiimote on Github.
Some have already asked for it, now i finally did it!

Check it out: https://github.com/jloehr/HID-Wiimote

I am going to fill it with Issues and Milestones in the next days.
But you can add Issues on your own, when encountering a bug.
If you manage to fix a bug, or come up with a cool feature, feel free to contribute.
Fork it, fix it, send a Pull Request!