1///////////////////////////////////////////////////////////////////////////// 2// Name: src/msw/joystick.cpp 3// Purpose: wxJoystick class 4// Author: Julian Smart 5// Modified by: 6// Created: 04/01/98 7// RCS-ID: $Id: joystick.cpp 39021 2006-05-04 07:57:04Z ABX $ 8// Copyright: (c) Julian Smart 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15#ifdef __BORLANDC__ 16 #pragma hdrstop 17#endif 18 19#if wxUSE_JOYSTICK 20 21#include "wx/joystick.h" 22 23#ifndef WX_PRECOMP 24 #include "wx/string.h" 25 #include "wx/window.h" 26#endif 27 28#include "wx/msw/private.h" 29 30#if !defined(__GNUWIN32_OLD__) || defined(__CYGWIN10__) 31 #include <mmsystem.h> 32#endif 33 34// Why doesn't BC++ have joyGetPosEx? 35#if !defined(__WIN32__) || defined(__BORLANDC__) 36#define NO_JOYGETPOSEX 37#endif 38 39#include "wx/msw/registry.h" 40 41#include <regstr.h> 42 43IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject) 44 45// Attributes 46//////////////////////////////////////////////////////////////////////////// 47 48/** 49 johan@linkdata.se 2002-08-20: 50 Now returns only valid, functioning 51 joysticks, counting from the first 52 available and upwards. 53*/ 54wxJoystick::wxJoystick(int joystick) 55{ 56 JOYINFO joyInfo; 57 int i, maxsticks; 58 59 maxsticks = joyGetNumDevs(); 60 for( i=0; i<maxsticks; i++ ) 61 { 62 if( joyGetPos(i, & joyInfo) == JOYERR_NOERROR ) 63 { 64 if( !joystick ) 65 { 66 /* Found the one we want, store actual OS id and return */ 67 m_joystick = i; 68 return; 69 } 70 joystick --; 71 } 72 } 73 74 /* No such joystick, return ID 0 */ 75 m_joystick = 0; 76 return; 77} 78 79wxPoint wxJoystick::GetPosition() const 80{ 81 JOYINFO joyInfo; 82 MMRESULT res = joyGetPos(m_joystick, & joyInfo); 83 if (res == JOYERR_NOERROR ) 84 return wxPoint(joyInfo.wXpos, joyInfo.wYpos); 85 else 86 return wxPoint(0,0); 87} 88 89int wxJoystick::GetZPosition() const 90{ 91 JOYINFO joyInfo; 92 MMRESULT res = joyGetPos(m_joystick, & joyInfo); 93 if (res == JOYERR_NOERROR ) 94 return joyInfo.wZpos; 95 else 96 return 0; 97} 98 99/** 100 johan@linkdata.se 2002-08-20: 101 Return a bitmap with all button states in it, 102 like the GTK version does and Win32 does. 103*/ 104int wxJoystick::GetButtonState() const 105{ 106 JOYINFO joyInfo; 107 MMRESULT res = joyGetPos(m_joystick, & joyInfo); 108 if (res == JOYERR_NOERROR ) 109 { 110 return joyInfo.wButtons; 111#if 0 112 int buttons = 0; 113 114 if (joyInfo.wButtons & JOY_BUTTON1) 115 buttons |= wxJOY_BUTTON1; 116 if (joyInfo.wButtons & JOY_BUTTON2) 117 buttons |= wxJOY_BUTTON2; 118 if (joyInfo.wButtons & JOY_BUTTON3) 119 buttons |= wxJOY_BUTTON3; 120 if (joyInfo.wButtons & JOY_BUTTON4) 121 buttons |= wxJOY_BUTTON4; 122 123 return buttons; 124#endif 125 } 126 else 127 return 0; 128} 129 130/** 131 JLI 2002-08-20: 132 Returns -1 to signify error. 133*/ 134int wxJoystick::GetPOVPosition() const 135{ 136#ifndef NO_JOYGETPOSEX 137 JOYINFOEX joyInfo; 138 joyInfo.dwFlags = JOY_RETURNPOV; 139 joyInfo.dwSize = sizeof(joyInfo); 140 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo); 141 if (res == JOYERR_NOERROR ) 142 { 143 return joyInfo.dwPOV; 144 } 145 else 146 return -1; 147#else 148 return -1; 149#endif 150} 151 152/** 153 johan@linkdata.se 2002-08-20: 154 Returns -1 to signify error. 155*/ 156int wxJoystick::GetPOVCTSPosition() const 157{ 158#ifndef NO_JOYGETPOSEX 159 JOYINFOEX joyInfo; 160 joyInfo.dwFlags = JOY_RETURNPOVCTS; 161 joyInfo.dwSize = sizeof(joyInfo); 162 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo); 163 if (res == JOYERR_NOERROR ) 164 { 165 return joyInfo.dwPOV; 166 } 167 else 168 return -1; 169#else 170 return -1; 171#endif 172} 173 174int wxJoystick::GetRudderPosition() const 175{ 176#ifndef NO_JOYGETPOSEX 177 JOYINFOEX joyInfo; 178 joyInfo.dwFlags = JOY_RETURNR; 179 joyInfo.dwSize = sizeof(joyInfo); 180 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo); 181 if (res == JOYERR_NOERROR ) 182 { 183 return joyInfo.dwRpos; 184 } 185 else 186 return 0; 187#else 188 return 0; 189#endif 190} 191 192int wxJoystick::GetUPosition() const 193{ 194#ifndef NO_JOYGETPOSEX 195 JOYINFOEX joyInfo; 196 joyInfo.dwFlags = JOY_RETURNU; 197 joyInfo.dwSize = sizeof(joyInfo); 198 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo); 199 if (res == JOYERR_NOERROR ) 200 { 201 return joyInfo.dwUpos; 202 } 203 else 204 return 0; 205#else 206 return 0; 207#endif 208} 209 210int wxJoystick::GetVPosition() const 211{ 212#ifndef NO_JOYGETPOSEX 213 JOYINFOEX joyInfo; 214 joyInfo.dwFlags = JOY_RETURNV; 215 joyInfo.dwSize = sizeof(joyInfo); 216 MMRESULT res = joyGetPosEx(m_joystick, & joyInfo); 217 if (res == JOYERR_NOERROR ) 218 { 219 return joyInfo.dwVpos; 220 } 221 else 222 return 0; 223#else 224 return 0; 225#endif 226} 227 228int wxJoystick::GetMovementThreshold() const 229{ 230 UINT thresh = 0; 231 MMRESULT res = joyGetThreshold(m_joystick, & thresh); 232 if (res == JOYERR_NOERROR ) 233 { 234 return thresh; 235 } 236 else 237 return 0; 238} 239 240void wxJoystick::SetMovementThreshold(int threshold) 241{ 242 UINT thresh = threshold; 243 joySetThreshold(m_joystick, thresh); 244} 245 246// Capabilities 247//////////////////////////////////////////////////////////////////////////// 248 249/** 250 johan@linkdata.se 2002-08-20: 251 Now returns the number of connected, functioning 252 joysticks, as intended. 253*/ 254int wxJoystick::GetNumberJoysticks() 255{ 256 JOYINFO joyInfo; 257 int i, maxsticks, actualsticks; 258 maxsticks = joyGetNumDevs(); 259 actualsticks = 0; 260 for( i=0; i<maxsticks; i++ ) 261 { 262 if( joyGetPos( i, & joyInfo ) == JOYERR_NOERROR ) 263 { 264 actualsticks ++; 265 } 266 } 267 return actualsticks; 268} 269 270/** 271 johan@linkdata.se 2002-08-20: 272 The old code returned true if there were any 273 joystick capable drivers loaded (=always). 274*/ 275bool wxJoystick::IsOk() const 276{ 277 JOYINFO joyInfo; 278 return (joyGetPos(m_joystick, & joyInfo) == JOYERR_NOERROR); 279} 280 281int wxJoystick::GetManufacturerId() const 282{ 283 JOYCAPS joyCaps; 284 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 285 return 0; 286 else 287 return joyCaps.wMid; 288} 289 290int wxJoystick::GetProductId() const 291{ 292 JOYCAPS joyCaps; 293 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 294 return 0; 295 else 296 return joyCaps.wPid; 297} 298 299wxString wxJoystick::GetProductName() const 300{ 301 wxString str; 302#ifndef __WINE__ 303 JOYCAPS joyCaps; 304 if (joyGetDevCaps(m_joystick, &joyCaps, sizeof(joyCaps)) != JOYERR_NOERROR) 305 return wxEmptyString; 306 307 wxRegKey key1(wxString::Format(wxT("HKEY_LOCAL_MACHINE\\%s\\%s\\%s"), 308 REGSTR_PATH_JOYCONFIG, joyCaps.szRegKey, REGSTR_KEY_JOYCURR)); 309 310 key1.QueryValue(wxString::Format(wxT("Joystick%d%s"), 311 m_joystick + 1, REGSTR_VAL_JOYOEMNAME), 312 str); 313 314 wxRegKey key2(wxString::Format(wxT("HKEY_LOCAL_MACHINE\\%s\\%s"), 315 REGSTR_PATH_JOYOEM, str.c_str())); 316 key2.QueryValue(REGSTR_VAL_JOYOEMNAME, str); 317#endif 318 return str; 319} 320 321int wxJoystick::GetXMin() const 322{ 323 JOYCAPS joyCaps; 324 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 325 return 0; 326 else 327 return joyCaps.wXmin; 328} 329 330int wxJoystick::GetYMin() const 331{ 332 JOYCAPS joyCaps; 333 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 334 return 0; 335 else 336 return joyCaps.wYmin; 337} 338 339int wxJoystick::GetZMin() const 340{ 341 JOYCAPS joyCaps; 342 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 343 return 0; 344 else 345 return joyCaps.wZmin; 346} 347 348int wxJoystick::GetXMax() const 349{ 350 JOYCAPS joyCaps; 351 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 352 return 0; 353 else 354 return joyCaps.wXmax; 355} 356 357int wxJoystick::GetYMax() const 358{ 359 JOYCAPS joyCaps; 360 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 361 return 0; 362 else 363 return joyCaps.wYmax; 364} 365 366int wxJoystick::GetZMax() const 367{ 368 JOYCAPS joyCaps; 369 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 370 return 0; 371 else 372 return joyCaps.wZmax; 373} 374 375int wxJoystick::GetNumberButtons() const 376{ 377 JOYCAPS joyCaps; 378 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 379 return 0; 380 else 381 return joyCaps.wNumButtons; 382} 383 384int wxJoystick::GetNumberAxes() const 385{ 386#if defined(__WIN32__) 387 JOYCAPS joyCaps; 388 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 389 return 0; 390 else 391 return joyCaps.wNumAxes; 392#else 393 return 0; 394#endif 395} 396 397int wxJoystick::GetMaxButtons() const 398{ 399#if defined(__WIN32__) 400 JOYCAPS joyCaps; 401 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 402 return 0; 403 else 404 return joyCaps.wMaxButtons; 405#else 406 return 0; 407#endif 408} 409 410int wxJoystick::GetMaxAxes() const 411{ 412#if defined(__WIN32__) 413 JOYCAPS joyCaps; 414 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 415 return 0; 416 else 417 return joyCaps.wMaxAxes; 418#else 419 return 0; 420#endif 421} 422 423int wxJoystick::GetPollingMin() const 424{ 425 JOYCAPS joyCaps; 426 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 427 return 0; 428 else 429 return joyCaps.wPeriodMin; 430} 431 432int wxJoystick::GetPollingMax() const 433{ 434 JOYCAPS joyCaps; 435 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 436 return 0; 437 else 438 return joyCaps.wPeriodMax; 439} 440 441int wxJoystick::GetRudderMin() const 442{ 443#if defined(__WIN32__) 444 JOYCAPS joyCaps; 445 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 446 return 0; 447 else 448 return joyCaps.wRmin; 449#else 450 return 0; 451#endif 452} 453 454int wxJoystick::GetRudderMax() const 455{ 456#if defined(__WIN32__) 457 JOYCAPS joyCaps; 458 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 459 return 0; 460 else 461 return joyCaps.wRmax; 462#else 463 return 0; 464#endif 465} 466 467int wxJoystick::GetUMin() const 468{ 469#if defined(__WIN32__) 470 JOYCAPS joyCaps; 471 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 472 return 0; 473 else 474 return joyCaps.wUmin; 475#else 476 return 0; 477#endif 478} 479 480int wxJoystick::GetUMax() const 481{ 482#if defined(__WIN32__) 483 JOYCAPS joyCaps; 484 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 485 return 0; 486 else 487 return joyCaps.wUmax; 488#else 489 return 0; 490#endif 491} 492 493int wxJoystick::GetVMin() const 494{ 495#if defined(__WIN32__) 496 JOYCAPS joyCaps; 497 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 498 return 0; 499 else 500 return joyCaps.wVmin; 501#else 502 return 0; 503#endif 504} 505 506int wxJoystick::GetVMax() const 507{ 508#if defined(__WIN32__) 509 JOYCAPS joyCaps; 510 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 511 return 0; 512 else 513 return joyCaps.wVmax; 514#else 515 return 0; 516#endif 517} 518 519 520bool wxJoystick::HasRudder() const 521{ 522#if defined(__WIN32__) 523 JOYCAPS joyCaps; 524 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 525 return false; 526 else 527 return ((joyCaps.wCaps & JOYCAPS_HASR) == JOYCAPS_HASR); 528#else 529 return false; 530#endif 531} 532 533bool wxJoystick::HasZ() const 534{ 535#if defined(__WIN32__) 536 JOYCAPS joyCaps; 537 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 538 return false; 539 else 540 return ((joyCaps.wCaps & JOYCAPS_HASZ) == JOYCAPS_HASZ); 541#else 542 return false; 543#endif 544} 545 546bool wxJoystick::HasU() const 547{ 548#if defined(__WIN32__) 549 JOYCAPS joyCaps; 550 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 551 return false; 552 else 553 return ((joyCaps.wCaps & JOYCAPS_HASU) == JOYCAPS_HASU); 554#else 555 return false; 556#endif 557} 558 559bool wxJoystick::HasV() const 560{ 561#if defined(__WIN32__) 562 JOYCAPS joyCaps; 563 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 564 return false; 565 else 566 return ((joyCaps.wCaps & JOYCAPS_HASV) == JOYCAPS_HASV); 567#else 568 return false; 569#endif 570} 571 572bool wxJoystick::HasPOV() const 573{ 574#if defined(__WIN32__) 575 JOYCAPS joyCaps; 576 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 577 return false; 578 else 579 return ((joyCaps.wCaps & JOYCAPS_HASPOV) == JOYCAPS_HASPOV); 580#else 581 return false; 582#endif 583} 584 585bool wxJoystick::HasPOV4Dir() const 586{ 587#if defined(__WIN32__) 588 JOYCAPS joyCaps; 589 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 590 return false; 591 else 592 return ((joyCaps.wCaps & JOYCAPS_POV4DIR) == JOYCAPS_POV4DIR); 593#else 594 return false; 595#endif 596} 597 598bool wxJoystick::HasPOVCTS() const 599{ 600#if defined(__WIN32__) 601 JOYCAPS joyCaps; 602 if (joyGetDevCaps(m_joystick, & joyCaps, sizeof(JOYCAPS)) != JOYERR_NOERROR) 603 return false; 604 else 605 return ((joyCaps.wCaps & JOYCAPS_POVCTS) == JOYCAPS_POVCTS); 606#else 607 return false; 608#endif 609} 610 611// Operations 612//////////////////////////////////////////////////////////////////////////// 613 614bool wxJoystick::SetCapture(wxWindow* win, int pollingFreq) 615{ 616 BOOL changed = (pollingFreq == 0); 617 MMRESULT res = joySetCapture((HWND) win->GetHWND(), m_joystick, pollingFreq, changed); 618 return (res == JOYERR_NOERROR); 619} 620 621bool wxJoystick::ReleaseCapture() 622{ 623 MMRESULT res = joyReleaseCapture(m_joystick); 624 return (res == JOYERR_NOERROR); 625} 626 627#endif // wxUSE_JOYSTICK 628