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

Last change on this file since 2183 was 2183, checked in by sam, 10 years ago

build: fix the WTFPL site URL in all code comments.

  • Property svn:keywords set to Id
File size: 5.4 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://www.wtfpl.net/ 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    /* Enable Unicode translation of keyboard events */
59    SDL_EnableUNICODE(1);
60
61    SDL_Init(SDL_INIT_TIMER | SDL_INIT_JOYSTICK);
62
63#   if SDL_FORCE_POLL_JOYSTICK
64    SDL_JoystickEventState(SDL_QUERY);
65#   else
66    SDL_JoystickEventState(SDL_ENABLE);
67#   endif
68
69    /* Register all the joysticks we can find, and let the input
70     * system decide what it wants to track. */
71    for (int i = 0; i < SDL_NumJoysticks(); i++)
72    {
73        SDL_Joystick *sdlstick = SDL_JoystickOpen(i);
74
75        /* Blacklist some devices:
76         *  - HDAPS, it's not a real joystick.
77         *  - X360 controllers, Xinput handles them better since
78         *    it won't think there is only one trigger axis. */
79        char const *name = SDL_JoystickName(i);
80        if (strstr(name, "HDAPS")
81#   if defined USE_XINPUT
82             || strstr(name, "XBOX 360 For Windows")
83#   endif
84             || false)
85        {
86            SDL_JoystickClose(sdlstick);
87            continue;
88        }
89
90        Stick *stick = Input::CreateStick();
91        stick->SetAxisCount(SDL_JoystickNumAxes(sdlstick));
92        stick->SetButtonCount(SDL_JoystickNumButtons(sdlstick));
93
94        /* It's possible to remap axes */
95        //stick->RemapAxis(4, 2);
96        //stick->RemapAxis(2, 4);
97
98        m_data->m_joysticks.Push(sdlstick, stick);
99    }
100#endif
101
102    m_gamegroup = GAMEGROUP_BEFORE;
103}
104
105SdlInput::~SdlInput()
106{
107#if defined USE_SDL
108    /* Unregister all the joysticks we added */
109    while (m_data->m_joysticks.Count())
110    {
111        SDL_JoystickClose(m_data->m_joysticks[0].m1);
112        Input::DestroyStick(m_data->m_joysticks[0].m2);
113        m_data->m_joysticks.Remove(0);
114    }
115#endif
116    delete m_data;
117}
118
119void SdlInput::TickGame(float seconds)
120{
121    Entity::TickGame(seconds);
122
123#if !defined _WIN32
124    m_data->Tick(seconds);
125#endif
126}
127
128void SdlInput::TickDraw(float seconds)
129{
130    Entity::TickDraw(seconds);
131
132#if defined _WIN32
133    m_data->Tick(seconds);
134#endif
135}
136
137void SdlInputData::Tick(float seconds)
138{
139#if defined USE_SDL
140    /* Handle mouse input */
141    ivec2 mouse = SdlInputData::GetMousePos();;
142    Input::SetMousePos(mouse);
143
144#   if SDL_FORCE_POLL_JOYSTICK
145    /* Pump all joystick events because no event is coming to us. */
146    SDL_JoystickUpdate();
147    for (int j = 0; j < m_joysticks.Count(); j++)
148    {
149        for (int i = 0; i < SDL_JoystickNumButtons(m_joysticks[j].m1); i++)
150            m_joysticks[j].m2->SetButton(i, SDL_JoystickGetButton(m_joysticks[j].m1, i));
151        for (int i = 0; i < SDL_JoystickNumAxes(m_joysticks[j].m1); i++)
152            m_joysticks[j].m2->SetAxis(i, (float)SDL_JoystickGetAxis(m_joysticks[j].m1, i) / 32768.f);
153    }
154#   endif
155
156    /* Handle keyboard and WM events */
157    SDL_Event event;
158    while (SDL_PollEvent(&event))
159    {
160        switch (event.type)
161        {
162        case SDL_QUIT:
163            Ticker::Shutdown();
164            break;
165#if 0
166        case SDL_KEYDOWN:
167            if (event.key.keysym.unicode)
168                fprintf(stderr, "%c (0x%04X)\n", event.key.keysym.unicode, event.key.keysym.unicode);
169            break;
170#endif
171        case SDL_MOUSEBUTTONDOWN:
172        case SDL_MOUSEBUTTONUP:
173        {
174            ivec2 newmouse = SdlInputData::GetMousePos();
175            if (newmouse != mouse)
176                Input::SetMousePos(mouse = newmouse);
177            if (event.type == SDL_MOUSEBUTTONDOWN)
178                Input::SetMouseButton(event.button.button - 1);
179            else
180                Input::UnsetMouseButton(event.button.button - 1);
181            break;
182        }
183
184#   if !SDL_FORCE_POLL_JOYSTICK
185        case SDL_JOYAXISMOTION:
186            m_joysticks[event.jaxis.which].m2->SetAxis(event.jaxis.axis, (float)event.jaxis.value / 32768.f);
187            break;
188
189        case SDL_JOYBUTTONUP:
190        case SDL_JOYBUTTONDOWN:
191            m_joysticks[event.jbutton.which].m2->SetButton(event.jbutton.button, event.jbutton.state);
192            break;
193#   endif
194        }
195    }
196
197    /* Send the whole keyboard state to the input system */
198#if 0
199    Uint8 *keystate = SDL_GetKeyState(NULL);
200    for (int i = 0; i < 256; i++)
201        if (keystate[i])
202            Input::KeyPressed(i, seconds);
203#else
204    (void)seconds;
205#endif
206#endif
207}
208
209ivec2 SdlInputData::GetMousePos()
210{
211    ivec2 ret(-1, -1);
212
213#if defined USE_SDL
214    if (SDL_GetAppState() & SDL_APPMOUSEFOCUS)
215    {
216        SDL_GetMouseState(&ret.x, &ret.y);
217        ret.y = Video::GetSize().y - 1 - ret.y;
218    }
219#endif
220    return ret;
221}
222
223} /* namespace lol */
224
Note: See TracBrowser for help on using the repository browser.