From: <mk...@us...> - 2003-01-04 23:49:54
|
Update of /cvsroot/csp/APPLICATIONS/CSPFlightSim/Source In directory sc8-pr-cvs1:/tmp/cvs-serv16793/Source Added Files: Tag: simdata HID.cpp Log Message: initial version of a new virtual human interface device --- NEW FILE: HID.cpp --- // Combat Simulator Project - FlightSim Demo // Copyright (C) 2002 The Combat Simulator Project // http://csp.sourceforge.net // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** * @file HID.cpp * **/ #include "HID.h" ///////////////////////////////////////////////////////////////////////////// // class EventMapping int EventMapping::getKeyID(SDL_keysym &key, EDir dir, int mode) const { int press = (dir == PRESS) ? (1 << 28) : 0; return (key.sym & 0xFFF) + ((key.mod & 0xFFF) << 12) + ((mode & 0x00F) << 24) + press; } int EventMapping::getJoystickButtonID(int device, int button, EDir dir, int mode) const { int press = (dir == PRESS) ? (1 << 28) : 0; return (device & 0xFFF) + ((button & 0xFFF) << 12) + ((mode & 0x00F) << 24) + press; } int EventMapping::getMouseButtonID(int device, int button, EDir dir, int kmod, int mode) const { int press = (dir == PRESS) ? (1 << 28) : 0; return (device & 0xF) + ((button & 0xFF) << 4) + ((kmod & 0xFFF) << 12) + ((mode & 0xF) << 24) + press; } int EventMapping::getMouseMotionID(int device, int state, int kmod, int mode) const { return (device & 0xF) + ((state & 0xFF) << 4) + ((kmod & 0xFFF) << 12) + ((mode & 0xF) << 24); } EventMapping::Script const *EventMapping::getKeyScript(SDL_keysym &key, EDir dir, int mode) const { int id = getKeyID(key, dir, mode); EventScript kScript = m_KeyMap.find(id); if (kScript == m_KeyMap.end()) return NULL; return &(kScript->second); } EventMapping::Script const *EventMapping::getJoystickButtonScript(int device, int button, EDir dir, int mode) const { int id = getJoystickButtonID(device, button, dir, mode); EventScript bScript = m_JoystickButtonMap.find(id); if (bScript == m_JoystickButtonMap.end()) return NULL; return &(bScript->second); } EventMapping::Axis const *EventMapping::getJoystickAxis(int device, int axis) const { return &(m_JoystickAxisMap[device & 3][axis & 7]); } void EventMapping::addJoystickAxisMap(int device, int axis, Axis const &a) { assert(device >= 0 && device < 4); assert(axis >= 0 && axis < 8); m_JoystickAxisMap[device][axis] = a; } void EventMapping::addKeyMap(SDL_keysym &key, EDir dir, int mode, Script const &s) { int id = getKeyID(key, dir, mode); m_KeyMap[id] = s; } void EventMapping::addJoystickButtonMap(int device, int button, EDir dir, int mode, Script const &s) { int id = getJoystickButtonID(device, button, dir, mode); m_JoystickButtonMap[id] = s; } void EventMapping::addMouseMotionMap(int device, int state, int kmod, int mode, int map_to) { int id = getMouseMotionID(device, state, kmod, mode); m_MouseMotionMap[id] = map_to; } // convenience method for testing purposes only void EventMapping::addKeyMap(SDLKey vkey, SDLMod kmod, EDir dir, int mode, int action, double time) { SDL_keysym key; key.sym = vkey; key.mod = kmod; Script s; Action a; a.id = action; a.time = time; s.push_back(a); addKeyMap(key, dir, mode, s); } // convenience method for testing purposes only void EventMapping::addJoystickButtonMap(int device, int button, EDir dir, int mode, int action, double time) { Script s; Action a; a.id = action; a.time = time; s.push_back(a); addJoystickButtonMap(device, button, dir, mode, s); } EventMapping::Script const *EventMapping::getMouseButtonScript(int device, int button, EDir dir, int kmod, int mode) const { int id = getMouseButtonID(device, button, dir, kmod, mode); EventScript mScript = m_MouseButtonMap.find(id); if (mScript == m_MouseButtonMap.end()) return NULL; return &(mScript->second); } int EventMapping::getMouseMotion(int device, int state, int kmod, int mode) const { int id = getMouseMotionID(device, state, kmod, mode); motion_map::const_iterator map = m_MouseMotionMap.find(id); if (map == m_MouseMotionMap.end()) return -1; return map->second; } ///////////////////////////////////////////////////////////////////////////// // class VirtualHID: public HID VirtualHID::VirtualHID() { m_Map = 0; m_VirtualMode = 0; m_ActiveScript = 0; m_LastMouseMoveID = -1; } VirtualHID::~VirtualHID() {} void VirtualHID::setMapping(EventMapping const & map) { m_Map = ↦ } void VirtualHID::bindObject(SimObject *object) { m_Object = object; } bool VirtualHID::OnKeyDown(SDL_keysym &key) { if (!m_Object || !m_Map) return false; EventMapping::Script const *s = m_Map->getKeyScript(key, EventMapping::PRESS, 0); if (s == NULL) return false; setScript(s); return true; } bool VirtualHID::OnKeyUp(SDL_keysym &key) { if (!m_Object || !m_Map) return false; EventMapping::Script const *s = m_Map->getKeyScript(key, EventMapping::RELEASE, 0); if (s == NULL) return false; setScript(s); return true; } bool VirtualHID::OnJoystickButtonDown(int joynum, int butnum) { if (!m_Object || !m_Map) return false; EventMapping::Script const *s = m_Map->getJoystickButtonScript(joynum, butnum, EventMapping::PRESS, m_VirtualMode); if (s == NULL) return false; setScript(s); return true; } bool VirtualHID::OnJoystickButtonUp(int joynum, int butnum) { if (!m_Object || !m_Map) return false; EventMapping::Script const *s = m_Map->getJoystickButtonScript(joynum, butnum, EventMapping::RELEASE, m_VirtualMode); if (s == NULL) return false; setScript(s); return true; } void VirtualHID::OnJoystickAxisMotion(int joynum, int axis, int val) { if (!m_Object || !m_Map) return; EventMapping::Axis const *Axis = m_Map->getJoystickAxis(joynum, axis); int id = Axis->id; if (id < 0 || id > m_Axes.size()) return; AxisAdapter adapter = m_Axes[id]; if (adapter) adapter(m_Object, val); } void VirtualHID::setVirtualMode(int mode) { m_VirtualMode = mode; } bool VirtualHID::OnMouseMove(SDL_MouseMotionEvent const &event) { if (!m_Object || !m_Map) return false; int kmod = SDL_GetModState(); int id = m_Map->getMouseMotion(event.which, event.state, kmod, m_VirtualMode); if (id != m_LastMouseMoveID) { m_LastMouseMoveID = id; m_LastMouseMoveAdapter = NULL; MotionMap::const_iterator map = m_Motions.find(id); if (map == m_Motions.end()) return false; m_LastMouseMoveAdapter = map->second; } MotionAdapter adapter = m_LastMouseMoveAdapter; if (!adapter) return false; adapter(m_Object, event.x, event.y, event.xrel, event.yrel); return true; } bool VirtualHID::OnMouseButtonDown(SDL_MouseButtonEvent const &event) { if (!m_Object || !m_Map) return false; int kmod = SDL_GetModState(); EventMapping::Script const *s = m_Map->getMouseButtonScript(event.which, event.button, EventMapping::PRESS, kmod, m_VirtualMode); if (s == NULL) return false; setScript(s, event.x, event.y); return true; } bool VirtualHID::OnMouseButtonUp(SDL_MouseButtonEvent const &event) { if (!m_Object || !m_Map) return false; int kmod = SDL_GetModState(); EventMapping::Script const *s = m_Map->getMouseButtonScript(event.which, event.button, EventMapping::RELEASE, kmod, m_VirtualMode); if (s == NULL) return false; setScript(s, event.x, event.y); return true; } void VirtualHID::OnUpdate(double dt) { if (!m_ActiveScript) return; m_ScriptTime += dt; while (m_ScriptAction->time <= m_ScriptTime) { int id = m_ScriptAction->id; if (id < -15) { // nop } else if (id < 0) { setVirtualMode(-id); } else { // FIXME: don't use [] ActionAdapter adapter = m_Actions[id]; if (adapter) adapter(m_Object, m_MouseEventX, m_MouseEventY); } if (++m_ScriptAction == m_ActiveScript->end()) { m_ActiveScript = 0; break; } } } void VirtualHID::setScript(EventMapping::Script const *s, int x, int y) { m_MouseEventX = x; m_MouseEventY = y; m_ActiveScript = s; m_ScriptAction = s->begin(); m_ScriptTime = 0.0; OnUpdate(0.0); } //////////////////////////////////////////////////////////////////// // class AircraftInterface: public VirtualHID AircraftInterface::AircraftInterface(): VirtualHID() { // temparory for testing... bindObject(new AircraftObject()); bindEvents(); } void AircraftInterface::bindEvents() { m_Actions.clear(); m_Axes.clear(); m_Axes.resize(16, NULL); BIND_ACTION(AircraftObject, RETRACT_GEAR, RetractGear); BIND_ACTION(AircraftObject, EXTEND_GEAR, ExtendGear); BIND_ACTION(AircraftObject, TOGGLE_GEAR, ToggleGear); BIND_MOTION(AircraftObject, PAN_VIEW, PanView); BIND_AXIS(AircraftObject, THROTTLE, Throttle); } |