____ _ __
/ __ )____ _____ | | / /___ ___________
/ __ / __ \/ ___/ | | /| / / __ `/ ___/ ___/
/ /_/ / /_/ (__ ) | |/ |/ / /_/ / / (__ )
/_____/\____/____/ |__/|__/\__,_/_/ /____/
A futuristic real-time strategy game.
This file is part of Bos Wars.
(C) Copyright 2001-2007 by the Bos Wars and Stratagus Project.
Distributed under the "GNU General Public License"00001 /* _______ __ __ __ ______ __ __ _______ __ __ 00002 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ 00003 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / 00004 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / 00005 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / 00006 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / 00007 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ 00008 * 00009 * Copyright (c) 2004, 2005 darkbits Js_./ 00010 * Per Larsson a.k.a finalman _RqZ{a<^_aa 00011 * Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a// 00012 * _Qhm`] _f "'c 1!5m 00013 * Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[ 00014 * .)j(] .d_/ '-( P . S 00015 * License: (BSD) <Td/Z <fP"5(\"??"\a. .L 00016 * Redistribution and use in source and _dV>ws?a-?' ._/L #' 00017 * binary forms, with or without )4d[#7r, . ' )d`)[ 00018 * modification, are permitted provided _Q-5'5W..j/?' -?!\)cam' 00019 * that the following conditions are met: j<<WP+k/);. _W=j f 00020 * 1. Redistributions of source code must .$%w\/]Q . ."' . mj$ 00021 * retain the above copyright notice, ]E.pYY(Q]>. a J@\ 00022 * this list of conditions and the j(]1u<sE"L,. . ./^ ]{a 00023 * following disclaimer. 4'_uomm\. )L);-4 (3= 00024 * 2. Redistributions in binary form must )_]X{Z('a_"a7'<a"a, ]"[ 00025 * reproduce the above copyright notice, #}<]m7`Za??4,P-"'7. ).m 00026 * this list of conditions and the ]d2e)Q(<Q( ?94 b- LQ/ 00027 * following disclaimer in the <B!</]C)d_, '(<' .f. =C+m 00028 * documentation and/or other materials .Z!=J ]e []('-4f _ ) -.)m]' 00029 * provided with the distribution. .w[5]' _[ /.)_-"+? _/ <W" 00030 * 3. Neither the name of Guichan nor the :$we` _! + _/ . j? 00031 * names of its contributors may be used =3)= _f (_yQmWW$#( " 00032 * to endorse or promote products derived - W, sQQQQmZQ#Wwa].. 00033 * from this software without specific (js, \[QQW$QWW#?!V"". 00034 * prior written permission. ]y:.<\.. . 00035 * -]n w/ ' [. 00036 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT )/ )/ ! 00037 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY < (; sac , ' 00038 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ]^ .- % 00039 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF c < r 00040 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR aga< <La 00041 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5% )P'-3L 00042 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR _bQf` y`..)a 00043 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ,J?4P'.P"_(\?d'., 00044 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES _Pa,)!f/<[]/ ?" 00045 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT _2-..:. .r+_,.. . 00046 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ?a.<%"' " -'.a_ _, 00047 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ^ 00048 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00049 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00050 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00051 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00052 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00053 */ 00054 00055 /* 00056 * For comments regarding functions please see the header file. 00057 */ 00058 00059 #include "guichan/sdl/sdlinput.h" 00060 #include "guichan/exception.h" 00061 00062 namespace gcn 00063 { 00064 SDLInput::SDLInput() 00065 { 00066 mMouseInWindow = true; 00067 mMouseDown = false; 00068 mIsRepeating = false; 00069 } 00070 00071 bool SDLInput::isKeyQueueEmpty() 00072 { 00073 return mKeyInputQueue.empty(); 00074 } 00075 00076 KeyInput SDLInput::dequeueKeyInput() 00077 { 00078 KeyInput keyInput; 00079 00080 if (mKeyInputQueue.empty()) 00081 { 00082 throw GCN_EXCEPTION("The queue is empty."); 00083 } 00084 00085 keyInput = mKeyInputQueue.front(); 00086 mKeyInputQueue.pop(); 00087 00088 return keyInput; 00089 } 00090 00091 bool SDLInput::isMouseQueueEmpty() 00092 { 00093 return mMouseInputQueue.empty(); 00094 } 00095 00096 MouseInput SDLInput::dequeueMouseInput() 00097 { 00098 MouseInput mouseInput; 00099 00100 if (mMouseInputQueue.empty()) 00101 { 00102 throw GCN_EXCEPTION("The queue is empty."); 00103 } 00104 00105 mouseInput = mMouseInputQueue.front(); 00106 mMouseInputQueue.pop(); 00107 00108 return mouseInput; 00109 } 00110 00111 void SDLInput::processKeyRepeat() 00112 { 00113 KeyInput keyInput; 00114 00115 if (mIsRepeating) { 00116 keyInput.setKey(mLastKey); 00117 keyInput.setType(KeyInput::PRESS); 00118 mKeyInputQueue.push(keyInput); 00119 } 00120 } 00121 00122 void SDLInput::pushInput(SDL_Event event) 00123 { 00124 KeyInput keyInput; 00125 MouseInput mouseInput; 00126 00127 switch (event.type) 00128 { 00129 case SDL_KEYDOWN: 00130 mLastKey = convertKeyCharacter(event.key.keysym); 00131 mIsRepeating = true; 00132 keyInput.setKey(mLastKey); 00133 keyInput.setType(KeyInput::PRESS); 00134 mKeyInputQueue.push(keyInput); 00135 break; 00136 00137 case SDL_KEYUP: 00138 mIsRepeating = false; 00139 keyInput.setKey(convertKeyCharacter(event.key.keysym)); 00140 keyInput.setType(KeyInput::RELEASE); 00141 mKeyInputQueue.push(keyInput); 00142 break; 00143 00144 case SDL_MOUSEBUTTONDOWN: 00145 mMouseDown = true; 00146 mouseInput.x = event.button.x; 00147 mouseInput.y = event.button.y; 00148 mouseInput.setButton(convertMouseButton(event.button.button)); 00149 mouseInput.setType(MouseInput::PRESS); 00150 mouseInput.setTimeStamp(SDL_GetTicks()); 00151 mMouseInputQueue.push(mouseInput); 00152 break; 00153 00154 case SDL_MOUSEBUTTONUP: 00155 mMouseDown = false; 00156 mouseInput.x = event.button.x; 00157 mouseInput.y = event.button.y; 00158 mouseInput.setButton(convertMouseButton(event.button.button)); 00159 mouseInput.setType(MouseInput::RELEASE); 00160 mouseInput.setTimeStamp(SDL_GetTicks()); 00161 mMouseInputQueue.push(mouseInput); 00162 break; 00163 00164 case SDL_MOUSEMOTION: 00165 mouseInput.x = event.button.x; 00166 mouseInput.y = event.button.y; 00167 mouseInput.setButton(MouseInput::EMPTY); 00168 mouseInput.setType(MouseInput::MOTION); 00169 mouseInput.setTimeStamp(SDL_GetTicks()); 00170 mMouseInputQueue.push(mouseInput); 00171 break; 00172 00173 case SDL_ACTIVEEVENT: 00174 /* 00175 * This occurs when the mouse leaves the window and the Gui-chan 00176 * application loses its mousefocus. 00177 */ 00178 if ((event.active.state & SDL_APPMOUSEFOCUS) 00179 && !event.active.gain) 00180 { 00181 mMouseInWindow = false; 00182 00183 if (!mMouseDown) 00184 { 00185 mouseInput.x = -1; 00186 mouseInput.y = -1; 00187 mouseInput.setButton(MouseInput::EMPTY); 00188 mouseInput.setType(MouseInput::MOTION); 00189 mMouseInputQueue.push(mouseInput); 00190 } 00191 } 00192 00193 if ((event.active.state & SDL_APPMOUSEFOCUS) 00194 && event.active.gain) 00195 { 00196 mMouseInWindow = true; 00197 } 00198 break; 00199 00200 } // end switch 00201 } 00202 00203 int SDLInput::convertMouseButton(int button) 00204 { 00205 switch (button) 00206 { 00207 case SDL_BUTTON_LEFT: 00208 return MouseInput::LEFT; 00209 break; 00210 case SDL_BUTTON_RIGHT: 00211 return MouseInput::RIGHT; 00212 break; 00213 case SDL_BUTTON_MIDDLE: 00214 return MouseInput::MIDDLE; 00215 break; 00216 case SDL_BUTTON_WHEELUP: 00217 return MouseInput::WHEEL_UP; 00218 break; 00219 case SDL_BUTTON_WHEELDOWN: 00220 return MouseInput::WHEEL_DOWN; 00221 break; 00222 } 00223 00224 throw GCN_EXCEPTION("Unknown SDL mouse type."); 00225 00226 return 0; 00227 } 00228 00229 Key SDLInput::convertKeyCharacter(SDL_keysym keysym) 00230 { 00231 int value = 0; 00232 Key key; 00233 00234 if (keysym.unicode < 255) 00235 { 00236 if (keysym.unicode == 0) 00237 { 00238 value = keysym.sym; 00239 } 00240 else 00241 { 00242 value = (int)keysym.unicode; 00243 } 00244 } 00245 00246 switch (keysym.sym) 00247 { 00248 case SDLK_TAB: 00249 value = Key::TAB; 00250 break; 00251 case SDLK_LALT: 00252 value = Key::LEFT_ALT; 00253 break; 00254 case SDLK_RALT: 00255 value = Key::RIGHT_ALT; 00256 break; 00257 case SDLK_LSHIFT: 00258 value = Key::LEFT_SHIFT; 00259 break; 00260 case SDLK_RSHIFT: 00261 value = Key::RIGHT_SHIFT; 00262 break; 00263 case SDLK_LCTRL: 00264 value = Key::LEFT_CONTROL; 00265 break; 00266 case SDLK_RCTRL: 00267 value = Key::RIGHT_CONTROL; 00268 break; 00269 case SDLK_BACKSPACE: 00270 value = Key::BACKSPACE; 00271 break; 00272 case SDLK_PAUSE: 00273 value = Key::PAUSE; 00274 break; 00275 case SDLK_SPACE: 00276 value = Key::SPACE; 00277 break; 00278 case SDLK_ESCAPE: 00279 value = Key::ESCAPE; 00280 break; 00281 case SDLK_DELETE: 00282 value = Key::DELETE; 00283 break; 00284 case SDLK_INSERT: 00285 value = Key::INSERT; 00286 break; 00287 case SDLK_HOME: 00288 value = Key::HOME; 00289 break; 00290 case SDLK_END: 00291 value = Key::END; 00292 break; 00293 case SDLK_PAGEUP: 00294 value = Key::PAGE_UP; 00295 break; 00296 case SDLK_PRINT: 00297 value = Key::PRINT_SCREEN; 00298 break; 00299 case SDLK_PAGEDOWN: 00300 value = Key::PAGE_DOWN; 00301 break; 00302 case SDLK_F1: 00303 value = Key::F1; 00304 break; 00305 case SDLK_F2: 00306 value = Key::F2; 00307 break; 00308 case SDLK_F3: 00309 value = Key::F3; 00310 break; 00311 case SDLK_F4: 00312 value = Key::F4; 00313 break; 00314 case SDLK_F5: 00315 value = Key::F5; 00316 break; 00317 case SDLK_F6: 00318 value = Key::F6; 00319 break; 00320 case SDLK_F7: 00321 value = Key::F7; 00322 break; 00323 case SDLK_F8: 00324 value = Key::F8; 00325 break; 00326 case SDLK_F9: 00327 value = Key::F9; 00328 break; 00329 case SDLK_F10: 00330 value = Key::F10; 00331 break; 00332 case SDLK_F11: 00333 value = Key::F11; 00334 break; 00335 case SDLK_F12: 00336 value = Key::F12; 00337 break; 00338 case SDLK_F13: 00339 value = Key::F13; 00340 break; 00341 case SDLK_F14: 00342 value = Key::F14; 00343 break; 00344 case SDLK_F15: 00345 value = Key::F15; 00346 break; 00347 case SDLK_NUMLOCK: 00348 value = Key::NUM_LOCK; 00349 break; 00350 case SDLK_CAPSLOCK: 00351 value = Key::CAPS_LOCK; 00352 break; 00353 case SDLK_SCROLLOCK: 00354 value = Key::SCROLL_LOCK; 00355 break; 00356 case SDLK_RMETA: 00357 value = Key::RIGHT_META; 00358 break; 00359 case SDLK_LMETA: 00360 value = Key::LEFT_META; 00361 break; 00362 case SDLK_LSUPER: 00363 value = Key::LEFT_SUPER; 00364 break; 00365 case SDLK_RSUPER: 00366 value = Key::RIGHT_SUPER; 00367 break; 00368 case SDLK_MODE: 00369 value = Key::ALT_GR; 00370 break; 00371 case SDLK_UP: 00372 value = Key::UP; 00373 break; 00374 case SDLK_DOWN: 00375 value = Key::DOWN; 00376 break; 00377 case SDLK_LEFT: 00378 value = Key::LEFT; 00379 break; 00380 case SDLK_RIGHT: 00381 value = Key::RIGHT; 00382 break; 00383 case SDLK_RETURN: 00384 value = Key::ENTER; 00385 break; 00386 case SDLK_KP_ENTER: 00387 value = Key::ENTER; 00388 break; 00389 00390 default: 00391 break; 00392 } 00393 00394 if (!(keysym.mod & KMOD_NUM)) 00395 { 00396 switch (keysym.sym) 00397 { 00398 case SDLK_KP0: 00399 value = Key::INSERT; 00400 break; 00401 case SDLK_KP1: 00402 value = Key::END; 00403 break; 00404 case SDLK_KP2: 00405 value = Key::DOWN; 00406 break; 00407 case SDLK_KP3: 00408 value = Key::PAGE_DOWN; 00409 break; 00410 case SDLK_KP4: 00411 value = Key::LEFT; 00412 break; 00413 case SDLK_KP5: 00414 value = 0; 00415 break; 00416 case SDLK_KP6: 00417 value = Key::RIGHT; 00418 break; 00419 case SDLK_KP7: 00420 value = Key::HOME; 00421 break; 00422 case SDLK_KP8: 00423 value = Key::UP; 00424 break; 00425 case SDLK_KP9: 00426 value = Key::PAGE_UP; 00427 break; 00428 default: 00429 break; 00430 } 00431 } 00432 00433 key.setValue(value); 00434 key.setShiftPressed((keysym.mod & KMOD_SHIFT) != 0); 00435 key.setControlPressed((keysym.mod & KMOD_CTRL) != 0); 00436 key.setAltPressed((keysym.mod & KMOD_ALT) != 0); 00437 key.setMetaPressed((keysym.mod & KMOD_META) != 0); 00438 00439 if (keysym.sym >= SDLK_KP0 && keysym.sym <= SDLK_KP_EQUALS) 00440 { 00441 key.setNumericPad(true); 00442 } 00443 00444 return key; 00445 } 00446 }
1.5.6