Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TouchInput.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2013 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include "TouchInput.h"
21 
22 #include "graphics/Camera.h"
23 #include "graphics/GameView.h"
24 #include "lib/timer.h"
26 #include "ps/Game.h"
27 
28 // When emulation is enabled:
29 // Left-click to put finger 0 down.
30 // Then left-click-and-drag to move finger 0.
31 // Then left-click to put finger 0 up.
32 // Same with right-click for finger 1.
33 #define EMULATE_FINGERS_WITH_MOUSE 0
34 
35 extern int g_xres, g_yres;
36 
37 // NOTE: All this code is currently just a basic prototype for testing;
38 // it might need significant redesigning for proper usage.
39 
41  m_State(STATE_INACTIVE)
42 {
43  for (size_t i = 0; i < MAX_FINGERS; ++i)
44  m_Down[i] = false;
45 
46  for (size_t i = 0; i < MAX_MOUSE; ++i)
48 }
49 
51 {
52 }
53 
55 {
56 #if OS_ANDROID || EMULATE_FINGERS_WITH_MOUSE
57  return true;
58 #else
59  return false;
60 #endif
61 }
62 
63 void CTouchInput::OnFingerDown(int id, int x, int y)
64 {
65  debug_printf(L"finger down %d %d %d; state %d\n", id, x, y, m_State);
66  m_Down[id] = true;
67  m_Prev[id] = m_Pos[id] = CVector2D(x, y);
68 
69  if (m_State == STATE_INACTIVE && id == 0)
70  {
73  m_FirstTouchPos = CVector2D(x, y);
74  }
75  else if ((m_State == STATE_FIRST_TOUCH || m_State == STATE_PANNING) && id == 1)
76  {
78  }
79 }
80 
81 void CTouchInput::OnFingerUp(int id, int x, int y)
82 {
83  debug_printf(L"finger up %d %d %d; state %d\n", id, x, y, m_State);
84  m_Down[id] = false;
85  m_Pos[id] = CVector2D(x, y);
86 
87  if (m_State == STATE_FIRST_TOUCH && id == 0 && timer_Time() < m_FirstTouchTime + 0.5)
88  {
90 
91  SDL_Event_ ev;
93  ev.ev.button.x = m_Pos[0].X;
94  ev.ev.button.y = m_Pos[0].Y;
95 
98  SDL_PushEvent(&ev.ev);
99 
102  SDL_PushEvent(&ev.ev);
103  }
104  else if (m_State == STATE_ZOOMING && id == 1)
105  {
107  }
108  else
109  {
111  }
112 }
113 
114 void CTouchInput::OnFingerMotion(int id, int x, int y)
115 {
116  debug_printf(L"finger motion %d %d %d; state %d\n", id, x, y, m_State);
117 
118  CVector2D pos(x, y);
119 
120  m_Prev[id] = m_Pos[id];
121  m_Pos[id] = pos;
122 
123  if (m_State == STATE_FIRST_TOUCH && id == 0)
124  {
125  if ((pos - m_FirstTouchPos).Length() > 16)
126  {
128 
129  CCamera& camera = *(g_Game->GetView()->GetCamera());
132  }
133  }
134 
135  if (m_State == STATE_PANNING && id == 0)
136  {
137  CCamera& camera = *(g_Game->GetView()->GetCamera());
138  CVector3D origin, dir;
139  camera.BuildCameraRay(x, y, origin, dir);
140  dir *= m_PanDist / dir.Y;
141  camera.GetOrientation().Translate(m_PanFocus - dir - origin);
142  camera.UpdateFrustum();
143  }
144 
145  if (m_State == STATE_ZOOMING && id == 1)
146  {
147  float oldDist = (m_Prev[id] - m_Pos[1 - id]).Length();
148  float newDist = (m_Pos[id] - m_Pos[1 - id]).Length();
149  float zoomDist = (newDist - oldDist) * -0.005f * m_PanDist;
150 
151  CCamera& camera = *(g_Game->GetView()->GetCamera());
152  CVector3D origin, dir;
153  camera.BuildCameraRay(m_Pos[0].X, m_Pos[0].Y, origin, dir);
154  dir *= zoomDist;
155  camera.GetOrientation().Translate(dir);
156  camera.UpdateFrustum();
157 
158  m_PanFocus = camera.GetWorldCoordinates(m_Pos[0].X, m_Pos[0].Y, true);
160  }
161 }
162 
164 {
165  double t = timer_Time();
166  if (m_State == STATE_FIRST_TOUCH && t > m_FirstTouchTime + 1.0)
167  {
169 
170  SDL_Event_ ev;
172  ev.ev.button.x = m_Pos[0].X;
173  ev.ev.button.y = m_Pos[0].Y;
174 
176  ev.ev.button.state = SDL_PRESSED;
177  SDL_PushEvent(&ev.ev);
178 
181  SDL_PushEvent(&ev.ev);
182  }
183 }
184 
186 {
187  UNUSED2(ev); // may be unused depending on #ifs
188 
189  if (!IsEnabled())
190  return IN_PASS;
191 
192 #if EMULATE_FINGERS_WITH_MOUSE
193  switch(ev->ev.type)
194  {
195  case SDL_MOUSEBUTTONDOWN:
196  {
197  int button;
198  if (ev->ev.button.button == SDL_BUTTON_LEFT)
199  button = 0;
200  else if (ev->ev.button.button == SDL_BUTTON_RIGHT)
201  button = 1;
202  else
203  return IN_PASS;
204 
205  m_MouseEmulateDownPos[button] = CVector2D(ev->ev.button.x, ev->ev.button.y);
206  if (m_MouseEmulateState[button] == MOUSE_INACTIVE)
207  {
209  OnFingerDown(button, ev->ev.button.x, ev->ev.button.y);
210  }
211  else if (m_MouseEmulateState[button] == MOUSE_ACTIVE_UP)
212  {
214  }
215  return IN_HANDLED;
216  }
217 
218  case SDL_MOUSEBUTTONUP:
219  {
220  int button;
221  if (ev->ev.button.button == SDL_BUTTON_LEFT)
222  button = 0;
223  else if (ev->ev.button.button == SDL_BUTTON_RIGHT)
224  button = 1;
225  else
226  return IN_PASS;
227 
228  if (m_MouseEmulateState[button] == MOUSE_ACTIVATING)
229  {
231  }
232  else if (m_MouseEmulateState[button] == MOUSE_ACTIVE_DOWN)
233  {
234  float dist = (m_MouseEmulateDownPos[button] - CVector2D(ev->ev.button.x, ev->ev.button.y)).Length();
235  if (dist <= 2)
236  {
238  OnFingerUp(button, ev->ev.button.x, ev->ev.button.y);
239  }
240  else
241  {
243  }
244  }
245  return IN_HANDLED;
246  }
247 
248  case SDL_MOUSEMOTION:
249  {
250  for (size_t i = 0; i < MAX_MOUSE; ++i)
251  {
253  {
254  OnFingerMotion(i, ev->ev.motion.x, ev->ev.motion.y);
255  }
256  }
257  return IN_HANDLED;
258  }
259  }
260 #endif
261 
262 #if SDL_VERSION_ATLEAST(2, 0, 0)
263  switch(ev->ev.type)
264  {
265  case SDL_FINGERDOWN:
266  case SDL_FINGERUP:
267  case SDL_FINGERMOTION:
268  {
269  // Map finger events onto the mouse, for basic testing
270  debug_printf(L"finger %s tid=%lld fid=%lld x=%d y=%d dx=%d dy=%d p=%d\n",
271  ev->ev.type == SDL_FINGERDOWN ? "down" :
272  ev->ev.type == SDL_FINGERUP ? "up" :
273  ev->ev.type == SDL_FINGERMOTION ? "motion" : "?",
274  ev->ev.tfinger.touchId, ev->ev.tfinger.fingerId,
275  ev->ev.tfinger.x, ev->ev.tfinger.y, ev->ev.tfinger.dx, ev->ev.tfinger.dy, ev->ev.tfinger.pressure);
276 
277  if (ev->ev.type == SDL_FINGERDOWN)
278  OnFingerDown(ev->ev.tfinger.fingerId, g_xres * (ev->ev.tfinger.x/32767.0f), g_yres * (ev->ev.tfinger.y/32767.0f));
279  else if (ev->ev.type == SDL_FINGERUP)
280  OnFingerUp(ev->ev.tfinger.fingerId, g_xres * (ev->ev.tfinger.x/32767.0f), g_yres * (ev->ev.tfinger.y/32767.0f));
281  else if (ev->ev.type == SDL_FINGERMOTION)
282  OnFingerMotion(ev->ev.tfinger.fingerId, g_xres * (ev->ev.tfinger.x/32767.0f), g_yres * (ev->ev.tfinger.y/32767.0f));
283  return IN_HANDLED;
284  }
285  }
286 #endif
287 
288  return IN_PASS;
289 }
290 
292 
294 {
295  return g_TouchInput.HandleEvent(ev);
296 }
void Translate(float x, float y, float z)
Definition: Matrix3D.cpp:172
InReaction HandleEvent(const SDL_Event_ *ev)
Definition: TouchInput.cpp:185
Definition: Decompose.h:22
int m_MouseEmulateState[MAX_MOUSE]
Definition: TouchInput.h:61
bool IsEnabled()
Returns whether the touch input mode is enabled for this device.
Definition: TouchInput.cpp:54
float X
Definition: Vector2D.h:157
Definition: Decompose.h:22
CVector2D m_Prev[MAX_FINGERS]
Definition: TouchInput.h:68
static const size_t MAX_FINGERS
Definition: TouchInput.h:65
int g_xres
Definition: Config.cpp:58
bool m_Down[MAX_FINGERS]
Definition: TouchInput.h:66
Maps touch events (e.g.
Definition: TouchInput.h:29
InReaction touch_input_handler(const SDL_Event_ *ev)
Definition: TouchInput.cpp:293
CVector3D GetWorldCoordinates(int px, int py, bool aboveWater=false) const
Definition: Camera.cpp:204
static const size_t MAX_MOUSE
Definition: TouchInput.h:60
SDL_MouseMotionEvent motion
Definition: wsdl.h:307
void OnFingerDown(int id, int x, int y)
Definition: TouchInput.cpp:63
CVector2D m_FirstTouchPos
Definition: TouchInput.h:81
SDL_Event ev
Definition: libsdl.h:56
#define UNUSED2(param)
mark a function local variable or parameter as unused and avoid the corresponding compiler warning...
CMatrix3D & GetOrientation()
Definition: Camera.h:52
Uint8 type
Definition: wsdl.h:302
CTouchInput g_TouchInput
Definition: TouchInput.cpp:291
SDL_MouseButtonEvent button
Definition: wsdl.h:308
float Y
Definition: Vector3D.h:31
InReaction
Definition: input.h:34
Definition: input.h:40
int g_yres
Definition: Config.cpp:58
Definition: Camera.h:39
CCamera * GetCamera()
Definition: GameView.cpp:390
CGame * g_Game
Globally accessible pointer to the CGame object.
Definition: Game.cpp:56
void OnFingerUp(int id, int x, int y)
Definition: TouchInput.cpp:81
CVector2D m_Pos[MAX_FINGERS]
Definition: TouchInput.h:67
double m_FirstTouchTime
Definition: TouchInput.h:80
double timer_Time()
Definition: timer.cpp:98
float Y
Definition: Vector2D.h:157
void UpdateFrustum(const CBoundingBoxAligned &scissor=CBoundingBoxAligned(CVector3D(-1.0f,-1.0f,-1.0f), CVector3D(1.0f, 1.0f, 1.0f)))
Definition: Camera.cpp:83
CGameView * GetView()
Get the pointer to the game view object.
Definition: Game.h:128
CVector3D m_PanFocus
Definition: TouchInput.h:83
void BuildCameraRay(int px, int py, CVector3D &origin, CVector3D &dir) const
Definition: Camera.cpp:167
int SDL_PushEvent(SDL_Event *ev)
Definition: wsdl.cpp:1354
void Frame()
Should be called once per frame to perform updates.
Definition: TouchInput.cpp:163
void OnFingerMotion(int id, int x, int y)
Definition: TouchInput.cpp:114
CVector3D GetTranslation() const
Definition: Matrix3D.cpp:195
static float Length(const SVec3 v)
Definition: mikktspace.cpp:112
CVector2D m_MouseEmulateDownPos[MAX_MOUSE]
Definition: TouchInput.h:62
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
Definition: debug.cpp:142
float m_PanDist
Definition: TouchInput.h:84