Last active
August 29, 2015 14:20
-
-
Save DarkWanderer/3ac07a213bfc8a02932d to your computer and use it in GitHub Desktop.
Joystick detection test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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(); | |
} |
You need to compile as Console app, not Windows app
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 ==========