/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/plugins/SSSPSXPAD/PadSSSPSX.cpp
ViewVC logotype

Annotation of /branch/r3113_0.9.7_beta/plugins/SSSPSXPAD/PadSSSPSX.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (hide annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (10 years, 9 months ago) by william
File size: 28919 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 william 31 #define WINVER 0x0500
2     #define _WIN32_WINNT WINVER
3     #define DIRECTINPUT_VERSION 0x0800
4    
5     #include <windows.h>
6     #include <windowsx.h>
7     #include <commctrl.h>
8     #include <dinput.h>
9     #include <string>
10    
11     #include "PadSSSPSX.h"
12    
13     #ifdef _MSC_VER
14     # include "svnrev.h"
15     #endif
16    
17     static const unsigned char version = 0x0002;
18     static const unsigned char revision = 1;
19     static const unsigned char build = 7;
20     static const unsigned char buildfix = 1;
21    
22     HMODULE hInstance;
23     HWND hTargetWnd;
24    
25     static std::string s_strIniPath( "inis/" );
26    
27     static CRITICAL_SECTION update_lock;
28     static CRITICAL_SECTION init_lock;
29    
30     struct EnterScopedSection
31     {
32     CRITICAL_SECTION& m_cs;
33    
34     EnterScopedSection( CRITICAL_SECTION& cs ) : m_cs( cs ) {
35     EnterCriticalSection( &m_cs );
36     }
37    
38     ~EnterScopedSection() {
39     LeaveCriticalSection( &m_cs );
40     }
41     };
42    
43    
44     static struct
45     {
46     keyEvent ev;
47     u8 state[2][256];
48     } save;
49    
50     static struct
51     {
52     Config config;
53     int devcnt;
54     LPDIRECTINPUT8 pDInput;
55     LPDIRECTINPUTDEVICE8 pDKeyboard;
56     LPDIRECTINPUTDEVICE8 pDDevice[4];
57     LPDIRECTINPUTEFFECT pDEffect[4][2]; /* for Small & Big Motor */
58     DIJOYSTATE JoyState[4];
59     u16 padStat[2];
60     int padID[2];
61     int padMode1[2];
62     int padMode2[2];
63     int padModeE[2];
64     int padModeC[2];
65     int padModeF[2];
66     int padVib0[2];
67     int padVib1[2];
68     int padVibF[2][4];
69     int padVibC[2];
70     DWORD padPress[2][16];
71     int curPad;
72     int curByte;
73     int curCmd;
74     int cmdLen;
75     } global;
76    
77     static BOOL CALLBACK EnumAxesCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
78     {
79     LPDIRECTINPUTDEVICE8 pDDevice = (LPDIRECTINPUTDEVICE8)pvRef;
80     DIPROPRANGE diprg;
81     diprg.diph.dwSize = sizeof (diprg);
82     diprg.diph.dwHeaderSize = sizeof (diprg.diph);
83     diprg.diph.dwObj = lpddoi->dwType;
84     diprg.diph.dwHow = DIPH_BYID;
85     diprg.lMin = -128;
86     diprg.lMax = 127;
87     pDDevice->SetProperty (DIPROP_RANGE, &diprg.diph);
88     return DIENUM_CONTINUE;
89     }
90    
91     static BOOL CALLBACK EnumJoysticksCallback (const DIDEVICEINSTANCE* instance, VOID* pContext)
92     {
93     const int devno = global.devcnt;
94     if (devno >= 4)
95     return DIENUM_STOP;
96     HRESULT result = global.pDInput->CreateDevice (instance->guidInstance, &global.pDDevice[devno], NULL);
97     if (FAILED (result))
98     return DIENUM_CONTINUE;
99     global.devcnt++;
100     return DIENUM_CONTINUE;
101     }
102    
103     static bool ReleaseDirectInput (void)
104     {
105     int index = 4;
106     while (index--)
107     {
108     int index2 = 2;
109     while (index2--)
110     {
111     if (global.pDEffect[index][index2])
112     {
113     global.pDEffect[index][index2]->Unload();
114     global.pDEffect[index][index2]->Release();
115     global.pDEffect[index][index2] = NULL;
116     }
117     }
118     if (global.pDDevice[index])
119     {
120     global.pDDevice[index]->Unacquire();
121     global.pDDevice[index]->Release();
122     global.pDDevice[index] = NULL;
123     }
124     }
125     if (global.pDKeyboard)
126     {
127     global.pDKeyboard->Unacquire();
128     global.pDKeyboard->Release();
129     global.pDKeyboard = NULL;
130     }
131     if (global.pDInput)
132     {
133     global.pDInput->Release();
134     global.pDInput = NULL;
135     }
136     global.devcnt = 0;
137     return FALSE;
138     }
139    
140     static bool InitDirectInput (void)
141     {
142     EnterScopedSection initlock( init_lock );
143    
144     if (global.pDInput)
145     return TRUE;
146     HRESULT result = DirectInput8Create (hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&global.pDInput, NULL);
147     if (FAILED (result))
148     return ReleaseDirectInput();
149     result = global.pDInput->CreateDevice (GUID_SysKeyboard, &global.pDKeyboard, NULL);
150     if (FAILED (result))
151     return ReleaseDirectInput();
152     result = global.pDInput->EnumDevices (DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY);
153     if (FAILED (result))
154     return ReleaseDirectInput();
155     result = global.pDKeyboard->SetDataFormat (&c_dfDIKeyboard);
156     if (FAILED (result))
157     return ReleaseDirectInput();
158     if (hTargetWnd)
159     {
160     global.pDKeyboard->Unacquire();
161     result = global.pDKeyboard->SetCooperativeLevel (hTargetWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
162     if (FAILED (result))
163     return ReleaseDirectInput();
164     }
165     int index = global.devcnt;
166     while (index--)
167     {
168     const LPDIRECTINPUTDEVICE8 pDDevice = global.pDDevice[index];
169     result = pDDevice->SetDataFormat (&c_dfDIJoystick);
170     if (FAILED (result))
171     return ReleaseDirectInput();
172     if (hTargetWnd)
173     {
174     pDDevice->Unacquire();
175     result = pDDevice->SetCooperativeLevel (hTargetWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
176     if (FAILED (result))
177     return ReleaseDirectInput();
178     }
179     struct
180     {
181     DIPROPDWORD dipdw;
182     DWORD rgdwAxes[2];
183     LONG rglDirection[2];
184     DIPERIODIC per;
185     DICONSTANTFORCE cf;
186     DIEFFECT eff;
187     } local;
188     memset (&local, 0, sizeof (local));
189     local.dipdw.diph.dwSize = sizeof (DIPROPDWORD);
190     local.dipdw.diph.dwHeaderSize = sizeof (DIPROPHEADER);
191     local.dipdw.diph.dwHow = DIPH_DEVICE;
192     local.dipdw.dwData = DIPROPAUTOCENTER_OFF;
193     pDDevice->SetProperty (DIPROP_AUTOCENTER, &local.dipdw.diph);
194     result = pDDevice->EnumObjects (EnumAxesCallback, pDDevice, DIDFT_AXIS);
195     if (FAILED (result))
196     return ReleaseDirectInput();
197    
198     local.rgdwAxes[0] = DIJOFS_X;
199     local.rgdwAxes[1] = DIJOFS_Y;
200     local.eff.dwSize = sizeof (DIEFFECT);
201     local.eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
202     local.eff.dwDuration = INFINITE;
203     local.eff.dwGain = DI_FFNOMINALMAX;
204     local.eff.dwTriggerButton = DIEB_NOTRIGGER;
205     local.eff.cAxes = 2;
206     local.eff.rgdwAxes = local.rgdwAxes;
207     local.eff.rglDirection = local.rglDirection;
208    
209     /* Small Motor */
210     local.eff.cbTypeSpecificParams = sizeof (DIPERIODIC);
211     local.eff.lpvTypeSpecificParams = &local.per;
212     result = pDDevice->CreateEffect (GUID_Square , &local.eff, &global.pDEffect[index][0], NULL);
213     if (FAILED (result))
214     global.pDEffect[index][0] = NULL;
215    
216     /* Big Motor */
217     local.eff.cbTypeSpecificParams = sizeof (DICONSTANTFORCE);
218     local.eff.lpvTypeSpecificParams = &local.cf;
219     result = pDDevice->CreateEffect (GUID_ConstantForce , &local.eff, &global.pDEffect[index][1], NULL);
220     if (FAILED (result))
221     global.pDEffect[index][1] = NULL;
222     }
223     return TRUE;
224     }
225    
226     static bool AcquireDevice (LPDIRECTINPUTDEVICE8 lpDirectInputDevice)
227     {
228     if (FAILED (lpDirectInputDevice->Acquire()))
229     {
230     HRESULT result = lpDirectInputDevice->Acquire();
231     if (result == DIERR_OTHERAPPHASPRIO)
232     return FALSE;
233     if (FAILED (result))
234     return ReleaseDirectInput();
235     }
236     return TRUE;
237     }
238    
239     /* Small Motor */
240     static bool SetDeviceForceS (int pad, DWORD force)
241     {
242     InitDirectInput();
243     if (global.pDEffect[pad][0])
244     {
245     LONG rglDirection[2] = { 0, 0 };
246     DIPERIODIC per;
247     rglDirection[0] = 0;
248     rglDirection[1] = 1;
249     per.dwMagnitude = force;
250     per.dwPeriod = (DWORD) (0.01 * DI_SECONDS);
251     per.lOffset = 0;
252     per.dwPhase = 0;
253     DIEFFECT eff;
254     eff.dwSize = sizeof (DIEFFECT);
255     eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
256     eff.cAxes = 2;
257     eff.rglDirection = rglDirection;
258     eff.lpEnvelope = 0;
259     eff.cbTypeSpecificParams = sizeof (DIPERIODIC);
260     eff.lpvTypeSpecificParams = &per;
261     if (FAILED (global.pDEffect[pad][0]->SetParameters (&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START)))
262     return ReleaseDirectInput();
263     if (FAILED (global.pDEffect[pad][0]->Stop()))
264     {
265     AcquireDevice (global.pDDevice[pad]);
266     if (FAILED (global.pDEffect[pad][0]->Stop()))
267     return ReleaseDirectInput();
268     }
269     if (force == 0)
270     return TRUE;
271     if (FAILED (global.pDEffect[pad][0]->Start (1, 0)))
272     {
273     AcquireDevice (global.pDDevice[pad]);
274     if (FAILED (global.pDEffect[pad][0]->Start (1, 0)))
275     return ReleaseDirectInput();
276     }
277     }
278     return TRUE;
279     }
280    
281     /* Big Motor */
282     static bool SetDeviceForceB (int pad, DWORD force)
283     {
284     InitDirectInput();
285     if (global.pDEffect[pad][1])
286     {
287     LONG rglDirection[2] = { 0, 0 };
288     DICONSTANTFORCE cf;
289     rglDirection[0] = 1;
290     rglDirection[1] = 0;
291     cf.lMagnitude = force;
292     DIEFFECT eff;
293     eff.dwSize = sizeof (DIEFFECT);
294     eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
295     eff.cAxes = 2;
296     eff.rglDirection = rglDirection;
297     eff.lpEnvelope = 0;
298     eff.cbTypeSpecificParams = sizeof (DICONSTANTFORCE);
299     eff.lpvTypeSpecificParams = &cf;
300     if (FAILED (global.pDEffect[pad][1]->SetParameters (&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START)))
301     return ReleaseDirectInput();
302     if (FAILED (global.pDEffect[pad][1]->Stop()))
303     {
304     AcquireDevice (global.pDDevice[pad]);
305     if (FAILED (global.pDEffect[pad][1]->Stop()))
306     return ReleaseDirectInput();
307     }
308     if (force == 0)
309     return TRUE;
310     if (FAILED (global.pDEffect[pad][1]->Start (1, 0)))
311     {
312     AcquireDevice (global.pDDevice[pad]);
313     if (FAILED (global.pDEffect[pad][1]->Start (1, 0)))
314     return ReleaseDirectInput();
315     }
316     }
317     return TRUE;
318     }
319    
320     static bool GetJoyState (const int devno)
321     {
322     InitDirectInput();
323     if (global.pDDevice[devno] == NULL)
324     return FALSE;
325     global.pDDevice[devno]->Poll();
326     if (FAILED (global.pDDevice[devno]->GetDeviceState (sizeof (DIJOYSTATE), &global.JoyState[devno])))
327     {
328     AcquireDevice (global.pDDevice[devno]);
329     return FALSE;
330     }
331     return TRUE;
332     }
333    
334     static bool GetKeyState (u8* keyboard)
335     {
336     InitDirectInput();
337     if (global.pDKeyboard == NULL)
338     return FALSE;
339     global.pDKeyboard->Poll();
340     if (FAILED (global.pDKeyboard->GetDeviceState (256, keyboard)))
341     {
342     AcquireDevice (global.pDKeyboard);
343     return FALSE;
344     }
345     return TRUE;
346     }
347    
348     static std::string MakeConfigFileName()
349     {
350     //GetModuleFileName (hInstance, fname, 256);
351     //strcpy (fname + strlen (fname) - 3, "cfg");
352    
353     return s_strIniPath + "PadSSSPSX.cfg";
354     }
355    
356     static void SaveConfig (void)
357     {
358     const std::string fname( MakeConfigFileName() );
359     CreateDirectory( s_strIniPath.c_str(), NULL );
360    
361     HANDLE hFile = CreateFile (fname.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
362     if (hFile != INVALID_HANDLE_VALUE)
363     {
364     DWORD number_of_bytes;
365     WriteFile (hFile, &global.config, sizeof (global.config), &number_of_bytes, NULL);
366     CloseHandle (hFile);
367     }
368     }
369    
370     static void LoadConfig (void)
371     {
372     const std::string fname( MakeConfigFileName() );
373     HANDLE hFile = CreateFile (fname.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
374     if (hFile != INVALID_HANDLE_VALUE)
375     {
376     DWORD number_of_bytes;
377     ReadFile (hFile, &global.config, sizeof (global.config), &number_of_bytes, NULL);
378     CloseHandle (hFile);
379     }
380     global.padVibC[0] = global.padVibC[1] = -1;
381     for (int cnt = 21; cnt--; )
382     {
383     const int key0 = global.config.keys[0][cnt];
384     if (key0 >= 0x1000)
385     global.padVibC[0] = (key0 & 0xfff) / 0x100;
386     const int key1 = global.config.keys[1][cnt];
387     if (key1 >= 0x1000)
388     global.padVibC[1] = (key1 & 0xfff) / 0x100;
389     }
390     }
391    
392     static void PADsetMode (const int pad, const int mode)
393     {
394     static const u8 padID[] = { 0x41, 0x73, 0x41, 0x79 };
395     global.padMode1[pad] = mode;
396     global.padVib0[pad] = 0;
397     global.padVib1[pad] = 0;
398     global.padVibF[pad][0] = 0;
399     global.padVibF[pad][1] = 0;
400     global.padID[pad] = padID[global.padMode2[pad] * 2 + mode];
401     }
402    
403     static void KeyPress (const int pad, const int index, const bool press)
404     {
405     if (index < 16)
406     {
407     if (press)
408     {
409     global.padStat[pad] &= ~(1 << index);
410     if (global.padPress[pad][index] == 0)
411     global.padPress[pad][index] = GetTickCount();
412     }
413     else
414     {
415     global.padStat[pad] |= 1 << index;
416     global.padPress[pad][index] = 0;
417     }
418     }
419     else
420     {
421     static bool prev[2] = { FALSE, FALSE };
422     if ((prev[pad] != press) && (global.padModeF[pad] == 0))
423     {
424     prev[pad] = press;
425     if (press) PADsetMode (pad, !global.padMode1[pad]);
426     }
427     }
428     }
429    
430     static void UpdateState (const int pad)
431     {
432     static int flag_keyboard;
433     static int flag_joypad[4];
434     if (pad == 0)
435     {
436     flag_keyboard = 0;
437     flag_joypad[0] = 0;
438     flag_joypad[1] = 0;
439     flag_joypad[2] = 0;
440     flag_joypad[3] = 0;
441     }
442     static u8 keystate[256];
443     for (int index = 17; index--; )
444     {
445     const int key = global.config.keys[pad][index];
446     if (key == 0)
447     continue;
448     else if (key < 0x100)
449     {
450     if (flag_keyboard == FALSE)
451     {
452     flag_keyboard = TRUE;
453     if (GetKeyState (keystate) == FALSE)
454     return;
455     }
456     KeyPress (pad, index, !!(keystate[key] & 0x80));
457     }
458     else
459     {
460     const int joypad = ((key & 0xfff) / 0x100);
461     if (flag_joypad[joypad] == FALSE)
462     {
463     flag_joypad[joypad] = TRUE;
464     if (GetJoyState (joypad) == FALSE)
465     return;
466     }
467     if (key < 0x2000)
468     {
469     KeyPress (pad, index, !!(global.JoyState[joypad].rgbButtons[key & 0xff]));
470     }
471     else if (key < 0x3000)
472     {
473     const int state = ((int*)&global.JoyState[joypad].lX)[(key & 0xff) /2];
474     switch (key & 1)
475     {
476     case 0: KeyPress (pad, index, state < -64); break;
477     case 1: KeyPress (pad, index, state >= 64); break;
478     }
479     }
480     else
481     {
482     const u32 state = global.JoyState[joypad].rgdwPOV[(key & 0xff) /4];
483     switch (key & 3)
484     {
485     case 0: KeyPress (pad, index, (state >= 0 && state <= 4500) || (state >= 31500 && state <= 36000)); break;
486     case 1: KeyPress (pad, index, state >= 4500 && state <= 13500); break;
487     case 2: KeyPress (pad, index, state >= 13500 && state <= 22500); break;
488     case 3: KeyPress (pad, index, state >= 22500 && state <= 31500); break;
489     }
490     }
491     }
492     }
493    
494     /* Small Motor */
495     const int vib0 = global.padVibF[pad][0] ? 2000 : 0;
496     if ((global.padVibF[pad][2] != vib0) && (global.padVibC[pad] >= 0))
497     {
498     global.padVibF[pad][2] = vib0;
499     SetDeviceForceS (global.padVibC[pad], vib0);
500     }
501     /* Big Motor */
502     const int vib1 = global.padVibF[pad][1] ? 500 + 37*global.padVibF[pad][1] : 0;
503     if ((global.padVibF[pad][3] != vib1) && (global.padVibC[pad] >= 0))
504     {
505     global.padVibF[pad][3] = vib1;
506     SetDeviceForceB (global.padVibC[pad], vib1);
507     }
508     }
509    
510     static void set_label (const HWND hWnd, const int pad, const int index)
511     {
512     const int key = global.config.keys[pad][index];
513     char buff[64];
514     if (key < 0x100)
515     {
516     if (key == 0)
517     strcpy (buff, "NONE");
518     else if (GetKeyNameText (key << 16, buff, sizeof (buff)) == 0)
519     wsprintf (buff, "Keyboard 0x%02X", key);
520     }
521     else if (key >= 0x1000 && key < 0x2000)
522     {
523     wsprintf (buff, "J%d_%d", (key & 0xfff) / 0x100, (key & 0xff) + 1);
524     }
525     else if (key >= 0x2000 && key < 0x3000)
526     {
527     static const char name[][4] = { "MIN", "MAX" };
528     const int axis = (key & 0xff);
529     wsprintf (buff, "J%d_AXIS%d_%s", (key & 0xfff) / 0x100, axis / 2, name[axis % 2]);
530     if (index >= 17 && index <= 20)
531     buff[strlen (buff) -4] = '\0';
532     }
533     else if (key >= 0x3000 && key < 0x4000)
534     {
535     static const char name[][7] = { "FOWARD", "RIGHT", "BACK", "LEFT" };
536     const int pov = (key & 0xff);
537     wsprintf (buff, "J%d_POV%d_%s", (key & 0xfff) / 0x100, pov /4, name[pov % 4]);
538     }
539     Button_SetText (GetDlgItem (hWnd, IDC_ESELECT + index), buff);
540     }
541    
542     static BOOL CALLBACK ConfigureDlgProc (const HWND hWnd, const UINT msg, const WPARAM wParam, const LPARAM lParam)
543     {
544     static BYTE keymaps[2][256];
545     static DWORD countdown;
546     static int disabled;
547     static HWND hTabWnd;
548     static int pad;
549     int cnt1;
550     int cnt2;
551     int key;
552     switch (msg)
553     {
554     case WM_INITDIALOG:
555     hTargetWnd = hWnd;
556     pad = disabled = 0;
557     LoadConfig();
558     for (cnt1 = 21; cnt1--; )
559     set_label (hWnd, pad, cnt1);
560     hTabWnd = GetDlgItem (hWnd, IDC_TABC);
561     TCITEM tcI;
562     tcI.mask = TCIF_TEXT;
563     tcI.pszText = "PAD1";
564     TabCtrl_InsertItem (hTabWnd, 0, &tcI);
565     tcI.mask = TCIF_TEXT;
566     tcI.pszText = "PAD2";
567     TabCtrl_InsertItem (hTabWnd, 1, &tcI);
568     SetTimer (hWnd, 0x80, 50, NULL);
569     return TRUE;
570     case WM_DESTROY:
571     break;
572     case WM_NOTIFY:
573     if (wParam == IDC_TABC)
574     {
575     if (disabled)
576     EnableWindow (GetDlgItem (hWnd, disabled), TRUE);
577     disabled = 0;
578     pad = TabCtrl_GetCurSel (hTabWnd);
579     for (cnt1 = 21; cnt1--; )
580     set_label (hWnd, pad, cnt1);
581     }
582     break;
583     case WM_COMMAND:
584     for (cnt1 = 21; cnt1--; )
585     {
586     if (LOWORD (wParam) == IDC_BSELECT + cnt1)
587     {
588     if (disabled)
589     EnableWindow (GetDlgItem (hWnd, disabled), TRUE);
590     EnableWindow (GetDlgItem (hWnd, disabled = wParam), FALSE);
591     countdown = GetTickCount();
592     GetKeyState (keymaps[0]);
593     return TRUE;
594     }
595     }
596     if (LOWORD (wParam) == IDOK)
597     EndDialog (hWnd, IDOK);
598     else if (LOWORD (wParam) == IDCANCEL)
599     EndDialog (hWnd, IDCANCEL);
600     break;
601     case WM_TIMER:
602     if (disabled)
603     {
604     const int index = disabled - IDC_BSELECT;
605     int analog = FALSE;
606     if ((GetTickCount() - countdown) / 1000 != 10)
607     {
608     char buff[64];
609     wsprintf (buff, "Timeout: %d", 10 - (GetTickCount() - countdown) / 1000);
610     SetWindowText (GetDlgItem (hWnd, IDC_ESELECT + index), buff);
611     }
612     else
613     {
614     global.config.keys[pad][index] = 0;
615     set_label (hWnd, pad, index);
616     EnableWindow (GetDlgItem (hWnd, disabled), TRUE);
617     disabled = 0;
618     break;
619     }
620     if (GetKeyState (keymaps[1]) == FALSE)
621     break;
622     for (key = 0x100; key--; )
623     {
624     if (~keymaps[0][key] & keymaps[1][key] & 0x80)
625     break;
626     }
627     for (cnt1 = global.devcnt; cnt1--;)
628     {
629     if (GetJoyState (cnt1) == FALSE)
630     break;
631    
632     for (cnt2 = 32; cnt2--; )
633     {
634     if (global.JoyState[cnt1].rgbButtons[cnt2])
635     key = 0x1000 + 0x100 * cnt1 + cnt2;
636     }
637     for (cnt2 = 8; cnt2--; )
638     {
639     const int now = ((u32*)&global.JoyState[cnt1].lX)[cnt2];
640     if (now < -64)
641     {
642     key = 0x2000 + 0x100 * cnt1 + cnt2 * 2 +0;
643     analog = TRUE;
644     }
645     else if (now >= 64)
646     {
647     key = 0x2000 + 0x100 * cnt1 + cnt2 * 2 +1;
648     analog = TRUE;
649     }
650     }
651     for (cnt2 = 4; cnt2--; )
652     {
653     const u32 now = global.JoyState[cnt1].rgdwPOV[cnt2];
654     if ((now >= 0 && now < 4500) || (now >= 31500 && now < 36000))
655     key = 0x3000 + 0x100 * cnt1 + cnt2 * 4 +0;
656     if (now >= 4500 && now < 13500)
657     key = 0x3000 + 0x100 * cnt1 + cnt2 * 4 +1;
658     if (now >= 13500 && now < 22500)
659     key = 0x3000 + 0x100 * cnt1 + cnt2 * 4 +2;
660     if (now >= 22500 && now < 31500)
661     key = 0x3000 + 0x100 * cnt1 + cnt2 * 4 +3;
662     }
663     }
664     if (index >= 17 && index <= 20 && analog == 0)
665     key = 0;
666     else if (key > 0)
667     {
668     if (key != 1)
669     global.config.keys[pad][index] = key;
670     set_label (hWnd, pad, index);
671     EnableWindow (GetDlgItem (hWnd, disabled), TRUE);
672     disabled = 0;
673     }
674     }
675     }
676     return FALSE;
677     }
678    
679     static char LibraryName[256];
680     #define SSSPSX_NAME "SSSPSX PAD Pressure Mod"
681    
682     static void InitLibraryName()
683     {
684     #ifndef PCSX2_DEVBUILD
685    
686     // Public Release!
687     // Output a simplified string that's just our name:
688    
689     strcpy_s( LibraryName, SSSPSX_NAME );
690    
691     #else
692     #ifdef SVN_REV_UNKNOWN
693    
694     // Unknown revision.
695     // Output a name that includes devbuild status but not
696     // subversion revision tags:
697    
698     strcpy_s( LibraryName, SSSPSX_NAME
699     #ifdef PCSX2_DEBUG
700     "-Debug"
701     #elif defined( PCSX2_DEVBUILD )
702     "-Dev"
703     #else
704     ""
705     #endif
706     );
707    
708     #else
709    
710     // Use TortoiseSVN's SubWCRev utility's output
711     // to label the specific revision:
712    
713     sprintf_s( LibraryName, SSSPSX_NAME " r%d%s"
714     #ifdef PCSX2_DEBUG
715     "-Debug"
716     #elif defined( PCSX2_DEVBUILD )
717     "-Dev"
718     #else
719     ""
720     #endif
721     ,SVN_REV,
722     SVN_MODS ? "m" : ""
723     );
724     #endif
725     #endif
726    
727     }
728    
729    
730     u32 CALLBACK PS2EgetLibType (void)
731     {
732     return 0x02;
733     }
734    
735     const char* CALLBACK PS2EgetLibName (void)
736     {
737     InitLibraryName();
738     return LibraryName;
739     }
740    
741     u32 CALLBACK PS2EgetLibVersion2 (u32 type)
742     {
743     return (version << 16) | (revision << 8) | build | (buildfix<<24);
744     }
745    
746     u32 CALLBACK PSEgetLibType (void)
747     {
748     return 8;
749     }
750    
751     const char* CALLBACK PSEgetLibName (void)
752     {
753     InitLibraryName();
754     return LibraryName;
755     }
756    
757     u32 CALLBACK PSEgetLibVersion (void)
758     {
759     return (version << 16) | (revision << 8) | build;
760     }
761    
762     s32 CALLBACK PADinit (u32 flags)
763     {
764     return 0;
765     }
766    
767     void CALLBACK PADshutdown (void)
768     {
769     }
770    
771     static int n_open = 0;
772     s32 CALLBACK PADopen (HWND hWnd)
773     {
774     if (!IsWindow (hWnd) && !IsBadReadPtr ((u32*)hWnd, 4))
775     hWnd = *(HWND*)hWnd;
776     if (!IsWindow (hWnd))
777     hWnd = NULL;
778     else
779     {
780     while (GetWindowLong (hWnd, GWL_STYLE) & WS_CHILD)
781     hWnd = GetParent (hWnd);
782     }
783     hTargetWnd = hWnd;
784     if (n_open++ == FALSE)
785     {
786     memset (&global, 0, sizeof (global));
787     global.padStat[0] = 0xffff;
788     global.padStat[1] = 0xffff;
789     LoadConfig();
790     PADsetMode (0, 0);
791     PADsetMode (1, 0);
792     }
793     return 0;
794     }
795    
796     void CALLBACK PADclose (void)
797     {
798     if (--n_open == 0)
799     ReleaseDirectInput();
800     }
801    
802     u32 CALLBACK PADquery (void)
803     {
804     return 3;
805     }
806    
807     u8 CALLBACK PADstartPoll (int pad)
808     {
809     global.curPad = pad -1;
810     global.curByte = 0;
811     return 0xff;
812     }
813    
814     static const u8 cmd40[8] =
815     {
816     0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5a
817     };
818     static const u8 cmd41[8] =
819     {
820     0xff, 0x5a, 0xff, 0xff, 0x03, 0x00, 0x00, 0x5a,
821     };
822     static const u8 cmd44[8] =
823     {
824     0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
825     };
826     static const u8 cmd45[8] =
827     {
828     0xff, 0x5a, 0x03, 0x02, 0x01, 0x02, 0x01, 0x00,
829     };
830     static const u8 cmd46[8] =
831     {
832     0xff, 0x5a, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0a,
833     };
834     static const u8 cmd47[8] =
835     {
836     0xff, 0x5a, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
837     };
838     static const u8 cmd4c[8] =
839     {
840     0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
841     };
842     static const u8 cmd4d[8] =
843     {
844     0xff, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
845     };
846     static const u8 cmd4f[8] =
847     {
848     0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
849     };
850    
851     static u8 get_analog (const int key)
852     {
853     const int pad = ((key & 0xf00) / 0x100);
854     const int pos = ((key & 0x0ff) /2);
855     int value = (((int*)&global.JoyState[pad].lX)[pos] + 0x7F);
856     if (value >= 0xC0) value++;
857     if (value < 0) value = 0;
858     // Don't think this happens, but just in case...
859     if (value > 0xFF) value = 0xFF;
860     return (u8)value;
861     }
862    
863     static u8 get_pressure (const DWORD now, const DWORD press)
864     {
865     if (press == 0)
866     return 0;
867     return (u8)((now - press > 2550) ? 255 : (now - press) / 10);
868     }
869    
870     void CALLBACK PADupdate (int pad)
871     {
872     // PADupdate should be called by the emulator from the thread that owns our hwnd, but
873     // older versions of PCSX2 don't always follow that rule. I suspect this call was
874     // added to the PAD api because supposedly DInput is happiest called from the thread
875     // that owns the hwnd (although it doesn't seem to care in practice).
876    
877     // [TODO] SSSPSX really should do all it's DInput pooling/updating here, instead of
878     // in PADpoll, just for the sake of obeying thread affinity suggested guidelines.
879     // I'm not quite sure how to do that and still have it work though. --air
880     }
881    
882     // Called from the context of the EE thread.
883     u8 CALLBACK PADpoll (const u8 value)
884     {
885     const int pad = global.curPad;
886     const int cur = global.curByte;
887     static u8 buf[20];
888     if (cur == 0)
889     {
890     global.curByte++;
891     global.curCmd = value;
892     switch (value)
893     {
894     case 0x40:
895     global.cmdLen = sizeof (cmd40);
896     memcpy (buf, cmd40, sizeof (cmd40));
897     return 0xf3;
898     case 0x41:
899     global.cmdLen = sizeof (cmd41);
900     memcpy (buf, cmd41, sizeof (cmd41));
901     return 0xf3;
902     case 0x42:
903     case 0x43:
904     {
905     //EnterScopedSection scoped_lock( update_lock );
906     if (value == 0x42) UpdateState (pad);
907     global.cmdLen = 2 + 2 * (global.padID[pad] & 0x0f);
908     buf[1] = global.padModeC[pad] ? 0x00 : 0x5a;
909     (u16&)buf[2] = global.padStat[pad];
910     if (value == 0x43 && global.padModeE[pad])
911     {
912     buf[4] = 0;
913     buf[5] = 0;
914     buf[6] = 0;
915     buf[7] = 0;
916     return 0xf3;
917     }
918     else
919     {
920     buf[ 4] = get_analog (global.config.keys[pad][19]);
921     buf[ 5] = get_analog (global.config.keys[pad][20]);
922     buf[ 6] = get_analog (global.config.keys[pad][17]);
923     buf[ 7] = get_analog (global.config.keys[pad][18]);
924     if (global.padID[pad] == 0x79)
925     {
926     const DWORD now = GetTickCount();
927     buf[ 8] = get_pressure (now, global.padPress[pad][2]);
928     buf[ 9] = get_pressure (now, global.padPress[pad][0]);
929     buf[10] = get_pressure (now, global.padPress[pad][3]);
930     buf[11] = get_pressure (now, global.padPress[pad][1]);
931     buf[12] = get_pressure (now, global.padPress[pad][11]);
932     buf[13] = get_pressure (now, global.padPress[pad][10]);
933     buf[14] = get_pressure (now, global.padPress[pad][9]);
934     buf[15] = get_pressure (now, global.padPress[pad][8]);
935     buf[16] = get_pressure (now, global.padPress[pad][13]);
936     buf[17] = get_pressure (now, global.padPress[pad][12]);
937     buf[18] = get_pressure (now, global.padPress[pad][15]);
938     buf[19] = get_pressure (now, global.padPress[pad][14]);
939     }
940     return (u8)global.padID[pad];
941     }
942     break;
943     }
944     case 0x44:
945     global.cmdLen = sizeof (cmd44);
946     memcpy (buf, cmd44, sizeof (cmd44));
947     return 0xf3;
948     case 0x45:
949     global.cmdLen = sizeof (cmd45);
950     memcpy (buf, cmd45, sizeof (cmd45));
951     buf[4] = (u8)global.padMode1[pad];
952     return 0xf3;
953     case 0x46:
954     global.cmdLen = sizeof (cmd46);
955     memcpy (buf, cmd46, sizeof (cmd46));
956     return 0xf3;
957     case 0x47:
958     global.cmdLen = sizeof (cmd47);
959     memcpy (buf, cmd47, sizeof (cmd47));
960     return 0xf3;
961     case 0x4c:
962     global.cmdLen = sizeof (cmd4c);
963     memcpy (buf, cmd4c, sizeof (cmd4c));
964     return 0xf3;
965     case 0x4d:
966     global.cmdLen = sizeof (cmd4d);
967     memcpy (buf, cmd4d, sizeof (cmd4d));
968     return 0xf3;
969     case 0x4f:
970     {
971     //EnterScopedSection scoped_lock( update_lock );
972     global.padID[pad] = 0x79;
973     global.padMode2[pad] = 1;
974     global.cmdLen = sizeof (cmd4f);
975     memcpy (buf, cmd4f, sizeof (cmd4f));
976     return 0xf3;
977     }
978     }
979     }
980    
981     //EnterScopedSection scoped_lock( update_lock );
982    
983     switch (global.curCmd)
984     {
985     case 0x42:
986     if (cur == global.padVib0[pad])
987     global.padVibF[pad][0] = value;
988     if (cur == global.padVib1[pad])
989     global.padVibF[pad][1] = value;
990     break;
991     case 0x43:
992     if (cur == 2)
993     {
994     global.padModeE[pad] = value;
995     global.padModeC[pad] = 0;
996     }
997     break;
998     case 0x44:
999     if (cur == 2)
1000     PADsetMode (pad, value);
1001     if (cur == 3)
1002     global.padModeF[pad] = (value == 3);
1003     break;
1004     case 0x46:
1005     if (cur == 2)
1006     {
1007     switch(value)
1008     {
1009     case 0:
1010     buf[5] = 0x02;
1011     buf[6] = 0x00;
1012     buf[7] = 0x0A;
1013     break;
1014     case 1:
1015     buf[5] = 0x01;
1016     buf[6] = 0x01;
1017     buf[7] = 0x14;
1018     break;
1019     }
1020     }
1021     break;
1022     case 0x4c:
1023     if (cur == 2)
1024     {
1025     static const u8 buf5[] = { 0x04, 0x07, 0x02, 0x05 };
1026     buf[5] = buf5[value & 3];
1027     }
1028     break;
1029     case 0x4d:
1030     if (cur >= 2)
1031     {
1032     if (cur == global.padVib0[pad])
1033     buf[cur] = 0x00;
1034     if (cur == global.padVib1[pad])
1035     buf[cur] = 0x01;
1036     if (value == 0x00)
1037     {
1038     global.padVib0[pad] = cur;
1039     if ((global.padID[pad] & 0x0f) < (cur - 1) / 2)
1040     global.padID[pad] = (global.padID[pad] & 0xf0) + (cur - 1) / 2;
1041     }
1042     else if (value == 0x01)
1043     {
1044     global.padVib1[pad] = cur;
1045     if ((global.padID[pad] & 0x0f) < (cur - 1) / 2)
1046     global.padID[pad] = (global.padID[pad] & 0xf0) + (cur - 1) / 2;
1047     }
1048     }
1049     break;
1050     }
1051     if (cur >= global.cmdLen)
1052     return 0;
1053     return buf[global.curByte++];
1054     }
1055    
1056     typedef struct
1057     {
1058     unsigned char controllerType;
1059     unsigned short buttonStatus;
1060     unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY;
1061     unsigned char moveX, moveY;
1062     unsigned char reserved[91];
1063     } PadDataS;
1064    
1065     long CALLBACK PADreadPort1 (PadDataS* pads)
1066     {
1067     memset (pads, 0, sizeof (PadDataS));
1068     if ((global.padID[0] & 0xf0) == 0x40)
1069     pads->controllerType = 4;
1070     else
1071     pads->controllerType = 7;
1072     pads->buttonStatus = global.padStat[0];
1073     pads->leftJoyX = get_analog (global.config.keys[0][17]);
1074     pads->leftJoyY = get_analog (global.config.keys[0][18]);
1075     pads->rightJoyX = get_analog (global.config.keys[0][19]);
1076     pads->rightJoyY = get_analog (global.config.keys[0][20]);
1077     pads->moveX = 0;
1078     pads->moveY = 0;
1079     return 0;
1080     }
1081    
1082     long CALLBACK PADreadPort2 (PadDataS* pads)
1083     {
1084     memset (pads, 0, sizeof (PadDataS));
1085     if ((global.padID[1] & 0xf0) == 0x40)
1086     pads->controllerType = 4;
1087     else
1088     pads->controllerType = 7;
1089     pads->buttonStatus = global.padStat[1];
1090     pads->leftJoyX = get_analog (global.config.keys[1][17]);
1091     pads->leftJoyY = get_analog (global.config.keys[1][18]);
1092     pads->rightJoyX = get_analog (global.config.keys[1][19]);
1093     pads->rightJoyY = get_analog (global.config.keys[1][20]);
1094     pads->moveX = 0;
1095     pads->moveY = 0;
1096     return 0;
1097     }
1098    
1099     keyEvent* CALLBACK PADkeyEvent (void)
1100     {
1101     if (n_open)
1102     {
1103     memcpy (save.state[0], save.state[1], sizeof (save.state[0]));
1104     GetKeyState (save.state[1]);
1105     for (int cnt = 0; cnt < 256; cnt++)
1106     {
1107     if ((~save.state[0][cnt] & save.state[1][cnt] & 0x80) ||
1108     (save.state[0][cnt] & ~save.state[1][cnt] & 0x80))
1109     {
1110     save.ev.evt = (save.state[1][cnt] & 0x80) ? 1 : 2;
1111     save.ev.key = MapVirtualKey (cnt, 1);
1112     return &save.ev;
1113     }
1114     }
1115     }
1116     return NULL;
1117     }
1118    
1119     void CALLBACK PADconfigure (void)
1120     {
1121     if (n_open == 0)
1122     {
1123     memset (&global, 0, sizeof (global));
1124     if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_DIALOG1), GetActiveWindow(), (DLGPROC)ConfigureDlgProc) == IDOK)
1125     SaveConfig();
1126     ReleaseDirectInput();
1127     }
1128     }
1129    
1130     void CALLBACK PADabout (void)
1131     {
1132     MessageBox (GetActiveWindow(), "Copyright (C) 2004-2006 Nagisa\nVersion 1.7.1\n\nModified by Jake Stine for PCSX2 0.9.7 compatibility.",
1133     "SSSPSX PAD plugin", MB_OK | MB_SETFOREGROUND);
1134     }
1135    
1136     s32 CALLBACK PADtest (void)
1137     {
1138     return 0;
1139     }
1140    
1141     void CALLBACK PADsetSettingsDir(const char* dir)
1142     {
1143     s_strIniPath = (dir==NULL) ? "inis/" : dir;
1144     }
1145    
1146     // Returns 0 on success, -1 on error.
1147     s32 CALLBACK PADfreeze (int mode, freezeData *data)
1148     {
1149     switch (mode)
1150     {
1151     case FREEZE_SIZE:
1152     data->size = 0;
1153     break;
1154    
1155     case FREEZE_LOAD:
1156     break;
1157    
1158     case FREEZE_SAVE:
1159     break;
1160     }
1161    
1162     return 0;
1163     }
1164    
1165     BOOL APIENTRY DllMain(HMODULE hInst, DWORD dwReason, LPVOID lpReserved)
1166     {
1167    
1168     if( dwReason == DLL_PROCESS_ATTACH )
1169     {
1170     hInstance = hInst;
1171     InitializeCriticalSection( &update_lock );
1172     InitializeCriticalSection( &init_lock );
1173     }
1174     else if( dwReason == DLL_PROCESS_DETACH )
1175     {
1176     DeleteCriticalSection( &update_lock );
1177     DeleteCriticalSection( &init_lock );
1178     }
1179    
1180     return TRUE;
1181     }
1182    
1183     BOOL APIENTRY EntryPoint (HMODULE hInst, DWORD dwReason, LPVOID lpReserved)
1184     {
1185     return DllMain( hInst, dwReason, lpReserved );
1186     }

  ViewVC Help
Powered by ViewVC 1.1.22