\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88/CDirectInput.cpp on 'feature/Fixing_DirectSound_memoryleak' - RSS feed" href="/view?p=dtxmania/dtxmania.git;a=rss;f=DTXViewer%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/@FDK10%C3%A3%C2%83%C2%97%C3%A3%C2%83%C2%AD%C3%A3%C2%82%C2%B8%C3%A3%C2%82%C2%A7%C3%A3%C2%82%C2%AF%C3%A3%C2%83%C2%88/CDirectInput.cpp;h=refs/heads/feature/Fixing_DirectSound_memoryleak" type="application/rss+xml" /> \83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88/CDirectInput.cpp on 'feature/Fixing_DirectSound_memoryleak' - RSS feed (no merges)" href="/view?p=dtxmania/dtxmania.git;a=rss;f=DTXViewer%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/@FDK10%C3%A3%C2%83%C2%97%C3%A3%C2%83%C2%AD%C3%A3%C2%82%C2%B8%C3%A3%C2%82%C2%A7%C3%A3%C2%82%C2%AF%C3%A3%C2%83%C2%88/CDirectInput.cpp;h=refs/heads/feature/Fixing_DirectSound_memoryleak;opt=--no-merges" type="application/rss+xml" /> \83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88/CDirectInput.cpp on 'feature/Fixing_DirectSound_memoryleak' - Atom feed" href="/view?p=dtxmania/dtxmania.git;a=atom;f=DTXViewer%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/@FDK10%C3%A3%C2%83%C2%97%C3%A3%C2%83%C2%AD%C3%A3%C2%82%C2%B8%C3%A3%C2%82%C2%A7%C3%A3%C2%82%C2%AF%C3%A3%C2%83%C2%88/CDirectInput.cpp;h=refs/heads/feature/Fixing_DirectSound_memoryleak" type="application/atom+xml" /> \83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88/CDirectInput.cpp on 'feature/Fixing_DirectSound_memoryleak' - Atom feed (no merges)" href="/view?p=dtxmania/dtxmania.git;a=atom;f=DTXViewer%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/@FDK10%C3%A3%C2%83%C2%97%C3%A3%C2%83%C2%AD%C3%A3%C2%82%C2%B8%C3%A3%C2%82%C2%A7%C3%A3%C2%82%C2%AF%C3%A3%C2%83%C2%88/CDirectInput.cpp;h=refs/heads/feature/Fixing_DirectSound_memoryleak;opt=--no-merges" type="application/atom+xml" />

OSDN Git Service

DirectSoundでClone()するとメモリリークする問題修正の途中版。WAVデータ実体への参照カウンタを実装済み。
[dtxmania/dtxmania.git] / DTXViewerプロジェクト / @FDK10ã\83\97ã\83­ã\82¸ã\82§ã\82¯ã\83\88 / CDirectInput.cpp
1 #include "stdafx.h"
2 #include "CDirectInput.h"
3 #include "FDKError.h"
4
5 namespace FDK {
6         namespace IO {
7
8 // JOYSTICK\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94
9 static BOOL CALLBACK EnumJoySticksCallback( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef ) {
10         return ((CDirectInput*) pvRef)->EnumJoySticksCallback( lpddi );
11 }
12 CDirectInput::CDirectInput()
13 {
14         // COM \82Ì\8f\89\8aú\89»
15         m_bNeedCleanupCOM       = SUCCEEDED( CoInitialize( NULL ) ) ? true : false;
16         this->pDI                               = NULL;
17         this->pDIDKeyboard              = NULL;
18         this->nJoySticks                = 0;
19 }
20
21 CDirectInput::~CDirectInput()
22 {
23         // COM \82Ì\8fI\97¹\81iCOM \82Ì\8f\89\8aú\89»\82É\8e¸\94s\82µ\82Ä\82¢\82é\8fê\8d\87\82Í\83X\83L\83b\83v\81j
24         if( m_bNeedCleanupCOM )
25                 CoUninitialize();
26 }
27
28 HRESULT CDirectInput::Init( HWND hWnd )
29 {
30         HRESULT hr;
31
32         // DirectInput7 \82Ì\90\90¬
33         if( FAILED( hr = DirectInputCreateEx( GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput7, (void**)&this->pDI, NULL ) ) )
34                 return hr;      // \8e¸\94s
35
36         // \83L\81[\83{\81[\83h\83f\83o\83C\83X\82Ì\8f\89\8aú\89»
37         if( FAILED( hr = InitKeyboard( hWnd ) ) )
38         {
39                 Term();
40                 return hr;      // \8e¸\94s
41         }
42
43         // \83W\83\87\83C\83X\83e\83B\83b\83N\83f\83o\83C\83X\82Ì\8f\89\8aú\89»
44         if( FAILED( hr = InitJoySticks( hWnd ) ) )
45         {
46                 Term();
47                 return hr;      //      \8e¸\94s
48         }
49
50         return S_OK;
51 }
52
53 HRESULT CDirectInput::InitKeyboard( HWND hWnd )
54 {
55         HRESULT hr;
56
57         // \93à\95\94\95Ï\90\94\82Ì\8f\89\8aú\89»
58         for( int i = 0; i < 256; i++ )
59         {
60                 this->byKeyState[i] = 0x00;
61                 this->bKeyPushDown[i] = false;
62                 this->bKeyPullUp[i] = false;
63         }
64
65         // \83L\81[\83{\81[\83h\83f\83o\83C\83X\82Ì\90\90¬
66         if( FAILED( hr = this->pDI->CreateDeviceEx( GUID_SysKeyboard, IID_IDirectInputDevice7, (LPVOID*)&this->pDIDKeyboard, NULL ) ) )
67         {
68                 this->pDIDKeyboard = NULL;
69                 return hr;              // \8e¸\94s
70         }
71         
72         // \83L\81[\83{\81[\83h\82Ì\83f\81[\83^\8c`\8e®\82Ì\90Ý\92è
73         if( FAILED( hr = this->pDIDKeyboard->SetDataFormat( &c_dfDIKeyboard ) ) )
74         {
75                 SAFE_RELEASE( this->pDIDKeyboard );
76                 return hr;              // \8e¸\94s
77         }
78
79         // \83L\81[\83{\81[\83h\82Ì\8b¦\92²\83\8c\83x\83\8b\82Ì\90Ý\92è
80         // WindowNT\82Å\93®\8dì\82³\82¹\82é\82É\82Í\81A\82±\82±\82Í DISCL_FOREGROUND | DISCL_NONEXCLUSIVE \82Å\82È\82­\82Ä\82Í\82¢\82¯\82È\82¢\81B
81         if( FAILED( hr = this->pDIDKeyboard->SetCooperativeLevel( hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY ) ) )
82         {
83                 SAFE_RELEASE( this->pDIDKeyboard );
84                 return hr;              // \8e¸\94s
85         }
86
87         // \83L\81[\83{\81[\83h\82Ì\83C\83x\83\93\83g\8eæ\93¾\97p\83o\83b\83t\83@\83T\83C\83Y MAX_DIEVENT_BUFFER \82ð\90Ý\92è\81B
88         DIPROPDWORD dipdw;
89         dipdw.diph.dwSize       = sizeof( DIPROPDWORD );
90         dipdw.diph.dwHeaderSize = sizeof( DIPROPHEADER );
91         dipdw.diph.dwObj        = 0;
92         dipdw.diph.dwHow        = DIPH_DEVICE;
93         dipdw.dwData            = MAX_DIEVENT_BUFFER;
94         if( FAILED( hr = this->pDIDKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
95         {
96                 SAFE_RELEASE( this->pDIDKeyboard );
97                 return hr;              // \8e¸\94s
98         }
99
100         // Acquire
101         //this->pDIDKeyboard->Acquire();                Acquire \82Í\8ds\82í\82¸\82É\8fI\97¹\81B\81i\81¨ Init() \8cã\82É\83v\83\8d\83p\83e\83B\82ð\90Ý\92è\82Å\82«\82é\81B\81j
102
103         return S_OK;
104 }
105
106 HRESULT CDirectInput::InitJoySticks( HWND hWnd )
107 {
108         HRESULT hr;
109
110         // \83W\83\87\83C\83X\83e\83B\83b\83N\82Ì\97ñ\8b\93
111         this->nJoySticks = 0;
112         if( FAILED( hr = this->pDI->EnumDevices( DIDEVTYPE_JOYSTICK, FDK::IO::EnumJoySticksCallback, (void*)this, DIEDFL_ATTACHEDONLY ) ) )
113                 return hr;      // \8e¸\94s
114
115         // \82»\82ê\82¼\82ê\82Ì\83W\83\87\83C\83X\83e\83B\83b\83N\83f\83o\83C\83X\82É\82Â\82¢\82Ä...
116         for( int i = 0; i < this->nJoySticks; i++ )
117         {
118                 // \8f\89\8aú\89»
119                 ZeroMemory( (LPVOID) &m_JoyStickInfo[i].state, sizeof( DIJOYSTATE2 ) );
120                 for( int j = 0; j < 128; j++ ) {
121                         m_JoyStickInfo[i].bPushDown[j] = false;
122                         m_JoyStickInfo[i].bPullUp[j] = false;
123                 }
124                 for( int j = 0; j < 3; j++ )
125                         m_JoyStickInfo[i].lMin[j] = m_JoyStickInfo[i].lMax[j] = 0;
126                 
127                 for( int j = 0; j < 6; j++ ) {
128                         m_JoyStickInfo[i].bAxisDown[0][j] = false;
129                         m_JoyStickInfo[i].bAxisDown[1][j] = false;
130                 }
131                 m_JoyStickInfo[i].nAxisDownIndex = 0;
132
133                 // \83W\83\87\83C\83X\83e\83B\83b\83N\83f\83o\83C\83X\82Ì\90\90¬
134                 if( FAILED( hr = this->pDI->CreateDeviceEx( m_JoyStickInfo[i].instance.guidInstance, IID_IDirectInputDevice7, (LPVOID*)&(m_JoyStickInfo[i].pDID), NULL ) ) )
135                 {
136                         m_JoyStickInfo[i].pDID = NULL;
137                         continue;               // \92\86\92f\82¹\82¸\8e\9f\82Ì\83W\83\87\83C\83X\83e\83B\83b\83N\82Ö\91J\88Ú
138                 }
139
140                 // \83W\83\87\83C\83X\83e\83B\83b\83N\82Ì\83f\81[\83^\8c`\8e®\82Ì\90Ý\92è
141                 if( FAILED( hr = m_JoyStickInfo[i].pDID->SetDataFormat( &c_dfDIJoystick2 ) ) )
142                 {
143                         SAFE_RELEASE( m_JoyStickInfo[i].pDID );
144                         continue;               // \92\86\92f\82¹\82¸\8e\9f\82Ì\83W\83\87\83C\83X\83e\83B\83b\83N\82Ö\91J\88Ú
145                 }
146
147                 // \83W\83\87\83C\83X\83e\83B\83b\83N\82Ì\8b¦\92²\83\8c\83x\83\8b\82Ì\90Ý\92è
148                 if( FAILED( hr = m_JoyStickInfo[i].pDID->SetCooperativeLevel( hWnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE ) ) )
149                 {
150                         SAFE_RELEASE( m_JoyStickInfo[i].pDID );
151                         continue;               // \92\86\92f\82¹\82¸\8e\9f\82Ì\83W\83\87\83C\83X\83e\83B\83b\83N\82Ö\91J\88Ú
152                 }
153
154                 // \83C\83x\83\93\83g\8eæ\93¾\97p\83o\83b\83t\83@\83T\83C\83Y\82Ì\90Ý\92è
155                 DIPROPDWORD dipdw;
156                 dipdw.diph.dwSize       = sizeof( DIPROPDWORD );
157                 dipdw.diph.dwHeaderSize = sizeof( DIPROPHEADER );
158                 dipdw.diph.dwObj        = 0;
159                 dipdw.diph.dwHow        = DIPH_DEVICE;
160                 dipdw.dwData            = MAX_DIEVENT_BUFFER;
161                 if( FAILED( hr = m_JoyStickInfo[i].pDID->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
162                 {
163                         SAFE_RELEASE( m_JoyStickInfo[i].pDID );
164                         continue;               // \92\86\92f\82¹\82¸\8e\9f\82Ì\83W\83\87\83C\83X\83e\83B\83b\83N\82Ö\91J\88Ú
165                 }
166  
167                 // X,Y,Z\8e²\82Ì\92l\88æ\82Ì\8eæ\93¾
168                 for( int j = 0; j < 3; j++ )
169                 {
170                         static const DWORD dwObj[3] = { DIJOFS_X, DIJOFS_Y, DIJOFS_Z };
171                         DIPROPRANGE dipr;
172                         dipr.diph.dwSize = sizeof( DIPROPRANGE );
173                         dipr.diph.dwHeaderSize = sizeof( DIPROPHEADER );
174                         dipr.diph.dwObj = dwObj[j];
175                         dipr.diph.dwHow = DIPH_BYOFFSET;
176                         dipr.lMin = dipr.lMax = 0;
177                         if( SUCCEEDED( m_JoyStickInfo[i].pDID->GetProperty( DIPROP_RANGE, &dipr.diph ) ) ) {
178                                 m_JoyStickInfo[i].lMin[j] = dipr.lMin;
179                                 m_JoyStickInfo[i].lMax[j] = dipr.lMax;
180                         }
181                 }
182
183                 // Acquire
184                 //m_JoyStickInfo[i].pDID->Acquire();    //              Acquire \82Í\8ds\82í\82È\82¢\81B\81i\81¨ Init() \8cã\82É\83v\83\8d\83p\83e\83B\82ð\90Ý\92è\82Å\82«\82é\81B\81j
185         }
186
187         return S_OK;
188 }
189
190 BOOL CDirectInput::EnumJoySticksCallback( LPCDIDEVICEINSTANCE lpddi )
191 {
192         if( this->nJoySticks >= MAX_JOYSTICKS )
193                 return DIENUM_STOP;             // \90\94\82ª\91½\82¢
194
195         CopyMemory( &m_JoyStickInfo[ this->nJoySticks ].instance, lpddi, sizeof( DIDEVICEINSTANCE ) );
196         this->nJoySticks ++;
197
198         return DIENUM_CONTINUE;
199 }
200
201 bool CDirectInput::Poll()
202 {
203         bool bRet = true;
204         
205         if( ! Poll\83L\81[\83{\81[\83h() )
206                 bRet = false;
207
208         if(  ! Poll\83W\83\87\83C\83X\83e\83B\83b\83N() )
209                 bRet = false;
210
211         return bRet;
212 }
213
214
215 bool CDirectInput::Poll\83L\81[\83{\81[\83h()
216 {
217         // \8fó\91Ô\83N\83\8a\83A
218         for( int i = 0; i < 256; i++ ) 
219         {
220                 this->bKeyPullUp[i] = false;
221                 this->bKeyPushDown[i] = false;
222         }
223
224         if( ! this->pDIDKeyboard )
225                 return true;    // \96¢\8f\89\8aú\89»
226
227         // Acquire \82µ\82Ä\82Ý\82é
228         HRESULT hr = this->pDIDKeyboard->Acquire();
229         if( hr != DI_OK && hr != S_FALSE )              // \90¬\8c÷\82·\82ê\82ΠDI_OK, \8eæ\93¾\8dÏ\82Ý\82È\82ç S_FALSE \82ª\95Ô\82é\81B
230                 return false;
231
232         // \83|\81[\83\8a\83\93\83O
233         if( FAILED( this->pDIDKeyboard->Poll() ) )
234                 return false;
235
236         // 1.\8fó\91Ô\8eæ\93¾
237         if( FAILED( this->pDIDKeyboard->GetDeviceState( 256, this->byKeyState ) ) )
238                 ZeroMemory( this->byKeyState, 256 );            // \8fó\91Ô\8eæ\93¾\82É\8e¸\94s\82µ\82½\82ç\91SOFF\88µ\82¢
239
240         // 2.\83C\83x\83\93\83g\8eæ\93¾
241         DIDEVICEOBJECTDATA ddod[ MAX_DIEVENT_BUFFER ];
242         DWORD dwItems = MAX_DIEVENT_BUFFER;
243         if( SUCCEEDED( this->pDIDKeyboard->GetDeviceData( sizeof( DIDEVICEOBJECTDATA ), ddod, &dwItems, 0 ) ) )
244         {
245                 for( DWORD i = 0; i < dwItems; i++ )
246                 {
247                         if( ( ddod[i].dwData & 0xFF ) == 0 )
248                                 this->bKeyPullUp[ ddod[i].dwOfs ] = true;               // \83L\81[\82ª\97£\82³\82ê\82½
249                         else
250                                 this->bKeyPushDown[ ddod[i].dwOfs ] = true;             // \83L\81[\82ª\89\9f\82³\82ê\82½
251                 }
252         }
253         return true;
254 }
255
256 bool CDirectInput::Poll\83W\83\87\83C\83X\83e\83B\83b\83N()
257 {
258         for( int i = 0; i < this->nJoySticks; i++ )
259         {
260                 // \8fó\91Ô\83N\83\8a\83A
261                 for( int j = 0; j < 128; j++ ) 
262                 {
263                         m_JoyStickInfo[i].bPushDown[j] = false;
264                         m_JoyStickInfo[i].bPullUp[j] = false;
265                 }
266
267                 if( ! m_JoyStickInfo[i].pDID )
268                         continue;
269
270                 // Acquire \82µ\82Ä\82Ý\82é
271                 HRESULT hr = m_JoyStickInfo[i].pDID->Acquire();
272                 if( hr != DI_OK && hr != S_FALSE )              // \90¬\8c÷\82·\82ê\82ΠDI_OK, \8eæ\93¾\8dÏ\82Ý\82È\82ç S_FALSE \82ª\95Ô\82é\81B
273                         continue;
274
275                 // \83|\81[\83\8a\83\93\83O
276                 if( FAILED( m_JoyStickInfo[i].pDID->Poll() ) )
277                         continue;
278
279                 // 1. \8fó\91Ô\8eæ\93¾
280                 if( FAILED( m_JoyStickInfo[i].pDID->GetDeviceState( sizeof( DIJOYSTATE2 ), &m_JoyStickInfo[i].state ) ) )
281                         ZeroMemory( &m_JoyStickInfo[i].state, sizeof(DIJOYSTATE2) );                    // \8fó\91Ô\8eæ\93¾\82É\8e¸\94s\82µ\82½\82ç\91S\83{\83^\83\93OFF\88µ\82¢
282                 m_JoyStickInfo[i].nAxisDownIndex = 1 - m_JoyStickInfo[i].nAxisDownIndex;        // \8e²\8fó\91Ô\82Ì\83C\83x\83\93\83g\83`\83F\83b\83N
283                 for( int k = 0; k < 6; k++ )
284                         m_JoyStickInfo[i].bAxisDown[ m_JoyStickInfo[i].nAxisDownIndex ][ k ] = IsAxisDown( i, k );
285
286                 // 2.\83C\83x\83\93\83g\8eæ\93¾
287                 DIDEVICEOBJECTDATA ddod[ MAX_DIEVENT_BUFFER ];
288                 DWORD dwItems = MAX_DIEVENT_BUFFER;
289                 if( SUCCEEDED( m_JoyStickInfo[i].pDID->GetDeviceData( sizeof( DIDEVICEOBJECTDATA ), ddod, &dwItems, 0 ) ) )
290                 {
291                         for( DWORD ev = 0; ev < dwItems; ev++ )
292                         {
293                                 for( int k = 0; k < 128; k++ )
294                                 {
295                                         if( ddod[ ev ].dwOfs == DIJOFS_BUTTON( k ) )
296                                         {
297                                                 if( ( ddod[ ev ].dwData & 0xFF ) == 0 )
298                                                         m_JoyStickInfo[i].bPullUp[ k ] = true;                  // \83{\83^\83\93\82ª\97£\82³\82ê\82½
299                                                 else
300                                                         m_JoyStickInfo[i].bPushDown[ k ] = true;                // \83{\83^\83\93\82ª\89\9f\82³\82ê\82½
301                                         }
302                                 }
303                         }
304                 }
305         }
306         return true;
307 }
308
309 void CDirectInput::Term()
310 {
311         // \83L\81[\83{\81[\83h\83f\83o\83C\83X\82Ì\89ð\95ú
312         if( this->pDIDKeyboard )
313         {
314                 this->pDIDKeyboard->Unacquire();
315                 SAFE_RELEASE( this->pDIDKeyboard );
316         }
317
318         // \83W\83\87\83C\83X\83e\83B\83b\83N\83f\83o\83C\83X\82Ì\89ð\95ú
319         for( int i = 0; i < this->nJoySticks; i++ )
320         {
321                 if( m_JoyStickInfo[i].pDID )
322                 {
323                         m_JoyStickInfo[i].pDID->Unacquire();
324                         SAFE_RELEASE( m_JoyStickInfo[i].pDID );
325                 }
326         }
327         this->nJoySticks = 0;
328
329         // DirectInput7 \82Ì\89ð\95ú
330         SAFE_RELEASE( this->pDI );
331 }
332
333 bool CDirectInput::IsKeyDown( int nDIK )
334 {
335         return ( nDIK >= 0 && nDIK < 256 && (this->byKeyState[ nDIK ] & 0x80) != 0x00 );
336 }
337
338 bool CDirectInput::IsKeyUp( int nDIK )
339 {
340         return ( nDIK >= 0 && nDIK < 256 && (this->byKeyState[ nDIK ] & 0x80) == 0x00 );
341 }
342
343 bool CDirectInput::IsKeyPushDown( int nDIK )
344 {
345         return ( nDIK >= 0 && nDIK < 256 && this->bKeyPushDown[ nDIK ] );
346 }
347
348 bool CDirectInput::IsKeyPullUp( int nKey )
349 {
350         return ( nKey >= 0 && nKey < 256 && this->bKeyPullUp[ nKey ] );
351 }
352
353 bool CDirectInput::IsButtonDown( int nID, int nButton )
354 {
355         if( nID < 0 || nID >= this->nJoySticks || nButton < 0 || nButton > 127 || m_JoyStickInfo[ nID ].pDID == NULL )
356                 return false;
357
358         return ( ( m_JoyStickInfo[ nID ].state.rgbButtons[ nButton ] & 0x80 ) != 0x00 );
359 }
360
361 bool CDirectInput::IsButtonUp( int nID, int nButton )
362 {
363         if( nID < 0 || nID >= this->nJoySticks || nButton < 0 || nButton > 127 || m_JoyStickInfo[ nID ].pDID == NULL )
364                 return false;
365
366         return ( ( m_JoyStickInfo[ nID ].state.rgbButtons[ nButton ] & 0x80 ) == 0x00 );
367 }
368
369 bool CDirectInput::IsButtonPushDown( int nID, int nButton )
370 {
371         return ( nID >= 0 && nID < this->nJoySticks && nButton >= 0 && nButton < 128 && m_JoyStickInfo[ nID ].bPushDown[ nButton ] );
372 }
373
374 bool CDirectInput::IsButtonPullUp( int nID, int nButton )
375 {
376         return ( nID >= 0 && nID < this->nJoySticks && nButton >= 0 && nButton < 128 && m_JoyStickInfo[ nID ].bPullUp[ nButton ] );
377 }
378
379 bool CDirectInput::IsAxisDown( int nID, int nAxis )
380 {
381         if( nID < 0 || nID >= this->nJoySticks || nAxis < 0 || nAxis > 5 || m_JoyStickInfo[ nID ].pDID == NULL )
382                 return false;
383
384         if( nAxis == 0 && m_JoyStickInfo[ nID ].state.lX < ( 3 * m_JoyStickInfo[ nID ].lMin[0] +     m_JoyStickInfo[ nID ].lMax[0] ) / 4 ) return true;
385         if( nAxis == 1 && m_JoyStickInfo[ nID ].state.lX > (     m_JoyStickInfo[ nID ].lMin[0] + 3 * m_JoyStickInfo[ nID ].lMax[0] ) / 4 ) return true;
386         if( nAxis == 2 && m_JoyStickInfo[ nID ].state.lY < ( 3 * m_JoyStickInfo[ nID ].lMin[1] +     m_JoyStickInfo[ nID ].lMax[1] ) / 4 ) return true;
387         if( nAxis == 3 && m_JoyStickInfo[ nID ].state.lY > (     m_JoyStickInfo[ nID ].lMin[1] + 3 * m_JoyStickInfo[ nID ].lMax[1] ) / 4 ) return true;
388         if( nAxis == 4 && m_JoyStickInfo[ nID ].state.lZ < ( 3 * m_JoyStickInfo[ nID ].lMin[2] +     m_JoyStickInfo[ nID ].lMax[2] ) / 4 ) return true;
389         if( nAxis == 5 && m_JoyStickInfo[ nID ].state.lZ > (     m_JoyStickInfo[ nID ].lMin[2] + 3 * m_JoyStickInfo[ nID ].lMax[2] ) / 4 ) return true;
390         return false;
391 }
392
393 bool CDirectInput::IsAxisUp( int nID, int nAxis )
394 {
395         if( nID < 0 || nID >= this->nJoySticks || nAxis < 0 || nAxis > 5 || m_JoyStickInfo[ nID ].pDID == NULL )
396                 return false;
397
398         if( nAxis == 0 && m_JoyStickInfo[ nID ].state.lX >= ( 3 * m_JoyStickInfo[ nID ].lMin[0] +     m_JoyStickInfo[ nID ].lMax[0] ) / 4 ) return true;
399         if( nAxis == 1 && m_JoyStickInfo[ nID ].state.lX <= (     m_JoyStickInfo[ nID ].lMin[0] + 3 * m_JoyStickInfo[ nID ].lMax[0] ) / 4 ) return true;
400         if( nAxis == 2 && m_JoyStickInfo[ nID ].state.lY >= ( 3 * m_JoyStickInfo[ nID ].lMin[1] +     m_JoyStickInfo[ nID ].lMax[1] ) / 4 ) return true;
401         if( nAxis == 3 && m_JoyStickInfo[ nID ].state.lY <= (     m_JoyStickInfo[ nID ].lMin[1] + 3 * m_JoyStickInfo[ nID ].lMax[1] ) / 4 ) return true;
402         if( nAxis == 4 && m_JoyStickInfo[ nID ].state.lZ >= ( 3 * m_JoyStickInfo[ nID ].lMin[2] +     m_JoyStickInfo[ nID ].lMax[2] ) / 4 ) return true;
403         if( nAxis == 5 && m_JoyStickInfo[ nID ].state.lZ <= (     m_JoyStickInfo[ nID ].lMin[2] + 3 * m_JoyStickInfo[ nID ].lMax[2] ) / 4 ) return true;
404         return false;
405 }
406
407 bool CDirectInput::IsAxisPushDown( int nID, int nAxis )
408 {
409         if( nID < 0 || nID >= this->nJoySticks || nAxis < 0 || nAxis > 5 || m_JoyStickInfo[ nID ].pDID == NULL )
410                 return false;
411
412         return     ! m_JoyStickInfo[ nID ].bAxisDown[ 1 - m_JoyStickInfo[ nID ].nAxisDownIndex ][ nAxis ]
413                         &&   m_JoyStickInfo[ nID ].bAxisDown[     m_JoyStickInfo[ nID ].nAxisDownIndex ][ nAxis ];
414 }
415
416 bool CDirectInput::IsAxisPullUp( int nID, int nAxis )
417 {
418         if( nID < 0 || nID >= this->nJoySticks || nAxis < 0 || nAxis > 5 || m_JoyStickInfo[ nID ].pDID == NULL )
419                 return false;
420
421         return       m_JoyStickInfo[ nID ].bAxisDown[ 1 - m_JoyStickInfo[ nID ].nAxisDownIndex ][ nAxis ]
422                         && ! m_JoyStickInfo[ nID ].bAxisDown[     m_JoyStickInfo[ nID ].nAxisDownIndex ][ nAxis ];
423 }
424
425 LPDIJOYSTATE2 CDirectInput::GetJoyState( int nID )
426 {
427         if( nID < 0 || nID >= this->nJoySticks || m_JoyStickInfo[ nID ].pDID == NULL )
428                 return NULL;
429
430         return &(m_JoyStickInfo[ nID ].state);
431 }
432
433 HRESULT CDirectInput::GetJoyProperty( int nID, REFGUID rguidProp, LPDIPROPHEADER pdiph )
434 {
435         if( nID < 0 || nID >= this->nJoySticks || m_JoyStickInfo[ nID ].pDID == NULL )
436                 return S_FALSE;
437
438         return m_JoyStickInfo[ nID ].pDID->GetProperty( rguidProp, pdiph );
439 }
440
441         }//IO
442 }//FDK