-
-
Save DarkWanderer/3ac07a213bfc8a02932d to your computer and use it in GitHub Desktop.
#include <dinput.h> | |
#include <assert.h> | |
#include <exception> | |
#include <iostream> | |
#include <string> | |
#include <chrono> | |
#include <list> | |
#pragma region Usings | |
using std::cout; | |
using std::endl; | |
using std::string; | |
using std::list; | |
#pragma endregion | |
#pragma comment (lib,"dxguid.lib") | |
#pragma comment (lib,"dinput8.lib") | |
void CheckDxCallResult(HRESULT result) | |
{ | |
assert(result == DI_OK); // Assertion to be triggered at runtime | |
if (result != DI_OK) | |
throw new std::exception("DirectX call was not completed successfully"); | |
} | |
BOOL __stdcall EnumDevicesCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID referencePointer) | |
{ | |
auto pDeviceCount = reinterpret_cast<size_t*>(referencePointer); | |
string instanceName(&pDeviceInstance->tszInstanceName[0]); | |
string productName(&pDeviceInstance->tszProductName[0]); | |
cout << " Device:" << endl; | |
//cout << " Size: " << pDeviceInstance->dwSize << endl; | |
//cout << " Type: " << pDeviceInstance->dwDevType << endl; | |
cout << " Name: " << productName << endl; | |
cout << " Instance: " << instanceName << endl; | |
(*pDeviceCount)++; | |
return TRUE; | |
} | |
size_t EnumerateGameControllers(IDirectInput8A* directInputObject) | |
{ | |
cout << "Enumerating devices" << endl; | |
assert(directInputObject != nullptr); | |
size_t deviceCount = 0; | |
CheckDxCallResult(directInputObject->EnumDevices(DI8DEVCLASS_GAMECTRL, &EnumDevicesCallback, &deviceCount, DIEDFL_ATTACHEDONLY)); | |
cout << "Found " << deviceCount << " devices" << endl; | |
return deviceCount; | |
} | |
IDirectInput8* CreateDirectInputObject() | |
{ | |
HINSTANCE hinstance = GetModuleHandle(nullptr); // A bit of a hack here, see http://forums.codeguru.com/showthread.php?148264-How-to-get-hInstance-handle-in-console-app | |
IDirectInput8* directInputObject = nullptr; | |
CheckDxCallResult(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<void**>(&directInputObject), nullptr)); | |
return directInputObject; | |
} | |
void FillAndFreeMemory() | |
{ | |
// This function will try to fill memory with blocks until a bad_alloc exception appears | |
auto start = std::chrono::high_resolution_clock::now(); | |
const size_t blockSize = 1 * 1024; | |
cout << "Filling memory with blocks of " << blockSize << " bytes" << endl; | |
try | |
{ | |
while (true) { | |
auto arr = new char[blockSize]; | |
} | |
} | |
catch (std::bad_alloc& exception) | |
{ | |
cout << "Caught bad_alloc, memory is full now" << endl; | |
} | |
// Uncomment this to try freeing the blocks before enumerating again | |
//for (auto block : blocks) | |
// delete[] block; | |
//blocks.clear(); | |
auto end = std::chrono::high_resolution_clock::now(); | |
cout << "Allocating memory took " << std::chrono::duration<double>(end - start).count() << "s" << endl; | |
}; | |
int main() | |
{ | |
cout << "'Disappearing joystick' test v3" << endl; | |
cout << "This utility tests whether your system is affected by the issue which is causing " | |
<< "the 'disappearing joystick syndrome' when opening settings in ArmA 3" << endl; | |
auto di = CreateDirectInputObject(); | |
cout << "Before allocation:" << endl; | |
auto count1 = EnumerateGameControllers(di); | |
if (count1 == 0) | |
{ | |
cout << "This utility requires at least 1 joystick to be present" << endl; | |
cout << "Plug in a joystick/game controller and restart" << endl; | |
cout << "Press any key to exit" << endl; | |
getchar(); | |
exit(1); | |
} | |
FillAndFreeMemory(); | |
cout << "After allocation:" << endl; | |
auto count2 = EnumerateGameControllers(di); | |
cout << "Finished" << endl; | |
cout << "Your system seems to be "; | |
if (count1 == count2) | |
cout << "NOT "; | |
cout << "AFFECTED" << endl; | |
cout << "Press any key to exit" << endl; | |
getchar(); | |
} |
Hi rogerxxx,
It relies only on recent versions of Windows SDK - which have DirectX libraries merged. I have not tried any open-source compilers, but I believe any compiler which can compile C++11 programs for windows should be able to handle it. No Microsoft extensions were used.
Installed Microsoft Visual 2013 Community (vs2013.4_ce_enu.iso) and Windows 8.1 SDK.
Imported new project from existing code. (ie. joystick/joystick.cpp) Build...
1>------ Build started: Project: joystick, Configuration: Debug Win32 ------
1> joystick.cpp
1> C:\Program Files (x86)\Windows Kits\8.1\Include\um\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
1>joystick.cpp(71): warning C4101: 'exception' : unreferenced local variable
1>MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
1>G:\Windows8.1\joystick\Debug\joystick.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
You need to compile as Console app, not Windows app
What libraries does this snippet rely on for compiling? (ie. Windows 8 SDK?)
What (free or open source) compilers can be used with this snippet?
If the above is easily acquired, I would be more than happy to compile & test the code!