ETS2/ATS have a problem with more than one simultaneously attached Arduino's (or other identical input hardware). This is the scenario:
- gear box knob with inbuild Arduino Micro
- self-build dashboard with Arduino Micro
In the controller settings, the game let you choose both controllers, but only one of them will be recognized. A closer look into your controls.sii shows the problem:
Code: Select all
...
config_lines[5]: "device joy2 `di8.'{A5E0C7C0-0C33-11EC-8001-444553540000}|{80372341-0000-0000-0000-504944564944}'`"
config_lines[6]: "device joy3 `di8.'{A5E0C7C0-0C33-11EC-8001-444553540000}|{80372341-0000-0000-0000-504944564944}'`"
...
In the meanwhile, I have a workaround. You have to enumerate your input devices by yourself and then correct the related lines in your controls.sii. The enumeration is the tricky part. Windows doesn't provide a ready-to-use helper for that. So, you can download this self-programmed small console application
Download (20 kB only)
or - if you think, it could be evil - bake your own (source code at the end of this post). The application produces an output like that:
Code: Select all
Currently connected DirectX input devices
di8.'{23B664D0-0283-11EC-8001-444553540000}|{C266046D-0000-0000-0000-504944564944}'
di8.'{A5E0C7C0-0C33-11EC-8001-444553540000}|{80372341-0000-0000-0000-504944564944}'
di8.'{A4596930-165F-11EC-8001-444553540000}|{80372341-0000-0000-0000-504944564944}'
press any key to leave this console
These are the identifier strings in SCS controls.sii manner. Every line consists of two so-called GUID's, the instance GUID and the product GUID. The product GUID (the second one) starts with the product and vendor id (here 80372341), four chars each. The first four chars are the PID and the latter the VID (here: VID 2341 = Arduino SA, PID 8037 = Arduino Micro). The first line isn't interesting for us (here: it's the Logitech (046D) Racing Wheel G923 (C266). Line two and three are the important ones. As you can see, here we have two different instance id's. These id's we have to copy and paste to the controls.sii into the related lines. Place the content of a console line carefully between the back-ticks (`). There should be no space chars between text and back-ticks. Save the modified controls.sii. ETS2/ATS will recognize the Arduino's correctly now and you can assign the corresponding buttons, axes, what ever.
Finding the controls.sii can be a little bit tricky, too. In Windows Explorer go to your Documents folder and then to "Euro Truck Simulator 2", respectively "American Truck Simulator". Inside of this folder you have a "profiles" or a "steamprofiles" folder (if you have purchased your game(s) via Steam). Go to the corresponding folder. In case, you have more than one profile, you have to identify the right profile folder. This must be done with a little bit detective flair. Once you have found the right folder, open it. Et voilà, there is the controls.sii. WARNING: Never ever use Office or WordPad to edit this file! Use Editor or Notepad++ for editing! And, just in case, make a copy before editing.
That's all, so far. In case, you prefer to build your own devices enumerator, here is the source code:
Code: Select all
#include <dinput.h>
#include <tchar.h>
#include <stdio.h>
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")
#pragma warning (disable:6031)
BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* instance, VOID* context);
int main()
{
_tprintf(L"Currently connected DirectX input devices\n\n");
LPDIRECTINPUT8 di;
HRESULT hr;
// create a direct input interface
if (SUCCEEDED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&di, NULL)))
{
// enumerate attached direct input devices
di->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback, NULL, DIEDFL_ATTACHEDONLY);
// release the interface
di->Release();
}
else
{
// something goes wrong, so we want to have an informational error message
// variable 'hr' contains the error code
LPTSTR pBuffer = NULL; // will be allocated by FormatMessage
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, (LPTSTR)&pBuffer, 0, NULL);
if (!pBuffer)
{
// there is no textual message for the specified error code
_tprintf(L"No message available (0x%08X)", hr);
}
else
{
// print out the message
_tprintf(pBuffer);
// release the buffer
LocalFree(pBuffer);
}
}
// waiting for a key stroke
// otherwise, we couldn't read the output ;D
_tprintf(L"\npress any key to leave this console");
getc(stdin);
}
BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* instance, VOID* context)
{
TCHAR strGuidInst[40]; // a GUID consists of 38 chars
TCHAR strGuidProd[40];
StringFromGUID2(instance->guidInstance, strGuidInst, sizeof(strGuidInst) / sizeof(TCHAR));
StringFromGUID2(instance->guidProduct, strGuidProd, sizeof(strGuidProd) / sizeof(TCHAR));
// build a string in SCS controls.sii manner and print it out
_tprintf(L"di8.'%s|%s'\n", strGuidInst, strGuidProd);
// give us the next one, please
return DIENUM_CONTINUE;
}
Happy crafts,
Holger alias holmexx