source: trunk/src/platform/sdl/sdlinput.cpp @ 1709

Last change on this file since 1709 was 1709, checked in by sam, 9 years ago

input: switch SDL joystick handling mode to polling, because we won't get
any events if there is no X window.

  • Property svn:keywords set to Id
File size: 5.1 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#if defined USE_SDL
16#   if defined HAVE_SDL_SDL_H
17#      include <SDL/SDL.h>
18#   else
19#      include <SDL.h>
20#   endif
21#endif
22
23#include "core.h"
24#include "sdlinput.h"
25
26/* We force joystick polling because no events are received when
27 * there is no SDL display (eg. on the Raspberry Pi). */
28#define SDL_FORCE_POLL_JOYSTICK 1
29
30namespace lol
31{
32
33/*
34 * SDL Input implementation class
35 */
36
37class SdlInputData
38{
39    friend class SdlInput;
40
41private:
42    void Tick(float seconds);
43
44    static ivec2 GetMousePos();
45#if defined USE_SDL
46    Array<SDL_Joystick *, Stick *> m_joysticks;
47#endif
48};
49
50/*
51 * Public SdlInput class
52 */
53
54SdlInput::SdlInput()
55  : m_data(new SdlInputData())
56{
57#if defined USE_SDL
58    SDL_Init(SDL_INIT_TIMER | SDL_INIT_JOYSTICK);
59
60#   if SDL_FORCE_POLL_JOYSTICK
61    SDL_JoystickEventState(SDL_QUERY);
62#   else
63    SDL_JoystickEventState(SDL_ENABLE);
64#   endif
65
66    /* Register all the joysticks we can find, and let the input
67     * system decide what it wants to track. */
68    for (int i = 0; i < SDL_NumJoysticks(); i++)
69    {
70        SDL_Joystick *sdlstick = SDL_JoystickOpen(i);
71
72        /* Blacklist HDAPS, it's not a real joystick */
73        char const *name = SDL_JoystickName(i);
74        if (strstr(name, "HDAPS")
75#   if !defined USE_D3D9
76             || strstr(name, "XBOX 360 For Windows")
77#   endif
78             || false)
79        {
80            SDL_JoystickClose(sdlstick);
81            continue;
82        }
83
84        Stick *stick = Input::CreateStick();
85        stick->SetAxisCount(SDL_JoystickNumAxes(sdlstick));
86        stick->SetButtonCount(SDL_JoystickNumButtons(sdlstick));
87
88        /* It's possible to remap axes */
89        //stick->RemapAxis(4, 2);
90        //stick->RemapAxis(2, 4);
91
92        m_data->m_joysticks.Push(sdlstick, stick);
93    }
94#endif
95
96    m_gamegroup = GAMEGROUP_BEFORE;
97}
98
99SdlInput::~SdlInput()
100{
101#if defined USE_SDL
102    /* Unregister all the joysticks we added */
103    while (m_data->m_joysticks.Count())
104    {
105        SDL_JoystickClose(m_data->m_joysticks[0].m1);
106        Input::DestroyStick(m_data->m_joysticks[0].m2);
107        m_data->m_joysticks.Remove(0);
108    }
109#endif
110    delete m_data;
111}
112
113void SdlInput::TickGame(float seconds)
114{
115    Entity::TickGame(seconds);
116
117#if !defined _WIN32
118    m_data->Tick(seconds);
119#endif
120}
121
122void SdlInput::TickDraw(float seconds)
123{
124    Entity::TickDraw(seconds);
125
126#if defined _WIN32
127    m_data->Tick(seconds);
128#endif
129}
130
131void SdlInputData::Tick(float seconds)
132{
133#if defined USE_SDL
134    /* Handle mouse input */
135    ivec2 mouse = SdlInputData::GetMousePos();;
136    Input::SetMousePos(mouse);
137
138#   if SDL_FORCE_POLL_JOYSTICK
139    /* Pump all joystick events because no event is coming to us. */
140    SDL_JoystickUpdate();
141    for (int j = 0; j < m_joysticks.Count(); j++)
142    {
143        for (int i = 0; i < SDL_JoystickNumButtons(m_joysticks[j].m1); i++)
144            m_joysticks[j].m2->SetButton(i, SDL_JoystickGetButton(m_joysticks[j].m1, i));
145        for (int i = 0; i < SDL_JoystickNumAxes(m_joysticks[j].m1); i++)
146            m_joysticks[j].m2->SetAxis(i, (float)SDL_JoystickGetAxis(m_joysticks[j].m1, i) / 32768.f);
147    }
148#   endif
149
150    /* Handle keyboard and WM events */
151    SDL_Event event;
152    while (SDL_PollEvent(&event))
153    {
154        switch (event.type)
155        {
156        case SDL_QUIT:
157            Ticker::Shutdown();
158            break;
159#if 0
160        case SDL_KEYDOWN:
161            Input::KeyPressed(event.key.keysym.sym, seconds);
162            break;
163#endif
164        case SDL_MOUSEBUTTONDOWN:
165        case SDL_MOUSEBUTTONUP:
166        {
167            ivec2 newmouse = SdlInputData::GetMousePos();
168            if (newmouse != mouse)
169                Input::SetMousePos(mouse = newmouse);
170            if (event.type == SDL_MOUSEBUTTONDOWN)
171                Input::SetMouseButton(event.button.button - 1);
172            else
173                Input::UnsetMouseButton(event.button.button - 1);
174            break;
175        }
176
177#   if !SDL_FORCE_POLL_JOYSTICK
178        case SDL_JOYAXISMOTION:
179            m_joysticks[event.jaxis.which].m2->SetAxis(event.jaxis.axis, (float)event.jaxis.value / 32768.f);
180            break;
181
182        case SDL_JOYBUTTONUP:
183        case SDL_JOYBUTTONDOWN:
184            m_joysticks[event.jbutton.which].m2->SetButton(event.jbutton.button, event.jbutton.state);
185            break;
186#   endif
187        }
188    }
189
190    /* Send the whole keyboard state to the input system */
191#if 0
192    Uint8 *keystate = SDL_GetKeyState(NULL);
193    for (int i = 0; i < 256; i++)
194        if (keystate[i])
195            Input::KeyPressed(i, seconds);
196#endif
197#endif
198}
199
200ivec2 SdlInputData::GetMousePos()
201{
202    ivec2 ret(-1, -1);
203
204#if defined USE_SDL
205    if (SDL_GetAppState() & SDL_APPMOUSEFOCUS)
206    {
207        SDL_GetMouseState(&ret.x, &ret.y);
208        ret.y = Video::GetSize().y - 1 - ret.y;
209    }
210#endif
211    return ret;
212}
213
214} /* namespace lol */
215
Note: See TracBrowser for help on using the repository browser.