View difference between Paste ID: j0Qdvx39 and u0FxAXdG
SHOW: | | - or go back to the newest paste.
1
//////////////////////////////////////////////////////////////////////
2
// This console application demonstrates how to wrive a vJoy client
3
// Не везде удалял авторские комменты. Виноват, я ленивый.
4
//Тут где-то был копирайт, так вот, самая большая няша, которой мы обязаны
5
//этим кодом, - это Shaul Eizikovich. Большое ему спасибо.
6
//////////////////////////////////////////////////////////////////////
7
8
#include "stdafx.h"
9
#include "vjoyclient.h"
10
#include <malloc.h>
11
#include <iostream>
12
//#include <Windows.h>
13
14
#define STICK_STEP 1000 
15
//#define OLD_CONTROLS
16
17
using namespace std; 
18
19
//Так мне удобно сравнивать состояния геймпада на двух соседних проходах цикла
20
bool operator== (JOYSTICK_POSITION &p1, JOYSTICK_POSITION &p2)
21
{
22
	return (p1.bHats == p2.bHats) &&
23
		(p1.lButtons == p2.lButtons) &&
24
		(p1.wAxisX == p2.wAxisX) &&
25
		(p1.wAxisY == p2.wAxisY) &&
26
		(p1.wAxisZ == p2.wAxisZ) &&
27
		(p1.wAxisZRot == p2.wAxisZRot);
28
}
29
bool operator!= (JOYSTICK_POSITION &p1, JOYSTICK_POSITION &p2)
30
{
31
	return !(p1==p2);
32
}
33
int
34
__cdecl
35
_tmain(__in int argc, __in PZPWSTR argv)
36
{
37
38
	HDEVINFO hDeviceInfo;
39
	TCHAR ErrMsg[1000];
40
	ULONG  bytes;
41
	HANDLE hDevice;
42
	USHORT X, Y, Z, ZR;
43
	JOYSTICK_POSITION	iReport, iOldReport;
44
	PVOID pPositionMessage;
45
	UINT	IoCode = LOAD_POSITIONS;
46
	UINT	IoSize = sizeof(JOYSTICK_POSITION);
47
	HID_DEVICE_ATTRIBUTES attrib;
48
49
50
	// ---------------------------------------------------------------------------------------------------------- \\
51
	// Tests if vJoy device is installed 
52
	// This call to the system requests installation information for the device by its ID (GUID_DEVINTERFACE_VJOY)
53
	// It does not tests its functionality and it does not care if it is disabled.
54
	// Returns a valid handle if a driver identified by GUID_DEVINTERFACE_VJOY is installed (Enabeled or Disabled)
55
	hDeviceInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VJOY, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
56
	if (hDeviceInfo == INVALID_HANDLE_VALUE)
57
	{
58
		GetErrorString(ErrMsg,1000);
59
		_tprintf(_T("[E] SetupDiGetClassDevs failed with error: %s\n"), ErrMsg);
60
		return -1;
61
	};
62
	// ---------------------------------------------------------------------------------------------------------- \\
63
64
65
	// ---------------------------------------------------------------------------------------------------------- \\
66
	// Opens vJoy device for writing
67
	// Returns a valid handle to the device if the device is responsive
68
	// Returns an INvalid handle if the device is not responding for some reason
69
	hDevice = OpenJoystickDevice();
70
	if (hDevice  == INVALID_HANDLE_VALUE)
71
		return -1;
72
	// ---------------------------------------------------------------------------------------------------------- \\
73
74
75
	// ---------------------------------------------------------------------------------------------------------- \\
76
	// Get the driver attributes (Vendor ID, Product ID, Version Number)
77
	attrib.Size = sizeof (HID_DEVICE_ATTRIBUTES);	// Prepare the buffer that gets the data
78
	IoCode = IOCTL_VJOY_GET_ATTRIB;					// The op-code for this request
79
80
	// Now - access the device (vJoy) with the right op-code and get the data into the buffer (attrib)
81
	BOOL res = DeviceIoControl(hDevice, IoCode, NULL, 0, &(attrib), sizeof (HID_DEVICE_ATTRIBUTES), &bytes, NULL);
82
	if (!res)
83
	{
84
		GetErrorString(ErrMsg,1000);
85
		_tprintf(_T("[E] IOCTL_VJOY_GET_ATTRIB failed with error: %s\n"), ErrMsg);
86
	}
87
	else
88
		_tprintf(_T("[I] VendorID:0x%04X ProductID:0x%04X VersionNumber:%d\n"), attrib.VendorID,  attrib.ProductID, attrib.VersionNumber);
89
	// Expected result: "VendorID:0x1234 ProductID:0xBEAD VersionNumber:2"
90
	// ---------------------------------------------------------------------------------------------------------- \\
91
92
	// Initialize axes X,Y,Z,Z-Rotation
93
	X = 20;
94
	Y = 30;
95
	Z = 40;
96
	ZR = 80;   
97
	int XValue = 0x3FFF;
98
	int YValue = 0x3FFF;
99
	int XValue_c = 0;
100
	int YValue_c = 0;
101
	
102
	while (1)
103
	{
104
		
105
		bool shift = 0!=GetAsyncKeyState(VK_LSHIFT);
106
107
		bool leftKey = 0!=GetAsyncKeyState(VK_LEFT);
108
		bool rightKey = 0!=GetAsyncKeyState(VK_RIGHT);
109
		bool upKey = 0!=GetAsyncKeyState(VK_UP);
110-
		Y = X = 0x3fff;		
110+
111-
		Z = ZR = 0x3fff;
111+
112-
		if(!leftKey != !rightKey)
112+
113
		bool delKey = 0!=GetAsyncKeyState(VK_DELETE);
114-
			if (!shift)
114+
115-
				X = leftKey ? 0 : 0x7FFF;
115+
116-
			else
116+
117-
				Z = leftKey ? 0 : 0x7FFF;
117+
#ifdef OLD_CONTROLS
118
		XValue = YValue = 0x3fff;
119
		if(!leftKey != !rightKey)		
120
			XValue = leftKey ? 0 : 0x7FFF;
121-
			if(!shift)
121+
122-
				Y = upKey ? 0 : 0x7FFF;
122+
			YValue = upKey ? 0 : 0x7FFF;
123-
			else
123+
124-
				ZR = upKey ? 0 : 0x7FFF;
124+
#else
125
		if(leftKey) 
126
		{
127
			if(XValue_c > 0) XValue_c = 0;
128
				XValue_c -= STICK_STEP;
129
		}
130
		if(rightKey) 
131
		{
132
			if(XValue_c < 0) XValue_c = 0;
133
			XValue_c += STICK_STEP;
134
		}
135
		if(upKey)
136
		{ 
137
			if(YValue_c > 0) YValue_c = 0;
138
			YValue_c -= STICK_STEP;
139
		}
140
		if(downKey) 
141
		{ 
142
			if(YValue_c < 0) YValue_c = 0;
143
			YValue_c += STICK_STEP;
144
		}
145
		if(XValue_c<-16383) XValue_c = -16383;
146
		if(YValue_c<-16383) YValue_c = -16383;
147
		if(XValue_c>16384) XValue_c = 16384;
148
		if(YValue_c>16384) YValue_c = 16384;
149
		
150
		if (!leftKey && !rightKey)
151
		{
152
			XValue_c = 0;
153
		}
154
		if(!upKey && !downKey)
155
		{ 
156
			/*if (abs(XValue_c)<(2*STICK_STEP)) XValue_c = 0;
157
			else XValue_c -= ((XValue_c>0) ? (2*STICK_STEP): (-2*STICK_STEP));
158
			if (abs(YValue_c)<(2*STICK_STEP)) YValue_c = 0;
159
			else YValue_c -= ((YValue_c<0) ? -(2*STICK_STEP): (2*STICK_STEP));*/
160
			YValue_c = 0;
161
		}
162
		/*if(!upKey && !downKey)
163
		{ 
164
		}*/
165
		XValue = XValue_c + 0x3FFF;
166
		YValue = YValue_c + 0x3fff;
167
#endif 
168
		if(!shift)
169
		{
170
			X = XValue;
171
			Y = YValue;
172-
		Sleep(0);
172+
			Z = ZR = 0x3FFF;			
173
		}
174
		else
175
		{
176
			Z = XValue;
177
			ZR = YValue;
178
			X = Y = 0x3FFF;
179
		}		 
180
181
		iReport.bHats = 4;
182
		if(delKey) iReport.bHats = 3;
183
		if(homeKey) iReport.bHats = 0;
184
		if(pgdnKey) iReport.bHats = 1;
185
		if(endKey) iReport.bHats = 2;
186
		 
187
		// Set axes X,Y,Z,Z-Rotation to current values
188
		iReport.wAxisX=X;
189
		iReport.wAxisY=Y;
190
		iReport.wAxisZ=Z;
191
		iReport.wAxisZRot=ZR;
192
		
193
194
		iReport.lButtons = 0;
195
		if (0!=GetAsyncKeyState(0x41)) iReport.lButtons |= 0x1; //VJoy Button1 (X Button) is set to "A" key
196
		if (0!=GetAsyncKeyState(0x53)) iReport.lButtons |= 0x2; //(A Button) => "S" key
197
		if (0!=GetAsyncKeyState(0x44)) iReport.lButtons |= 0x4; //(B Button) => "D" key
198
		if (0!=GetAsyncKeyState(0x57)) iReport.lButtons |= 0x8; //(Y Button) => "W" key
199
		if (0!=GetAsyncKeyState(0x51)) iReport.lButtons |= 0x10; //(LB button) => "Q" key
200
		if (0!=GetAsyncKeyState(0x45)) iReport.lButtons |= 0x20; //(RB button) => "E" key
201
		if (0!=GetAsyncKeyState(0x5a)) iReport.lButtons |= 0x40; //(LT button) => "Z" key
202
		if ((0!=GetAsyncKeyState(0x43)) || shift) iReport.lButtons |= 0x80; //(RT button) => "C" key or LSHIFT
203
		if (0!=GetAsyncKeyState(VK_ESCAPE)) iReport.lButtons |= 0x100; //(Start button) => ESC, как ни странно
204
		if (0!=GetAsyncKeyState(VK_RETURN)) iReport.lButtons |= 0x200; //(Back button) => Enter, что удивительно. Мне так нравится.
205
		  
206
		if(iOldReport != iReport)
207
		{
208
			// Buffer hoding the joystick position (iReport) is ready
209
			// Cast it to PVOID and print some of it		
210
			pPositionMessage = (PVOID)(&iReport);
211
			//_tprintf(_T("Input: X=%4x, Y=%4x, Buttons=%X; \n"), iReport.wAxisX, iReport.wAxisY, iReport.lButtons);
212
		
213
			// Prepare op-code and buffer size for access to vJoy device
214
			IoCode = LOAD_POSITIONS;
215
			IoSize = sizeof(JOYSTICK_POSITION);
216
217
			// Send joystick position structure to vJoy device
218
			if (!DeviceIoControl (hDevice, IoCode, pPositionMessage, IoSize, NULL, 0, &bytes, NULL)) 
219
			{
220
				_tprintf(_T("Ioctl to vJoy device failed\n"));
221
				break;
222
			}
223
224
			iOldReport = iReport;
225
		}
226
		Sleep(1);
227
	};
228
229
230
	// Loop interupted - close handle and exit
231
	CloseHandle(hDevice);
232
	_tprintf(_T("OK\n"));
233
234
	return 0;
235
}
236
237
/*
238
Open vJoy device
239
The handle this function returns will be used as the means to communicate with the device
240
Return handle to open device or INVALID_HANDLE_VALUE 
241
*/
242
HANDLE OpenJoystickDevice(void)
243
{
244
	HANDLE hDevice;
245
	TCHAR ErrMsg[1000];
246
247
248
	// At the moment vJoy is opened as DOS_FILE_NAME ("\\.\PPJoyIOCTL1") - ASCII only!
249
	_tprintf(_T("CreateFile:  %s\n"), DOS_FILE_NAME);
250
	hDevice = CreateFileA(DOS_FILE_NAME, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
251
	if (hDevice == INVALID_HANDLE_VALUE)
252
	{
253
		DWORD err = GetErrorString(ErrMsg,1000);
254
		_tprintf(_T("[E=0x%x] CreateFile failed for %s with error: %s\n"), err, DOS_FILE_NAME, ErrMsg);
255
		return INVALID_HANDLE_VALUE;
256
	};
257
	return hDevice;
258
}
259
260
261
262
/* Helper Functions */
263
DWORD GetErrorString(TCHAR * Msg, int Size)
264
{
265
	TCHAR * s;
266
	DWORD errorcode = GetLastError();
267
	int nTChars = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,  NULL, errorcode, 0, (LPSTR)&s,  0, NULL);
268
	if (!nTChars)
269
		return errorcode;
270
271
	_tcsncpy_s(Msg, Size, s, Size);
272
	LocalFree(s);
273
	return errorcode;
274
}