Skip to content

Instantly share code, notes, and snippets.

@DarkWanderer
Last active August 29, 2015 14:20
Show Gist options
  • Save DarkWanderer/3ac07a213bfc8a02932d to your computer and use it in GitHub Desktop.
Save DarkWanderer/3ac07a213bfc8a02932d to your computer and use it in GitHub Desktop.
Joystick detection test
#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();
}
@DarkWanderer
Copy link
Author

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