~ubuntu-branches/ubuntu/lucid/balder2d/lucid

« back to all changes in this revision

Viewing changes to src/input.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bjørn Hansen
  • Date: 2006-10-14 15:33:42 UTC
  • Revision ID: james.westby@ubuntu.com-20061014153342-un0jglolcs01gcow
Tags: upstream-1.0~rc1
Import upstream version 1.0~rc1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2004 by Bjorn Hansen                                    *
 
3
 *   holomorph@users.sourceforge.net                                       *
 
4
 *                                                                         *
 
5
 *   This program is free software; you can redistribute it and/or modify  *
 
6
 *   it under the terms of the GNU General Public License as published by  *
 
7
 *   the Free Software Foundation; either version 2 of the License, or     *
 
8
 *   (at your option) any later version.                                   *
 
9
 *                                                                         *
 
10
 *   This program is distributed in the hope that it will be useful,       *
 
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
13
 *   GNU General Public License for more details.                          *
 
14
 *                                                                         *
 
15
 *   You should have received a copy of the GNU General Public License     *
 
16
 *   along with this program; if not, write to the                         *
 
17
 *   Free Software Foundation, Inc.,                                       *
 
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 
19
 ***************************************************************************/
 
20
 
 
21
#include <SDL/SDL.h>
 
22
#include <SDL/SDL_keyboard.h>
 
23
#include <map>
 
24
#include <string>
 
25
#include "../include/input.h"
 
26
#include "../include/gamemanager.h"
 
27
#include "../include/configmanager.h"
 
28
#include "../include/player.h"
 
29
#include "../include/log.h"
 
30
 
 
31
using namespace Balder;
 
32
 
 
33
const struct {
 
34
        const char *s;
 
35
        SDLKey k;
 
36
} SDLKeyStringTable[] = {
 
37
        {"BACKSPACE", SDLK_BACKSPACE},
 
38
        {"TAB",       SDLK_TAB}, 
 
39
        {"ENTER",     SDLK_RETURN}, 
 
40
        {"PAUSE",     SDLK_PAUSE}, 
 
41
        {"ESC",       SDLK_ESCAPE}, 
 
42
        {"SPACE",     SDLK_SPACE}, 
 
43
        {"DEL",       SDLK_DELETE}, 
 
44
        {"KP0",       SDLK_KP0}, 
 
45
        {"KP1",       SDLK_KP1}, 
 
46
        {"KP2",       SDLK_KP2}, 
 
47
        {"KP3",       SDLK_KP3}, 
 
48
        {"KP4",       SDLK_KP4}, 
 
49
        {"KP5",       SDLK_KP5}, 
 
50
        {"KP6",       SDLK_KP6}, 
 
51
        {"KP7",       SDLK_KP7}, 
 
52
        {"KP8",       SDLK_KP8}, 
 
53
        {"KP9",       SDLK_KP9}, 
 
54
        {"KP.",       SDLK_KP_PERIOD}, 
 
55
        {"KP/",       SDLK_KP_DIVIDE}, 
 
56
        {"KP*",       SDLK_KP_MULTIPLY}, 
 
57
        {"KP-",       SDLK_KP_MINUS}, 
 
58
        {"KP+",       SDLK_KP_PLUS}, 
 
59
        {"KP_ENTER",  SDLK_KP_ENTER}, 
 
60
        {"UP",        SDLK_UP}, 
 
61
        {"DOWN",      SDLK_DOWN}, 
 
62
        {"RIGHT",     SDLK_RIGHT}, 
 
63
        {"LEFT",      SDLK_LEFT}, 
 
64
        {"INSERT",    SDLK_INSERT}, 
 
65
        {"HOME",      SDLK_HOME}, 
 
66
        {"END",       SDLK_END}, 
 
67
        {"PAGEUP",    SDLK_PAGEUP}, 
 
68
        {"PAGEDOWN",  SDLK_PAGEDOWN}, 
 
69
        {"F1",        SDLK_F1}, 
 
70
        {"F2",        SDLK_F2}, 
 
71
        {"F3",        SDLK_F3}, 
 
72
        {"F4",        SDLK_F4}, 
 
73
        {"F5",        SDLK_F5}, 
 
74
        {"F6",        SDLK_F6}, 
 
75
        {"F7",        SDLK_F7}, 
 
76
        {"F8",        SDLK_F8}, 
 
77
        {"F9",        SDLK_F9}, 
 
78
        {"F10",       SDLK_F10}, 
 
79
        {"F11",       SDLK_F11}, 
 
80
        {"F12",       SDLK_F12}, 
 
81
        {"F13",       SDLK_F13}, 
 
82
        {"F14",       SDLK_F14}, 
 
83
        {"F15",       SDLK_F15},
 
84
        {"RSHIFT",        SDLK_RSHIFT},
 
85
        {"LSHIFT",    SDLK_LSHIFT},
 
86
        {"RCTRL",         SDLK_RCTRL},
 
87
        {"LCTRL",         SDLK_LCTRL},
 
88
        {"RALT",          SDLK_RALT},
 
89
        {"LALT",          SDLK_LALT},
 
90
        {"", SDLK_UNKNOWN} // terminator
 
91
};
 
92
 
 
93
typedef std::map<std::string, SDLKey> ParseKeyMap;
 
94
typedef std::map<std::string, SDLKey>::iterator ParseKeyIterator;
 
95
static ParseKeyMap parse_key_map;
 
96
 
 
97
bool Input::keymapInitialized = false;
 
98
 
 
99
// contstructor
 
100
  Input::Input(GameManager* gm, int nplayers): 
 
101
  game_manager(gm), num_players(nplayers)
 
102
{
 
103
    SDL_JoystickEventState(SDL_ENABLE);
 
104
    joystick = SDL_JoystickOpen(0); // joystick 0
 
105
        controllers = new PlayerController[num_players];
 
106
        BindKeys();
 
107
}
 
108
 
 
109
// checks the input state and pass it along to the game manager
 
110
void Input::CheckInput()
 
111
{
 
112
    SDL_Event event;
 
113
    if(SDL_PollEvent(&event))
 
114
    {
 
115
        SDLKey k;
 
116
        input_states old;
 
117
                switch(event.type)
 
118
        {
 
119
                case SDL_QUIT:
 
120
                game_manager->Quit();
 
121
                exit(2);
 
122
                break;
 
123
            case SDL_KEYDOWN:
 
124
                k = event.key.keysym.sym;
 
125
                if(SDLK_ESCAPE == k)
 
126
                        game_manager->Quit();
 
127
                // now check if the key is mapped to any player action
 
128
                for (int i = 0; i < num_players; ++i)
 
129
                {
 
130
                        old = controllers[i].inputs;
 
131
                        if (k == controllers[i].right)
 
132
                                controllers[i].inputs = old | RIGHT;
 
133
                        if (k == controllers[i].left)
 
134
                                controllers[i].inputs = old | LEFT;
 
135
                        if (k == controllers[i].stick)
 
136
                                controllers[i].inputs = old | STICK;
 
137
                        if (k == controllers[i].push)
 
138
                                controllers[i].inputs = old | PUSH;
 
139
                        if (k == controllers[i].fire)
 
140
                                controllers[i].inputs = old | FIRE;
 
141
                        // if anything was changed, send an event to the gamemanager
 
142
                        if (old != controllers[i].inputs){
 
143
                                game_manager->SendInputState(
 
144
                                        controllers[i].id, controllers[i].inputs);
 
145
                        }
 
146
                }
 
147
                break;
 
148
            case SDL_KEYUP:
 
149
                k = event.key.keysym.sym;
 
150
                // check if the key is mapped to any player action
 
151
                for (int i = 0; i < num_players; ++i)
 
152
                {
 
153
                        old = controllers[i].inputs;
 
154
                        if (k == controllers[i].right)
 
155
                                controllers[i].inputs = old - RIGHT;
 
156
                        if (k == controllers[i].left)
 
157
                                controllers[i].inputs = old - LEFT;
 
158
                        if (k == controllers[i].stick)
 
159
                                controllers[i].inputs = old - STICK;
 
160
                        if (k == controllers[i].push)
 
161
                                controllers[i].inputs = old - PUSH;
 
162
                        if (k == controllers[i].fire)
 
163
                                controllers[i].inputs = old - FIRE;
 
164
                        // if anything was changed, send an event to the gamemanager
 
165
                        if (old != controllers[i].inputs){
 
166
                                game_manager->SendInputState(
 
167
                                        controllers[i].id, controllers[i].inputs);
 
168
                        }
 
169
                }
 
170
                break;
 
171
            case SDL_JOYBUTTONDOWN: // hard coded to controller one, button0=fire, button1=push/stick
 
172
                old = controllers[1].inputs;
 
173
                if(event.jbutton.button == 0)
 
174
                    controllers[1].inputs = old | FIRE;
 
175
                else if(event.jbutton.button == 1)
 
176
                    controllers[1].inputs = old | STICK;
 
177
                else break;
 
178
                // we know at this point that button 0 or 1 was pressed,
 
179
                // so send the event
 
180
                game_manager->SendInputState(controllers[1].id, controllers[1].inputs);
 
181
                break;
 
182
            case SDL_JOYBUTTONUP:
 
183
                old = controllers[1].inputs;
 
184
                if(event.jbutton.button == 0 && (old & FIRE))
 
185
                    controllers[1].inputs = old - FIRE;
 
186
                else if(event.jbutton.button == 1 && (old & STICK))
 
187
                    controllers[1].inputs = old - STICK;
 
188
                else break;
 
189
                // we know at this point that button 0 or 1 was released, so send the event
 
190
                game_manager->SendInputState(controllers[1].id, controllers[1].inputs);
 
191
                break;
 
192
            case SDL_JOYAXISMOTION:
 
193
                if (event.jaxis.axis == 0){ // left/right
 
194
                    old = controllers[1].inputs;
 
195
                    if(event.jaxis.value < -3200){ // left
 
196
                        controllers[1].inputs = old | LEFT;
 
197
                        if (old & RIGHT)
 
198
                            controllers[1].inputs = old - RIGHT; 
 
199
                    }
 
200
                    else if(event.jaxis.value > 3200){ // right
 
201
                        controllers[1].inputs = old | RIGHT;
 
202
                        if (old & LEFT)
 
203
                            controllers[1].inputs = old - LEFT; 
 
204
                    }
 
205
                    else {
 
206
                        if (old & RIGHT)
 
207
                            controllers[1].inputs = old - RIGHT;
 
208
                        if (old & LEFT)
 
209
                            controllers[1].inputs = old - LEFT; 
 
210
                    }
 
211
                }
 
212
                // if anything was changed, send an event to the gamemanager
 
213
                if (old != controllers[1].inputs){
 
214
                        game_manager->SendInputState(
 
215
                                controllers[1].id, controllers[1].inputs);
 
216
                }
 
217
                break;
 
218
            default:
 
219
                return;
 
220
        }
 
221
    }   
 
222
}
 
223
 
 
224
 
 
225
void Input::SetPlayerInputController(player_id id, int controller_number)
 
226
{
 
227
        if (controller_number <= num_players) {
 
228
                controllers[controller_number -1].id = id;
 
229
        }
 
230
}
 
231
 
 
232
void Input::MapKeys()
 
233
{
 
234
        // fill the parse map
 
235
        int i;
 
236
        // put in all named keys
 
237
        for (i = 0; strlen(SDLKeyStringTable[i].s) > 0; i++)
 
238
        {
 
239
                parse_key_map[SDLKeyStringTable[i].s] = SDLKeyStringTable[i].k;
 
240
        }
 
241
        // add 1 character keys
 
242
        for (i = 33; i <123; i++)
 
243
        {
 
244
                // skip upper case letters
 
245
                if (65 == i) i = 91;
 
246
                // there has to be a cleaner way to do this but. . .
 
247
                std::string s("a");
 
248
                s[0] = (char)i;
 
249
                const char* c = s.c_str();
 
250
                parse_key_map[c] = (SDLKey)i;
 
251
        }
 
252
        keymapInitialized = true;
 
253
}
 
254
 
 
255
const char* Input::GetKeyString(SDLKey k)
 
256
{
 
257
        if (!keymapInitialized) { MapKeys();}
 
258
        ParseKeyIterator itr = parse_key_map.begin();
 
259
        while ((*itr).second != k) {
 
260
                ++itr;
 
261
                if (itr == parse_key_map.end()){ return "none";}
 
262
        }
 
263
        return (*itr).first.c_str();
 
264
}
 
265
 
 
266
 
 
267
void Input::BindKeys()
 
268
{       
 
269
        if (!keymapInitialized) { MapKeys();}   
 
270
        // now get all of the keys from the config manager.
 
271
        const char* key;
 
272
        SDLKey k;
 
273
        for (int i = 0; i < num_players; ++i)
 
274
        {
 
275
                // It is convenient to set the initial input state here so we will
 
276
                controllers[i].inputs = 0;
 
277
                // remember, players are numbered starting at 1, but the controllers 
 
278
                // array is indexed 0 to (num_players - 1), so the controller number 
 
279
                // we pass to the config manager is i + 1.
 
280
                key = ConfigManager::GetPlayerControl(i+1,"right");
 
281
                if (key && parse_key_map.count(key)) {k = parse_key_map[key];}
 
282
                else {k = SDLK_UNKNOWN;}
 
283
                controllers[i].right = k;
 
284
                
 
285
                key = ConfigManager::GetPlayerControl(i+1,"left");
 
286
                if (key && parse_key_map.count(key)) {k = parse_key_map[key];}
 
287
                else {k = SDLK_UNKNOWN;}
 
288
                controllers[i].left = k;
 
289
                
 
290
                key = ConfigManager::GetPlayerControl(i+1,"stick");
 
291
                if (key && parse_key_map.count(key)) {k = parse_key_map[key];}
 
292
                else {k = SDLK_UNKNOWN;}
 
293
                controllers[i].stick = k;
 
294
                
 
295
                key = ConfigManager::GetPlayerControl(i+1,"push");
 
296
                if (key && parse_key_map.count(key)) {k = parse_key_map[key];}
 
297
                else {k = SDLK_UNKNOWN;}
 
298
                controllers[i].push = k;
 
299
                
 
300
                key = ConfigManager::GetPlayerControl(i+1,"fire");
 
301
                if (key && parse_key_map.count(key)) {k = parse_key_map[key];}
 
302
                else {k = SDLK_UNKNOWN;}
 
303
                controllers[i].fire = k;                                
 
304
        }
 
305
}
 
306
 
 
307