00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00026
00028 #define _WIN32_WINNT 0x500
00029 #include <SFML/Window/Win32/WindowImplWin32.hpp>
00030 #include <GL/gl.h>
00031 #include <SFML/Window/glext/wglext.h>
00032 #include <SFML/Window/glext/glext.h>
00033 #include <mmsystem.h>
00034 #include <iostream>
00035
00036
00037 namespace sf
00038 {
00039 namespace priv
00040 {
00042
00044 unsigned int WindowImplWin32::ourWindowCount = 0;
00045 const wchar_t* WindowImplWin32::ourClassName = L"SFML_Window";
00046 WindowImplWin32* WindowImplWin32::ourDummyWindow = NULL;
00047 WindowImplWin32* WindowImplWin32::ourFullscreenWindow = NULL;
00048
00049
00054 WindowImplWin32::WindowImplWin32() :
00055 myHandle (NULL),
00056 myCallback(0),
00057 myCursor (NULL)
00058 {
00059
00060 if (ourWindowCount == 0)
00061 RegisterWindowClass();
00062
00063
00064 myWidth = 1;
00065 myHeight = 1;
00066
00067
00068 myHandle = CreateWindow(ourClassName, TEXT(""), WS_POPUP | WS_DISABLED, 0, 0, myWidth, myHeight, NULL, NULL, GetModuleHandle(NULL), NULL);
00069 ShowWindow(myHandle, SW_HIDE);
00070
00071
00072 if (myHandle)
00073 CreateContext(VideoMode(myWidth, myHeight, 32), false, 0);
00074
00075
00076 if (!ourDummyWindow)
00077 ourDummyWindow = this;
00078 }
00079
00080
00084 WindowImplWin32::WindowImplWin32(WindowHandle Handle, int AntialiasingLevel) :
00085 myCallback(0),
00086 myCursor (NULL)
00087 {
00088
00089 myHandle = static_cast<HWND>(Handle);
00090
00091 if (myHandle)
00092 {
00093
00094 RECT Rect;
00095 GetClientRect(myHandle, &Rect);
00096 myWidth = Rect.right - Rect.left;
00097 myHeight = Rect.bottom - Rect.top;
00098
00099
00100 VideoMode Mode = VideoMode::GetDesktopMode();
00101 Mode.Width = myWidth;
00102 Mode.Height = myHeight;
00103 CreateContext(Mode, false, AntialiasingLevel);
00104
00105
00106 SetWindowLongPtr(myHandle, GWLP_USERDATA, reinterpret_cast<long>(this));
00107 myCallback = SetWindowLongPtr(myHandle, GWLP_WNDPROC, reinterpret_cast<long>(&WindowImplWin32::GlobalOnEvent));
00108
00109
00110 SetupJoysticks();
00111 }
00112 }
00113
00114
00118 WindowImplWin32::WindowImplWin32(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, int AntialiasingLevel) :
00119 myHandle (NULL),
00120 myCallback(0),
00121 myCursor (NULL)
00122 {
00123
00124 if (ourWindowCount == 0)
00125 RegisterWindowClass();
00126
00127
00128 int Left = (GetDeviceCaps(GetDC(NULL), HORZRES) - Mode.Width) / 2;
00129 int Top = (GetDeviceCaps(GetDC(NULL), VERTRES) - Mode.Height) / 2;
00130 int Width = myWidth = Mode.Width;
00131 int Height = myHeight = Mode.Height;
00132
00133
00134 DWORD Win32Style = WS_VISIBLE;
00135 Win32Style |= (WindowStyle == Resizable ? WS_OVERLAPPEDWINDOW : WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
00136
00137
00138 if (WindowStyle != Fullscreen)
00139 {
00140 RECT Rect = {0, 0, Width, Height};
00141 AdjustWindowRect(&Rect, Win32Style, false);
00142 Width = Rect.right - Rect.left;
00143 Height = Rect.bottom - Rect.top;
00144 }
00145
00146
00147 wchar_t WTitle[256];
00148 int NbChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Title.c_str(), static_cast<int>(Title.size()), WTitle, sizeof(WTitle) / sizeof(*WTitle));
00149 WTitle[NbChars] = L'\0';
00150 myHandle = CreateWindow(ourClassName, WTitle, Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
00151
00152
00153 if (myHandle)
00154 CreateContext(Mode, WindowStyle == Fullscreen, AntialiasingLevel);
00155
00156
00157 ourWindowCount++;
00158
00159
00160 SetupJoysticks();
00161 }
00162
00163
00167 WindowImplWin32::~WindowImplWin32()
00168 {
00169 if (!myCallback)
00170 {
00171
00172 if (myHandle)
00173 DestroyWindow(myHandle);
00174
00175
00176 ourWindowCount--;
00177
00178
00179 if (ourWindowCount == 0)
00180 UnregisterClass(ourClassName, GetModuleHandle(NULL));
00181 }
00182 else
00183 {
00184
00185 SetWindowLongPtr(myHandle, GWLP_WNDPROC, myCallback);
00186 }
00187 }
00188
00189
00193 void WindowImplWin32::Display()
00194 {
00195 if (myDeviceContext && myGLContext)
00196 SwapBuffers(myDeviceContext);
00197 }
00198
00199
00203 void WindowImplWin32::ProcessEvents()
00204 {
00205
00206 if (!myCallback)
00207 {
00208 MSG Message;
00209 while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
00210 {
00211 TranslateMessage(&Message);
00212 DispatchMessage(&Message);
00213 }
00214 }
00215 }
00216
00217
00221 void WindowImplWin32::MakeCurrent() const
00222 {
00223 if (myDeviceContext && myGLContext)
00224 wglMakeCurrent(myDeviceContext, myGLContext);
00225 }
00226
00227
00231 void WindowImplWin32::UseVerticalSync(bool Enabled)
00232 {
00233 PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));
00234 if (wglSwapIntervalEXT)
00235 wglSwapIntervalEXT(Enabled ? 1 : 0);
00236 }
00237
00238
00242 void WindowImplWin32::ShowMouseCursor(bool Show)
00243 {
00244 if (Show)
00245 myCursor = LoadCursor(NULL, IDC_ARROW);
00246 else
00247 myCursor = NULL;
00248
00249 SetCursor(myCursor);
00250 }
00251
00252
00256 void WindowImplWin32::SetPosition(int Left, int Top)
00257 {
00258 SetWindowPos(myHandle, NULL, Left, Top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
00259 }
00260
00261
00265 void WindowImplWin32::RegisterWindowClass()
00266 {
00267 WNDCLASSW WindowClass;
00268 WindowClass.style = 0;
00269 WindowClass.lpfnWndProc = &WindowImplWin32::GlobalOnEvent;
00270 WindowClass.cbClsExtra = 0;
00271 WindowClass.cbWndExtra = 0;
00272 WindowClass.hInstance = GetModuleHandle(NULL);
00273 WindowClass.hIcon = NULL;
00274 WindowClass.hCursor = 0;
00275 WindowClass.hbrBackground = 0;
00276 WindowClass.lpszMenuName = NULL;
00277 WindowClass.lpszClassName = ourClassName;
00278
00279 RegisterClass(&WindowClass);
00280 }
00281
00282
00286 void WindowImplWin32::CreateContext(VideoMode Mode, bool Fullscreen, int AntialiasingLevel)
00287 {
00288
00289 if (Fullscreen)
00290 {
00291 DEVMODE DevMode;
00292 DevMode.dmSize = sizeof(DEVMODE);
00293 DevMode.dmPelsWidth = Mode.Width;
00294 DevMode.dmPelsHeight = Mode.Height;
00295 DevMode.dmBitsPerPel = Mode.BitsPerPixel;
00296 DevMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
00297
00298
00299 if (ChangeDisplaySettings(&DevMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
00300 {
00301 std::cerr << "Failed to change display mode for fullscreen -- cannot create OpenGL context" << std::endl;
00302 return;
00303 }
00304
00305
00306 SetWindowLong(myHandle, GWL_STYLE, WS_POPUP);
00307 SetWindowLong(myHandle, GWL_EXSTYLE, WS_EX_APPWINDOW);
00308
00309
00310 SetWindowPos(myHandle, HWND_TOP, 0, 0, Mode.Width, Mode.Height, SWP_FRAMECHANGED);
00311 ShowWindow(myHandle, SW_SHOW);
00312
00313
00314 ourFullscreenWindow = this;
00315 }
00316
00317
00318 long Style = GetWindowLong(myHandle, GWL_STYLE);
00319 SetWindowLong(myHandle, GWL_STYLE, Style | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
00320
00321
00322 myDeviceContext = GetDC(myHandle);
00323 if (myDeviceContext == NULL)
00324 {
00325 std::cerr << "Failed to get device context of window -- cannot create OpenGL context" << std::endl;
00326 return;
00327 }
00328
00329
00330 int PixelFormat = 0;
00331 if (AntialiasingLevel > 0)
00332 {
00333
00334 PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(wglGetProcAddress("wglChoosePixelFormatARB"));
00335
00336
00337 int IntAttributes[] =
00338 {
00339 WGL_SAMPLES_ARB, AntialiasingLevel,
00340 WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
00341 WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
00342 WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
00343 WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
00344 WGL_COLOR_BITS_ARB, Mode.BitsPerPixel,
00345 WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
00346 0, 0
00347 };
00348
00349
00350 int Formats[64];
00351 UINT NbFormats;
00352 float FloatAttributes[] = {0, 0};
00353 bool IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
00354 if (!IsValid || (NbFormats == 0))
00355 {
00356 if (AntialiasingLevel > 2)
00357 {
00358
00359 std::cerr << "Failed to find a pixel format supporting "
00360 << AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
00361
00362 IntAttributes[1] = 2;
00363 IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0;
00364 }
00365
00366 if (!IsValid || (NbFormats == 0))
00367 {
00368
00369 std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
00370 AntialiasingLevel = 0;
00371 }
00372 }
00373
00374
00375 if (IsValid && (NbFormats > 0))
00376 {
00377 PixelFormat = Formats[0];
00378 PIXELFORMATDESCRIPTOR BestAttribs;
00379 BestAttribs.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00380 BestAttribs.nVersion = 1;
00381 DescribePixelFormat(myDeviceContext, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &BestAttribs);
00382 for (UINT i = 1; i < NbFormats; ++i)
00383 {
00384
00385 PIXELFORMATDESCRIPTOR Attribs;
00386 Attribs.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00387 Attribs.nVersion = 1;
00388 DescribePixelFormat(myDeviceContext, Formats[i], sizeof(PIXELFORMATDESCRIPTOR), &Attribs);
00389
00390
00391 if ((BestAttribs.cStencilBits < Attribs.cStencilBits) || (BestAttribs.cDepthBits < Attribs.cDepthBits))
00392 {
00393 PixelFormat = Formats[i];
00394 BestAttribs = Attribs;
00395 }
00396 }
00397 }
00398 }
00399
00400
00401 if (AntialiasingLevel == 0)
00402 {
00403
00404 PIXELFORMATDESCRIPTOR PixelDescriptor;
00405 ZeroMemory(&PixelDescriptor, sizeof(PIXELFORMATDESCRIPTOR));
00406 PixelDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00407 PixelDescriptor.nVersion = 1;
00408 PixelDescriptor.iLayerType = PFD_MAIN_PLANE;
00409 PixelDescriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00410 PixelDescriptor.iPixelType = PFD_TYPE_RGBA;
00411 PixelDescriptor.cColorBits = static_cast<BYTE>(Mode.BitsPerPixel);
00412 PixelDescriptor.cDepthBits = 32;
00413 PixelDescriptor.cStencilBits = 8;
00414
00415
00416 PixelFormat = ChoosePixelFormat(myDeviceContext, &PixelDescriptor);
00417 if (PixelFormat == 0)
00418 {
00419 std::cerr << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl;
00420 return;
00421 }
00422 }
00423
00424
00425 PIXELFORMATDESCRIPTOR ActualDescriptor;
00426 ActualDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00427 ActualDescriptor.nVersion = 1;
00428 DescribePixelFormat(myDeviceContext, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &ActualDescriptor);
00429 myDepthBits = ActualDescriptor.cDepthBits;
00430 myStencilBits = ActualDescriptor.cStencilBits;
00431
00432
00433 if (!SetPixelFormat(myDeviceContext, PixelFormat, &ActualDescriptor))
00434 {
00435 std::cerr << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl;
00436 return;
00437 }
00438
00439
00440 myGLContext = wglCreateContext(myDeviceContext);
00441 if (myGLContext == NULL)
00442 {
00443 std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
00444 return;
00445 }
00446
00447
00448 if (wglGetCurrentContext())
00449 wglShareLists(wglGetCurrentContext(), myGLContext);
00450
00451
00452 SetCurrent();
00453
00454
00455 if (AntialiasingLevel > 0)
00456 glEnable(GL_MULTISAMPLE_ARB);
00457 }
00458
00459
00463 void WindowImplWin32::Cleanup()
00464 {
00465
00466 if (ourFullscreenWindow == this)
00467 {
00468 ChangeDisplaySettings(NULL, 0);
00469 ourFullscreenWindow = NULL;
00470 }
00471
00472
00473 ShowMouseCursor(true);
00474
00475
00476 if (myGLContext)
00477 {
00478
00479 if (this != ourDummyWindow)
00480 {
00481 if (ourDummyWindow)
00482 ourDummyWindow->SetCurrent();
00483 }
00484 else
00485 {
00486 ourDummyWindow = NULL;
00487 wglMakeCurrent(NULL, NULL);
00488 }
00489
00490
00491 wglDeleteContext(myGLContext);
00492 myGLContext = NULL;
00493 }
00494
00495
00496 if (myDeviceContext)
00497 {
00498 ReleaseDC(myHandle, myDeviceContext);
00499 myDeviceContext = NULL;
00500 }
00501 }
00502
00503
00507 void WindowImplWin32::ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam)
00508 {
00509
00510 if (myHandle == NULL)
00511 return;
00512
00513 switch (Message)
00514 {
00515
00516 case WM_DESTROY :
00517 {
00518
00519 Cleanup();
00520 break;
00521 }
00522
00523
00524 case WM_SETCURSOR :
00525 {
00526
00527 if (LOWORD(LParam) == HTCLIENT)
00528 SetCursor(myCursor);
00529
00530 break;
00531 }
00532
00533
00534 case WM_CLOSE :
00535 {
00536 Event Evt;
00537 Evt.Type = Event::Close;
00538 SendEvent(Evt);
00539 break;
00540 }
00541
00542
00543 case WM_SIZE :
00544 {
00545
00546 RECT Rect;
00547 GetClientRect(myHandle, &Rect);
00548 myWidth = Rect.right - Rect.left;
00549 myHeight = Rect.bottom - Rect.top;
00550
00551 Event Evt;
00552 Evt.Type = Event::Resize;
00553 Evt.Size.Width = myWidth;
00554 Evt.Size.Height = myHeight;
00555 SendEvent(Evt);
00556 break;
00557 }
00558
00559
00560 case WM_SETFOCUS :
00561 {
00562 Event Evt;
00563 Evt.Type = Event::GainedFocus;
00564 SendEvent(Evt);
00565 break;
00566 }
00567
00568
00569 case WM_KILLFOCUS :
00570 {
00571 Event Evt;
00572 Evt.Type = Event::LostFocus;
00573 SendEvent(Evt);
00574 break;
00575 }
00576
00577
00578 case WM_CHAR :
00579 {
00580 Event Evt;
00581 Evt.Type = Event::TextEntered;
00582 Evt.Text.Unicode = static_cast<Uint16>(WParam);
00583 SendEvent(Evt);
00584 break;
00585 }
00586
00587
00588 case WM_KEYDOWN :
00589 case WM_SYSKEYDOWN :
00590 {
00591 Event Evt;
00592 Evt.Type = Event::KeyPressed;
00593 Evt.Key.Code = VirtualKeyCodeToSF(WParam);
00594 Evt.Key.Alt = GetAsyncKeyState(VK_RMENU) || GetAsyncKeyState(VK_LMENU);
00595 Evt.Key.Control = GetAsyncKeyState(VK_RCONTROL) || GetAsyncKeyState(VK_LCONTROL);
00596 Evt.Key.Shift = GetAsyncKeyState(VK_RSHIFT) || GetAsyncKeyState(VK_LSHIFT);
00597 SendEvent(Evt);
00598 break;
00599 }
00600
00601
00602 case WM_KEYUP :
00603 case WM_SYSKEYUP :
00604 {
00605 Event Evt;
00606 Evt.Type = Event::KeyReleased;
00607 Evt.Key.Code = VirtualKeyCodeToSF(WParam);
00608 Evt.Key.Alt = GetAsyncKeyState(VK_RMENU) || GetAsyncKeyState(VK_LMENU);
00609 Evt.Key.Control = GetAsyncKeyState(VK_RCONTROL) || GetAsyncKeyState(VK_LCONTROL);
00610 Evt.Key.Shift = GetAsyncKeyState(VK_RSHIFT) || GetAsyncKeyState(VK_LSHIFT);
00611 SendEvent(Evt);
00612 break;
00613 }
00614
00615
00616 case WM_MOUSEWHEEL :
00617 {
00618 Event Evt;
00619 Evt.Type = Event::MouseWheelMoved;
00620 Evt.MouseWheel.Delta = static_cast<Int16>(HIWORD(WParam)) / WHEEL_DELTA;
00621 SendEvent(Evt);
00622 break;
00623 }
00624
00625
00626 case WM_LBUTTONDOWN :
00627 {
00628 Event Evt;
00629 Evt.Type = Event::MouseButtonPressed;
00630 Evt.Mouse.Buttons = Mouse::Left;
00631 Evt.Mouse.X = LOWORD(LParam);
00632 Evt.Mouse.Y = HIWORD(LParam);
00633 SendEvent(Evt);
00634 break;
00635 }
00636
00637
00638 case WM_LBUTTONUP :
00639 {
00640 Event Evt;
00641 Evt.Type = Event::MouseButtonReleased;
00642 Evt.Mouse.Buttons = Mouse::Left;
00643 Evt.Mouse.X = LOWORD(LParam);
00644 Evt.Mouse.Y = HIWORD(LParam);
00645 SendEvent(Evt);
00646 break;
00647 }
00648
00649
00650 case WM_RBUTTONDOWN :
00651 {
00652 Event Evt;
00653 Evt.Type = Event::MouseButtonPressed;
00654 Evt.Mouse.Buttons = Mouse::Right;
00655 Evt.Mouse.X = LOWORD(LParam);
00656 Evt.Mouse.Y = HIWORD(LParam);
00657 SendEvent(Evt);
00658 break;
00659 }
00660
00661
00662 case WM_RBUTTONUP :
00663 {
00664 Event Evt;
00665 Evt.Type = Event::MouseButtonReleased;
00666 Evt.Mouse.Buttons = Mouse::Right;
00667 Evt.Mouse.X = LOWORD(LParam);
00668 Evt.Mouse.Y = HIWORD(LParam);
00669 SendEvent(Evt);
00670 break;
00671 }
00672
00673
00674 case WM_MBUTTONDOWN :
00675 {
00676 Event Evt;
00677 Evt.Type = Event::MouseButtonPressed;
00678 Evt.Mouse.Buttons = Mouse::Middle;
00679 Evt.Mouse.X = LOWORD(LParam);
00680 Evt.Mouse.Y = HIWORD(LParam);
00681 SendEvent(Evt);
00682 break;
00683 }
00684
00685
00686 case WM_MBUTTONUP :
00687 {
00688 Event Evt;
00689 Evt.Type = Event::MouseButtonReleased;
00690 Evt.Mouse.Buttons = Mouse::Middle;
00691 Evt.Mouse.X = LOWORD(LParam);
00692 Evt.Mouse.Y = HIWORD(LParam);
00693 SendEvent(Evt);
00694 break;
00695 }
00696
00697
00698 case WM_MOUSEMOVE :
00699 {
00700 Event Evt;
00701 Evt.Type = Event::MouseMove;
00702 Evt.Mouse.Buttons = 0;
00703 if (GetAsyncKeyState(VK_LBUTTON)) Evt.Mouse.Buttons |= Mouse::Left;
00704 if (GetAsyncKeyState(VK_RBUTTON)) Evt.Mouse.Buttons |= Mouse::Right;
00705 if (GetAsyncKeyState(VK_MBUTTON)) Evt.Mouse.Buttons |= Mouse::Middle;
00706 Evt.Mouse.X = LOWORD(LParam);
00707 Evt.Mouse.Y = HIWORD(LParam);
00708 SendEvent(Evt);
00709 break;
00710 }
00711
00712
00713 case MM_JOY1MOVE :
00714 case MM_JOY2MOVE :
00715 {
00716 Event Evt;
00717 Evt.Type = Event::JoystickMove;
00718 Evt.Joystick.JoystickId = Message == MM_JOY1MOVE ? 0 : 1;
00719
00720 JOYINFO JoyState;
00721 joyGetPos(Message == MM_JOY1MOVE ? JOYSTICKID1 : JOYSTICKID2, &JoyState);
00722
00723 JoyCaps Caps = myJoystickCaps[Evt.Joystick.JoystickId];
00724 Evt.Joystick.X = (LOWORD(LParam) - Caps.CenterX) * 200 / Caps.RangeX;
00725 Evt.Joystick.Y = (HIWORD(LParam) - Caps.CenterY) * 200 / Caps.RangeY;
00726 Evt.Joystick.Z = (JoyState.wZpos - Caps.CenterZ) * 200 / Caps.RangeZ;
00727
00728 SendEvent(Evt);
00729 break;
00730 }
00731
00732
00733 case MM_JOY1ZMOVE :
00734 case MM_JOY2ZMOVE :
00735 {
00736 Event Evt;
00737 Evt.Type = Event::JoystickMove;
00738 Evt.Joystick.JoystickId = Message == MM_JOY1ZMOVE ? 0 : 1;
00739
00740 JOYINFO JoyState;
00741 joyGetPos(Message == MM_JOY1MOVE ? JOYSTICKID1 : JOYSTICKID2, &JoyState);
00742
00743 JoyCaps Caps = myJoystickCaps[Evt.Joystick.JoystickId];
00744 Evt.Joystick.X = (JoyState.wXpos - Caps.CenterX) * 200 / Caps.RangeX;
00745 Evt.Joystick.Y = (JoyState.wYpos - Caps.CenterY) * 200 / Caps.RangeY;
00746 Evt.Joystick.Z = (LOWORD(LParam) - Caps.CenterZ) * 200 / Caps.RangeZ;
00747
00748 SendEvent(Evt);
00749 break;
00750 }
00751
00752
00753 case MM_JOY1BUTTONDOWN :
00754 case MM_JOY2BUTTONDOWN :
00755 {
00756 Event Evt;
00757 Evt.Type = Event::JoystickButtonPressed;
00758 Evt.Joystick.JoystickId = Message == MM_JOY1BUTTONDOWN ? 0 : 1;
00759
00760 JOYINFO JoyState;
00761 joyGetPos(Message == MM_JOY1MOVE ? JOYSTICKID1 : JOYSTICKID2, &JoyState);
00762
00763 JoyCaps Caps = myJoystickCaps[Evt.Joystick.JoystickId];
00764 Evt.Joystick.X = (LOWORD(LParam) - Caps.CenterX) * 200 / Caps.RangeX;
00765 Evt.Joystick.Y = (HIWORD(LParam) - Caps.CenterY) * 200 / Caps.RangeY;
00766 Evt.Joystick.Z = (JoyState.wZpos - Caps.CenterZ) * 200 / Caps.RangeZ;
00767
00768 if ((WParam & JOY_BUTTON1) && (WParam & JOY_BUTTON1CHG)) Evt.Joystick.Button = 0;
00769 else if ((WParam & JOY_BUTTON2) && (WParam & JOY_BUTTON2CHG)) Evt.Joystick.Button = 1;
00770 else if ((WParam & JOY_BUTTON3) && (WParam & JOY_BUTTON3CHG)) Evt.Joystick.Button = 2;
00771 else if ((WParam & JOY_BUTTON4) && (WParam & JOY_BUTTON4CHG)) Evt.Joystick.Button = 3;
00772
00773 SendEvent(Evt);
00774 break;
00775 }
00776
00777
00778 case MM_JOY1BUTTONUP :
00779 case MM_JOY2BUTTONUP :
00780 {
00781 Event Evt;
00782 Evt.Type = Event::JoystickButtonReleased;
00783 Evt.Joystick.JoystickId = Message == MM_JOY1BUTTONUP ? 0 : 1;
00784
00785 JOYINFO JoyState;
00786 joyGetPos(Message == MM_JOY1MOVE ? JOYSTICKID1 : JOYSTICKID2, &JoyState);
00787
00788 JoyCaps Caps = myJoystickCaps[Evt.Joystick.JoystickId];
00789 Evt.Joystick.X = (LOWORD(LParam) - Caps.CenterX) * 200 / Caps.RangeX;
00790 Evt.Joystick.Y = (HIWORD(LParam) - Caps.CenterY) * 200 / Caps.RangeY;
00791 Evt.Joystick.Z = (JoyState.wZpos - Caps.CenterZ) * 200 / Caps.RangeZ;
00792
00793 if (!(WParam & JOY_BUTTON1) && (WParam & JOY_BUTTON1CHG)) Evt.Joystick.Button = 0;
00794 else if (!(WParam & JOY_BUTTON2) && (WParam & JOY_BUTTON2CHG)) Evt.Joystick.Button = 1;
00795 else if (!(WParam & JOY_BUTTON3) && (WParam & JOY_BUTTON3CHG)) Evt.Joystick.Button = 2;
00796 else if (!(WParam & JOY_BUTTON4) && (WParam & JOY_BUTTON4CHG)) Evt.Joystick.Button = 3;
00797
00798 SendEvent(Evt);
00799 break;
00800 }
00801 }
00802 }
00803
00804
00808 void WindowImplWin32::SetupJoysticks()
00809 {
00810
00811 MMRESULT Error;
00812 JOYINFOEX JoyInfo;
00813 unsigned int Count = 0;
00814 while ((Count < 2) && (Error = joyGetPosEx(JOYSTICKID1 + Count, &JoyInfo)) != JOYERR_PARMS)
00815 {
00816
00817 if (Error == JOYERR_NOERROR)
00818 {
00819
00820 joySetCapture(myHandle, JOYSTICKID1 + Count, 10, TRUE);
00821
00822
00823 JOYCAPS WinCaps;
00824 joyGetDevCaps(JOYSTICKID1 + Count, &WinCaps, sizeof(WinCaps));
00825 myJoystickCaps[Count].CenterX = (WinCaps.wXmax + WinCaps.wXmin) / 2;
00826 myJoystickCaps[Count].CenterY = (WinCaps.wYmax + WinCaps.wYmin) / 2;
00827 myJoystickCaps[Count].CenterZ = (WinCaps.wZmax + WinCaps.wZmin) / 2;
00828 myJoystickCaps[Count].RangeX = WinCaps.wXmax - WinCaps.wXmin;
00829 myJoystickCaps[Count].RangeY = WinCaps.wYmax - WinCaps.wYmin;
00830 myJoystickCaps[Count].RangeZ = WinCaps.wZmax - WinCaps.wZmin;
00831 }
00832
00833
00834 ++Count;
00835 }
00836 }
00837
00838
00842 Key::Code WindowImplWin32::VirtualKeyCodeToSF(WPARAM VirtualKey)
00843 {
00844 switch (VirtualKey)
00845 {
00846 case VK_ESCAPE : return Key::Escape;
00847 case VK_SPACE : return Key::Space;
00848 case VK_RETURN : return Key::Return;
00849 case VK_BACK : return Key::Back;
00850 case VK_TAB : return Key::Tab;
00851 case VK_PRIOR : return Key::PageUp;
00852 case VK_NEXT : return Key::PageDown;
00853 case VK_END : return Key::End;
00854 case VK_HOME : return Key::Home;
00855 case VK_INSERT : return Key::Insert;
00856 case VK_DELETE : return Key::Delete;
00857 case VK_ADD : return Key::Add;
00858 case VK_SUBTRACT : return Key::Subtract;
00859 case VK_MULTIPLY : return Key::Multiply;
00860 case VK_DIVIDE : return Key::Divide;
00861 case VK_PAUSE : return Key::Pause;
00862 case VK_F1 : return Key::F1;
00863 case VK_F2 : return Key::F2;
00864 case VK_F3 : return Key::F3;
00865 case VK_F4 : return Key::F4;
00866 case VK_F5 : return Key::F5;
00867 case VK_F6 : return Key::F6;
00868 case VK_F7 : return Key::F7;
00869 case VK_F8 : return Key::F8;
00870 case VK_F9 : return Key::F9;
00871 case VK_F10 : return Key::F10;
00872 case VK_F11 : return Key::F11;
00873 case VK_F12 : return Key::F12;
00874 case VK_F13 : return Key::F13;
00875 case VK_F14 : return Key::F14;
00876 case VK_F15 : return Key::F15;
00877 case VK_LEFT : return Key::Left;
00878 case VK_RIGHT : return Key::Right;
00879 case VK_UP : return Key::Up;
00880 case VK_DOWN : return Key::Down;
00881 case VK_NUMPAD0 : return Key::Numpad0;
00882 case VK_NUMPAD1 : return Key::Numpad1;
00883 case VK_NUMPAD2 : return Key::Numpad2;
00884 case VK_NUMPAD3 : return Key::Numpad3;
00885 case VK_NUMPAD4 : return Key::Numpad4;
00886 case VK_NUMPAD5 : return Key::Numpad5;
00887 case VK_NUMPAD6 : return Key::Numpad6;
00888 case VK_NUMPAD7 : return Key::Numpad7;
00889 case VK_NUMPAD8 : return Key::Numpad8;
00890 case VK_NUMPAD9 : return Key::Numpad9;
00891 case 'A' : return Key::A;
00892 case 'Z' : return Key::Z;
00893 case 'E' : return Key::E;
00894 case 'R' : return Key::R;
00895 case 'T' : return Key::T;
00896 case 'Y' : return Key::Y;
00897 case 'U' : return Key::U;
00898 case 'I' : return Key::I;
00899 case 'O' : return Key::O;
00900 case 'P' : return Key::P;
00901 case 'Q' : return Key::Q;
00902 case 'S' : return Key::S;
00903 case 'D' : return Key::D;
00904 case 'F' : return Key::F;
00905 case 'G' : return Key::G;
00906 case 'H' : return Key::H;
00907 case 'J' : return Key::J;
00908 case 'K' : return Key::K;
00909 case 'L' : return Key::L;
00910 case 'M' : return Key::M;
00911 case 'W' : return Key::W;
00912 case 'X' : return Key::X;
00913 case 'C' : return Key::C;
00914 case 'V' : return Key::V;
00915 case 'B' : return Key::B;
00916 case 'N' : return Key::N;
00917 case '0' : return Key::Num0;
00918 case '1' : return Key::Num1;
00919 case '2' : return Key::Num2;
00920 case '3' : return Key::Num3;
00921 case '4' : return Key::Num4;
00922 case '5' : return Key::Num5;
00923 case '6' : return Key::Num6;
00924 case '7' : return Key::Num7;
00925 case '8' : return Key::Num8;
00926 case '9' : return Key::Num9;
00927 }
00928
00929 return Key::Code(0);
00930 }
00931
00932
00936 LRESULT CALLBACK WindowImplWin32::GlobalOnEvent(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam)
00937 {
00938
00939 if (Message == WM_CREATE)
00940 {
00941
00942 long This = reinterpret_cast<long>(reinterpret_cast<CREATESTRUCT*>(LParam)->lpCreateParams);
00943
00944
00945 SetWindowLongPtr(Handle, GWLP_USERDATA, This);
00946 }
00947
00948
00949 WindowImplWin32* Window = reinterpret_cast<WindowImplWin32*>(GetWindowLongPtr(Handle, GWLP_USERDATA));
00950
00951
00952 if (Window)
00953 {
00954 Window->ProcessEvent(Message, WParam, LParam);
00955
00956 if (Window->myCallback)
00957 return CallWindowProc(reinterpret_cast<WNDPROC>(Window->myCallback), Handle, Message, WParam, LParam);
00958 }
00959
00960 return DefWindowProc(Handle, Message, WParam, LParam);
00961 }
00962
00963 }
00964
00965 }