// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . ///////////// // INCLUDE // ///////////// #include "stdpch.h" // Client #include "actions.h" #include "input.h" #include "interface_v3/interface_manager.h" #include "interface_v3/input_handler_manager.h" #include "client_cfg.h" #include "time_client.h" // 3D #include "nel/3d/u_driver.h" // Misc #include "nel/misc/mouse_device.h" #include "nel/misc/mouse_smoother.h" #include "nel/misc/system_utils.h" // Game Share /////////// // USING // /////////// using namespace NL3D; using namespace NLMISC; //////////// // EXTERN // //////////// extern UDriver *Driver; extern UMaterial GenericMat; extern CActionsManager Actions; // Actions Manager. //////////// // GLOBAL // //////////// IMouseDevice *MouseDevice = NULL; bool MouseHardware = false; bool MouseFreeLook = false; float MouseCursorSpeed = 1.f; uint MouseCursorAcceleration = 0; bool InitMouseFirstTime = true; bool SetMousePosFirstTime = true; // mask for mouse buttons that are known to be down uint DownMouseButtons = 0; ////////////// // FUNCTION // ////////////// // ********************************************************************************* uint GetMouseButtonsState() { return DownMouseButtons; } // ********************************************************************************* // Initialize the mouse bool InitMouseWithCursor (bool hardware) { Driver->showCursor(false); // First init ? if (MouseDevice) { // No.. change soft to hard or hard to soft ? if (hardware ^ MouseHardware) { // Ok, reinit the mouse Driver->enableLowLevelMouse (false, false); MouseDevice = NULL; MouseHardware = false; } } // Get the new mouse state MouseHardware = hardware; // Reinit ? if (MouseDevice == NULL) { if (!ClientCfg.DisableDirectInput) { // mouse capture not taken in account for hardware mouse MouseDevice = Driver->enableLowLevelMouse(true, hardware); if (!MouseDevice) return false; } // Update mouse information UpdateMouse (); if (InitMouseFirstTime) { InitMouseFirstTime = false; } else { if (!MouseFreeLook) { // Get the current mouse position if (hardware) { Driver->showCursor(true); CViewPointer *pointer = CWidgetManager::getInstance()->getPointer(); if (pointer) { float x = (float)pointer->getX()/(float)Driver->getWindowWidth(); float y = (float)pointer->getY()/(float)Driver->getWindowHeight(); if (SetMousePosFirstTime) { SetMousePosFirstTime = false; } else { Driver->setMousePos(x, y); nlwarning("mouse pos %f,%f", x, y); } } } else { CInterfaceManager *pIm = CInterfaceManager::getInstance(); CViewPointer *vp = CWidgetManager::getInstance()->getPointer(); Driver->showCursor(false); SetMousePosFirstTime = false; if (vp) { float x = (float) vp->getX(); float y = (float) vp->getY(); // First, hide the hardware mouse if (MouseDevice) { MouseDevice->setMousePos(x, y); } else { uint width = Driver->getWindowWidth(); uint height = Driver->getWindowHeight(); if (width != 0 && height != 0) { Driver->setMousePos(x / width, y / height); } } } } } } } return true; } // ********************************************************************************* // Is mouse cursor hardware ? bool IsMouseCursorHardware () { return MouseHardware; } // ********************************************************************************* // Set the mouse mode. Call this method once per frame to update window size void UpdateMouse () { // Freelook ? if (MouseFreeLook) { // Raw mode if (MouseDevice) { MouseDevice->setMessagesMode(IMouseDevice::RawMode); MouseDevice->setMouseAcceleration(ClientCfg.FreeLookAcceleration); } else { // no mouse device implementation on X11 and Cocoa, emulate raw mode Driver->emulateMouseRawMode(true); } } else { // Set the mouse properties if (MouseDevice) { // Get the driver size uint32 width, height; Driver->getWindowSize(width, height); MouseDevice->setMessagesMode(IMouseDevice::NormalMode); MouseDevice->setMouseMode(IMouseDevice::XAxis, IMouseDevice::Clamped); MouseDevice->setMouseMode(IMouseDevice::YAxis, IMouseDevice::Clamped); CRect window (0, 0, width, height); MouseDevice->setMouseFrame(window); MouseDevice->setFactors(1.f/std::max((float)width, 1.0f), 1.f/std::max((float)height, 1.0f)); MouseDevice->setMouseSpeed(MouseCursorSpeed); MouseDevice->setMouseAcceleration(MouseCursorAcceleration); } else { // no mouse device implementation on X11 and Cocoa, emulate raw mode Driver->emulateMouseRawMode(false); } } if (!Driver->isSystemCursorCaptured()) { DownMouseButtons = 0; } } // ********************************************************************************* // Use this method to toggle the mouse (freelook <- cursor) void SetMouseFreeLook () { if (!MouseFreeLook) { MouseFreeLook = true; if (MouseHardware) { Driver->showCursor(false); } else { CInterfaceManager *im = CInterfaceManager::getInstance(); if (im) { CViewPointer *pointer = CWidgetManager::getInstance()->getPointer(); if (pointer) pointer->show (false); } } UpdateMouse (); } } // ********************************************************************************* bool IsMouseFreeLook() { return MouseFreeLook; } // ********************************************************************************* // Use this method to toggle the mouse (freelook -> cursor) void SetMouseCursor (bool updatePos) { if (MouseFreeLook) { // Get the last cursor float x = 0.5f, y = 0.5f; // Window size uint width = Driver->getWindowWidth(); uint height = Driver->getWindowHeight(); // Update the interface pointer CInterfaceManager *instance = CInterfaceManager::getInstance(); if (instance) { // Get the cursor instance CViewPointer *cursor = CWidgetManager::getInstance()->getPointer(); if (cursor) { sint32 ix, iy; cursor->getPointerPos (ix, iy); x = (float)ix / (float)width; y = (float)iy / (float)height; } } MouseFreeLook = false; UpdateMouse (); // Integer coordinates sint ix = (sint)(x*(float)width+0.5f); sint iy = (sint)(y*(float)height+0.5f); if (updatePos) { if (MouseDevice) { MouseDevice->setMousePos((float)ix, (float)iy); } else { Driver->setMousePos(x, y); } if (MouseHardware) { Driver->setMousePos(x, y); } } // Update the interface pointer if (instance) { // Get the cursor instance CViewPointer *cursor = CWidgetManager::getInstance()->getPointer(); if (cursor) { cursor->setPointerPos(ix, iy); cursor->setPointerDispPos(ix, iy); } } CInputHandlerManager *IHM = CInputHandlerManager::getInstance (); if (IHM) { IHM->resetPos (ix, iy); } // Show the cursor if (MouseHardware) { Driver->showCursor(true); } else { CInterfaceManager *im = CInterfaceManager::getInstance(); if (im) { CViewPointer *pointer = CWidgetManager::getInstance()->getPointer(); if (pointer) pointer->show (true); } } } } // ********************************************************************************* // Use this method to set the cursor speed void SetMouseSpeed (float speed) { MouseCursorSpeed = speed; UpdateMouse (); } // ********************************************************************************* // Use this method to set the cursor acceleration void SetMouseAcceleration (uint accel) { MouseCursorAcceleration = accel; UpdateMouse (); } // ********************************************************************************* void HandleSystemCursorCapture(const CEvent &event) { if (event == EventMouseDownId) { CEventMouseDown &em = (CEventMouseDown &) event; DownMouseButtons |= em.Button & (leftButton | middleButton | rightButton); Driver->setCapture(true); } if (event == EventMouseUpId) { // if all buttons up CEventMouseDown &em = (CEventMouseDown &) event; DownMouseButtons &= ~(em.Button & (leftButton | middleButton | rightButton)); if (DownMouseButtons == 0) { Driver->setCapture(false); } } // if focus was lost then says that all buttons are up from this app viewpoint if (event == EventSetFocusId) { DownMouseButtons = 0; } } sint CNiceInputAuto::_Count = 0; CNiceInputAuto::CNiceInputAuto() { if (_Count == 0) { Driver->enableLowLevelMouse(false, false); // but ignore direct input (win 32 msg only) Driver->setCursor("curs_default.tga", CRGBA::White, 0, 0x15, 0x18); Driver->showCursor(true); // keep cursor visible in windowed mode MouseDevice = NULL; Driver->enableLowLevelKeyboard (false); } ++ _Count; } CNiceInputAuto::~CNiceInputAuto() { -- _Count; nlassert(_Count >= 0); if (_Count == 0) { InitMouseWithCursor (ClientCfg.HardwareCursor); Driver->enableLowLevelKeyboard (!ClientCfg.DisableDirectInputKeyboard); // the return value has already been tested at startup } }