1 /*
2  * This file is part of the Colobot: Gold Edition source code
3  * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
4  * http://epsitec.ch; http://colobot.info; http://github.com/colobot
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see http://gnu.org/licenses
18  */
19 
20 /**
21  * \file app/input.h
22  * \brief CInput class
23  */
24 
25 #pragma once
26 
27 #include "common/key.h"
28 #include "common/singleton.h"
29 
30 #include "math/intpoint.h"
31 #include "math/point.h"
32 #include "math/vector.h"
33 
34 #include <map>
35 
36 struct Event;
37 
38 /**
39  * \struct InputBinding
40  * \brief Binding for input slot
41  */
42 struct InputBinding
43 {
44     //! Primary and secondary bindings
45     //! Can be regular key, virtual key or virtual joystick button
46     unsigned int primary, secondary;
47 
48     InputBinding(unsigned int p = KEY_INVALID, unsigned int s = KEY_INVALID)
primaryInputBinding49     : primary(p), secondary(s) {}
50 };
51 
52 /**
53  * \struct JoyAxisBinding
54  * \brief Binding for joystick axis
55  */
56 struct JoyAxisBinding
57 {
58     //! Axis index or AXIS_INVALID
59     int axis = 0;
60     //! True to invert axis value
61     bool invert = false;
62 };
63 
64 //! Invalid value for axis binding (no axis assigned)
65 const int AXIS_INVALID = -1;
66 
67 /**
68  * \class CInput
69  * \brief Management of mouse, keyboard and joystick
70  */
71 class CInput : public CSingleton<CInput>
72 {
73 public:
74     //! Constructor
75     CInput();
76 
77     //! Process an incoming event, also sets .kmodState, .mousePos, .mouseButtonsState and .key.slot
78     void EventProcess(Event &event);
79 
80     //! Called by CApplication on SDL MOUSE_MOTION event
81     void MouseMove(Math::IntPoint pos);
82 
83 
84     //! Returns whether the key is pressed
85     bool        GetKeyState(InputSlot key) const;
86 
87     //! Returns whether the mouse button is pressed
88     bool        GetMouseButtonState(int index) const;
89 
90     //! Resets tracked key states and modifiers
91     void        ResetKeyStates();
92 
93     //! Returns the position of mouse cursor (in interface coords)
94     Math::Point GetMousePos() const;
95 
96 
97     //! Sets the default input bindings (keys and joystick axes)
98     void        SetDefaultInputBindings();
99 
100     //! Management of input bindings
101     //@{
102     void        SetInputBinding(InputSlot slot, InputBinding binding);
103     const InputBinding& GetInputBinding(InputSlot slot);
104     //@}
105 
106     //! Management of joystick axis bindings
107     //@{
108     void        SetJoyAxisBinding(JoyAxisSlot slot, JoyAxisBinding binding);
109     const JoyAxisBinding& GetJoyAxisBinding(JoyAxisSlot slot);
110     //@}
111 
112     //! Management of joystick deadzone
113     //@{
114     void        SetJoystickDeadzone(float zone);
115     float       GetJoystickDeadzone();
116     //@}
117 
118     //! Get binding slot for given key
119     InputSlot   FindBinding(unsigned int key);
120 
121     //! Saving/loading key bindings to colobot.ini
122     //@{
123     void        SaveKeyBindings();
124     void        LoadKeyBindings();
125     //@}
126 
127     //! Seeks a InputSlot by id. Returns INPUT_SLOT_MAX if not found
128     InputSlot   SearchKeyById(std::string id);
129 
130     //! Returns string describing keys to be pressed
131     //@{
132     std::string GetKeysString(InputBinding binding);
133     std::string GetKeysString(InputSlot slot);
134     //@}
135 
136 private:
137     //! Current state of keys
138     bool            m_keyPresses[INPUT_SLOT_MAX];
139 
140 
141     //! Current position of mouse cursor
142     Math::Point     m_mousePos;
143     //! Current state of mouse buttons (bitmask of MouseButton enum values)
144     unsigned int    m_mouseButtonsState;
145 
146 
147     //! Motion vector set by keyboard or joystick buttons
148     Math::Vector    m_keyMotion;
149     //! Motion vector set by joystick axes
150     Math::Vector    m_joyMotion;
151     //! Camera motion vector set by joystick axes
152     Math::Vector    m_joyMotionCam;
153 
154     //! Camera controls on the numpad
155     Math::Vector    m_cameraKeyMotion;
156 
157     //! Bindings for user inputs
158     InputBinding    m_inputBindings[INPUT_SLOT_MAX];
159     JoyAxisBinding  m_joyAxisBindings[JOY_AXIS_SLOT_MAX];
160     float           m_joystickDeadzone;
161 
162     std::map<InputSlot, std::string> m_keyTable;
163 };
164