source: trunk/src/input/input.cpp @ 1751

Last change on this file since 1751 was 1751, checked in by touky, 8 years ago

Added a skeleton for Input Tracking & base idea for Touch/untouch mechanics.

  • Property svn:keywords set to Id
File size: 7.3 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstdlib>
16
17#if defined USE_SDL
18#   if defined HAVE_SDL_SDL_H
19#      include <SDL/SDL.h>
20#   else
21#      include <SDL.h>
22#   endif
23#endif
24
25#include "core.h"
26
27namespace lol
28{
29
30/*
31 * Input implementation class
32 */
33
34Array<ButtonSetting>    Input::InputAssocationList;
35
36static class InputData
37{
38    friend class Input;
39
40public:
41    InputData()
42      : mouse(-1),
43        buttons(0),
44        nentities(0),
45        lastfocus(0)
46    { }
47
48private:
49    ivec2 mouse;
50    ivec3 buttons;
51
52    static int const MAX_ENTITIES = 100;
53    WorldEntity *entities[MAX_ENTITIES];
54    int nentities;
55    WorldEntity *lastfocus;
56
57    Array<Stick *> m_sticks;
58}
59inputdata;
60
61static InputData * const data = &inputdata;
62
63/*
64 * Public Input class
65 */
66
67#if 0
68vec2 Input::GetAxis(int axis)
69{
70    vec2 ret;
71
72#if defined USE_SDL
73    /* Simulate a joystick using the keyboard. This SDL call is free. */
74#if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION >= 3
75    Uint8 *keystate = SDL_GetKeyboardState(NULL);
76#else
77    Uint8 *keystate = SDL_GetKeyState(NULL);
78#endif
79    int left = keystate[SDLK_d] - (keystate[SDLK_a] | keystate[SDLK_q]);
80    int up = (keystate[SDLK_w] | keystate[SDLK_z]) - keystate[SDLK_s] ;
81    ret.x += left;
82    ret.y += up;
83    if (left && up)
84        ret = ret * sqrtf(0.5f);
85#else
86    ret = vec2(0, 0);
87#endif
88
89    return ret;
90}
91#endif
92
93ivec2 Input::GetMousePos()
94{
95    return data->mouse;
96}
97
98ivec3 Input::GetMouseButtons()
99{
100    return data->buttons;
101}
102
103//BH : Added this, is a v0.1 Alpha version.
104int Input::GetButtonState(int button)
105{
106#if defined USE_SDL
107#if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION >= 3
108    Uint8 *keystate = SDL_GetKeyboardState(NULL);
109#else
110    Uint8 *keystate = SDL_GetKeyState(NULL);
111#endif
112    return keystate[button];
113#else
114    return 0;
115#endif
116}
117
118//--
119
120//---
121//Internal : Updates the action status & timers
122void Input::UpdateActionStatus(float seconds)
123{
124        for (int i = 0; i < InputAssocationList.Count(); i++)
125        {
126                ButtonSetting &CurIT = InputAssocationList[i];
127
128                CurIT.PrevStatus = CurIT.CurStatus;
129                CurIT.CurStatus = Input::GetButtonState(CurIT.RawButtonId);
130
131                for (int j = 0; j < CurIT.AssociatedActionList.Count(); j++)
132                {
133                        ActionSetting &CurAS = CurIT.AssociatedActionList[j];
134
135                        if (CurAS.BufferedSince <= CurAS.BufferingTime)
136                                CurAS.BufferedSince += seconds;
137
138                        if (CurIT.CurStatus && CurAS.BufferingTime >= .0f)
139                                CurAS.BufferedSince = .0f;
140                }
141        }
142
143}
144
145//Helps link a software input Action-Id to an hardware input Button-Id.
146void Input::LinkActionIdToButtonId(int ActionId, int ButtonId)
147{
148        int ITIdx = GetButtonSettingIdx(ButtonId);
149        if (ITIdx == -1)
150        {
151                ITIdx = InputAssocationList.Count();
152                InputAssocationList << ButtonSetting(ButtonId);
153        }
154
155        ButtonSetting &CurIT = InputAssocationList[ITIdx];
156
157        int ASIdx = CurIT.GetActionSettingIdx(ActionId);
158        if (ASIdx == -1)
159        {
160                ASIdx = CurIT.AssociatedActionList.Count();
161                CurIT.AssociatedActionList << ActionSetting(ActionId);
162        }
163}
164
165//Helps unlink a software input Action-Id to an hardware input Button-Id.
166void Input::UnlinkActionId(int ActionId)
167{
168        for (int i = 0; i < InputAssocationList.Count(); i++)
169        {
170                ButtonSetting &CurIT = InputAssocationList[i];
171                int ASIdx = CurIT.GetActionSettingIdx(ActionId);
172                if (ASIdx != -1)
173                        CurIT.AssociatedActionList.Remove(ASIdx);
174        }
175}
176
177//Returns the current status of a given action
178int Input::GetActionStatus(int ActionId)
179{
180        for (int i = 0; i < InputAssocationList.Count(); i++)
181        {
182                ButtonSetting &CurIT = InputAssocationList[i];
183                int ASIdx = CurIT.GetActionSettingIdx(ActionId);
184                if (ASIdx != -1)
185                {
186                        ActionSetting &CurAS = CurIT.AssociatedActionList[ASIdx];
187                       
188                        if (CurAS.BufferingTime >= .0f && CurAS.BufferedSince <= CurAS.BufferingTime)
189                                return 1;
190                        return 0;
191                }
192        }
193        return 0;
194}
195
196//Returns TRUE if action status when from Active to Inactive this frame
197bool Input::WasActionJustReleased(int ActionId)
198{
199        for (int i = 0; i < InputAssocationList.Count(); i++)
200        {
201                ButtonSetting &CurIT = InputAssocationList[i];
202                int ASIdx = CurIT.GetActionSettingIdx(ActionId);
203                if (ASIdx != -1)
204                {
205                        if (!CurIT.CurStatus && CurIT.PrevStatus)
206                                return TRUE;
207                        return FALSE;
208                }
209        }
210        return FALSE;
211}
212
213//--
214void Input::TrackMouse(WorldEntity *e)
215{
216    if (data->nentities >= InputData::MAX_ENTITIES)
217        return;
218    data->entities[data->nentities] = e;
219    data->nentities++;
220}
221
222void Input::UntrackMouse(WorldEntity *e)
223{
224    for (int n = 0; n < data->nentities; n++)
225    {
226        if (data->entities[n] != e)
227            continue;
228
229        data->entities[n] = data->entities[data->nentities - 1];
230        data->nentities--;
231        n--;
232    }
233}
234
235void Input::SetMousePos(ivec2 coord)
236{
237    data->mouse = coord;
238
239    WorldEntity *top = NULL;
240
241    for (int n = 0; n < data->nentities; n++)
242    {
243        if (coord.x < data->entities[n]->m_bbox[0].x
244             || coord.x >= data->entities[n]->m_bbox[1].x
245             || coord.y < data->entities[n]->m_bbox[0].y
246             || coord.y >= data->entities[n]->m_bbox[1].y)
247            continue;
248
249        if (!top || top->m_bbox[1].z < data->entities[n]->m_bbox[1].z)
250            top = data->entities[n];
251    }
252
253    for (int n = 0; n < data->nentities; n++)
254    {
255        if (data->entities[n] == top)
256        {
257            data->entities[n]->m_mousepos = coord - (ivec2)top->m_bbox[0].xy;
258            if (top != data->lastfocus)
259                data->entities[n]->m_pressed = data->buttons;
260            else
261                data->entities[n]->m_clicked = ivec3(0);
262        }
263        else
264        {
265            data->entities[n]->m_mousepos = ivec2(-1);
266            /* FIXME */
267            data->entities[n]->m_released = ivec3(0);
268            data->entities[n]->m_pressed = ivec3(0);
269            data->entities[n]->m_clicked = ivec3(0);
270        }
271    }
272
273    data->lastfocus = top;
274}
275
276void Input::SetMouseButton(int index)
277{
278    data->buttons[index] = 1;
279
280    if (data->lastfocus)
281    {
282        if (!data->lastfocus->m_pressed[index])
283            data->lastfocus->m_clicked[index] = 1;
284        data->lastfocus->m_pressed[index] = 1;
285        data->lastfocus->m_released[index] = 0;
286    }
287}
288
289void Input::UnsetMouseButton(int index)
290{
291    data->buttons[index] = 0;
292
293    if (data->lastfocus)
294    {
295        if (data->lastfocus->m_pressed[index])
296            data->lastfocus->m_released[index] = 1;
297        data->lastfocus->m_pressed[index] = 0;
298        data->lastfocus->m_clicked[index] = 0;
299    }
300}
301
302Stick *Input::CreateStick()
303{
304    Stick *stick = new Stick();
305    Ticker::Ref(stick);
306    data->m_sticks.Push(stick);
307    return stick;
308}
309
310void Input::DestroyStick(Stick *stick)
311{
312    for (int i = 0; i < data->m_sticks.Count(); i++)
313        if (data->m_sticks[i] == stick)
314            data->m_sticks.Remove(i);
315    Ticker::Unref(stick);
316}
317
318Stick *Input::TrackStick(int desired)
319{
320    /* FIXME: add the possibility to choose amongst sticks */
321    if (desired >= data->m_sticks.Count())
322        return NULL;
323    Ticker::Ref(data->m_sticks[desired]);
324    return data->m_sticks[desired];
325}
326
327void Input::UntrackStick(Stick *stick)
328{
329    Ticker::Unref(stick);
330}
331
332} /* namespace lol */
333
Note: See TracBrowser for help on using the repository browser.