Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

sdlinput.cpp

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.hpp"
00060 #include "guichan/exception.hpp"
00061 
00062 namespace gcn
00063 {
00064     SDLInput::SDLInput()
00065     {
00066         mMouseInWindow = true;
00067     }
00068     
00069     bool SDLInput::isKeyQueueEmpty()
00070     {
00071         return mKeyInputQueue.empty();
00072     }
00073   
00074     KeyInput SDLInput::dequeueKeyInput()
00075     {
00076         KeyInput keyInput;
00077     
00078         if (mKeyInputQueue.empty())
00079         {
00080             throw GCN_EXCEPTION("The queue is empty.");
00081         }
00082     
00083         keyInput = mKeyInputQueue.front();
00084         mKeyInputQueue.pop();
00085 
00086         return keyInput;    
00087     }
00088 
00089     bool SDLInput::isMouseQueueEmpty()
00090     {
00091         return mMouseInputQueue.empty();
00092     }
00093 
00094     MouseInput SDLInput::dequeueMouseInput()
00095     {
00096         MouseInput mouseInput;
00097     
00098         if (mMouseInputQueue.empty())
00099         {
00100             throw GCN_EXCEPTION("The queue is empty.");
00101         }
00102     
00103         mouseInput = mMouseInputQueue.front();
00104         mMouseInputQueue.pop();
00105 
00106         return mouseInput;    
00107     }
00108     
00109     void SDLInput::pushInput(SDL_Event event)
00110     {
00111         KeyInput keyInput;
00112         MouseInput mouseInput;
00113     
00114         switch (event.type)
00115         {
00116           case SDL_KEYDOWN:
00117               keyInput.setKey(convertKeyCharacter(event.key.keysym));
00118               keyInput.setType(KeyInput::PRESS);        
00119               mKeyInputQueue.push(keyInput);
00120               break;
00121 
00122           case SDL_KEYUP:
00123               keyInput.setKey(convertKeyCharacter(event.key.keysym));
00124               keyInput.setType(KeyInput::RELEASE);
00125               mKeyInputQueue.push(keyInput);
00126               break;
00127 
00128           case SDL_MOUSEBUTTONDOWN:
00129               mMouseDown = true;
00130               mouseInput.x = event.button.x;
00131               mouseInput.y = event.button.y;
00132               mouseInput.setButton(convertMouseButton(event.button.button));
00133               mouseInput.setType(MouseInput::PRESS);
00134               mouseInput.setTimeStamp(SDL_GetTicks());
00135               mMouseInputQueue.push(mouseInput);
00136               break;
00137 
00138           case SDL_MOUSEBUTTONUP:
00139               mMouseDown = false;        
00140               mouseInput.x = event.button.x;
00141               mouseInput.y = event.button.y;
00142               mouseInput.setButton(convertMouseButton(event.button.button));
00143               mouseInput.setType(MouseInput::RELEASE);
00144               mouseInput.setTimeStamp(SDL_GetTicks());
00145               mMouseInputQueue.push(mouseInput);
00146               break;
00147         
00148           case SDL_MOUSEMOTION:
00149               mouseInput.x = event.button.x;
00150               mouseInput.y = event.button.y;
00151               mouseInput.setButton(MouseInput::EMPTY);
00152               mouseInput.setType(MouseInput::MOTION);
00153               mouseInput.setTimeStamp(SDL_GetTicks());
00154               mMouseInputQueue.push(mouseInput);
00155               break;
00156         
00157           case SDL_ACTIVEEVENT:
00158               /* 
00159                * This occurs when the mouse leaves the window and the Gui-chan
00160                * application loses its mousefocus.
00161                */
00162               if ((event.active.state & SDL_APPMOUSEFOCUS)
00163                   && !event.active.gain)
00164               {
00165                   mMouseInWindow = false;
00166           
00167                   if (!mMouseDown)
00168                   {
00169                       mouseInput.x = -1;
00170                       mouseInput.y = -1;
00171                       mouseInput.setButton(MouseInput::EMPTY);
00172                       mouseInput.setType(MouseInput::MOTION);
00173                       mMouseInputQueue.push(mouseInput);
00174                   }
00175               }
00176 
00177               if ((event.active.state & SDL_APPMOUSEFOCUS)
00178                   && event.active.gain)
00179               {
00180                   mMouseInWindow = true;
00181               }
00182               break;
00183         
00184         } // end switch
00185     }
00186   
00187     int SDLInput::convertMouseButton(int button)
00188     {
00189         switch (button)
00190         {
00191           case SDL_BUTTON_LEFT:
00192               return MouseInput::LEFT;
00193               break;
00194           case SDL_BUTTON_RIGHT:
00195               return MouseInput::RIGHT;
00196               break;
00197           case SDL_BUTTON_MIDDLE:
00198               return MouseInput::MIDDLE;
00199               break;
00200           case SDL_BUTTON_WHEELUP:
00201               return MouseInput::WHEEL_UP;
00202               break;
00203           case SDL_BUTTON_WHEELDOWN:
00204               return MouseInput::WHEEL_DOWN;
00205               break;
00206         } 
00207 
00208         throw GCN_EXCEPTION("Unknown SDL mouse type.");
00209     
00210         return 0;
00211     }
00212 
00213     Key SDLInput::convertKeyCharacter(SDL_keysym keysym)
00214     {
00215         int value = 0; 
00216         Key key;
00217     
00218         if (keysym.unicode < 255)
00219         {
00220             value = (int)keysym.unicode;
00221         }
00222 
00223         switch (keysym.sym)
00224         {
00225           case SDLK_TAB:
00226               value = Key::TAB;
00227               break;
00228           case SDLK_LALT:
00229               value = Key::LEFT_ALT;
00230               break;
00231           case SDLK_RALT:
00232               value = Key::RIGHT_ALT;
00233               break;
00234           case SDLK_LSHIFT:
00235               value = Key::LEFT_SHIFT;
00236               break;
00237           case SDLK_RSHIFT:
00238               value = Key::RIGHT_SHIFT;
00239               break;
00240           case SDLK_LCTRL:
00241               value = Key::LEFT_CONTROL;
00242               break;
00243           case SDLK_RCTRL:
00244               value = Key::RIGHT_CONTROL;
00245               break;
00246           case SDLK_BACKSPACE:
00247               value = Key::BACKSPACE;
00248               break;
00249           case SDLK_PAUSE:
00250               value = Key::PAUSE;
00251               break;
00252           case SDLK_SPACE:
00253               value = Key::SPACE;
00254               break;
00255           case SDLK_ESCAPE:
00256               value = Key::ESCAPE;
00257               break;
00258           case SDLK_DELETE:
00259               value = Key::DELETE;
00260               break;
00261           case SDLK_INSERT:
00262               value = Key::INSERT;
00263               break;
00264           case SDLK_HOME:
00265               value = Key::HOME;
00266               break;
00267           case SDLK_END:
00268               value = Key::END;
00269               break;
00270           case SDLK_PAGEUP:
00271               value = Key::PAGE_UP;
00272               break;
00273           case SDLK_PRINT:
00274               value = Key::PRINT_SCREEN;
00275               break;
00276           case SDLK_PAGEDOWN:
00277               value = Key::PAGE_DOWN;
00278               break;
00279           case SDLK_F1:
00280               value = Key::F1;
00281               break;
00282           case SDLK_F2:
00283               value = Key::F2;
00284               break;
00285           case SDLK_F3:
00286               value = Key::F3;
00287               break;
00288           case SDLK_F4:
00289               value = Key::F4;
00290               break;
00291           case SDLK_F5:
00292               value = Key::F5;
00293               break;
00294           case SDLK_F6:
00295               value = Key::F6;
00296               break;
00297           case SDLK_F7:
00298               value = Key::F7;
00299               break;
00300           case SDLK_F8:
00301               value = Key::F8;
00302               break;
00303           case SDLK_F9:
00304               value = Key::F9;
00305               break;
00306           case SDLK_F10:
00307               value = Key::F10;
00308               break;
00309           case SDLK_F11:
00310               value = Key::F11;
00311               break;
00312           case SDLK_F12:
00313               value = Key::F12;
00314               break;
00315           case SDLK_F13:
00316               value = Key::F13;
00317               break;
00318           case SDLK_F14:
00319               value = Key::F14;
00320               break;
00321           case SDLK_F15:
00322               value = Key::F15;
00323               break;
00324           case SDLK_NUMLOCK:
00325               value = Key::NUM_LOCK;
00326               break;
00327           case SDLK_CAPSLOCK:
00328               value = Key::CAPS_LOCK;
00329               break;
00330           case SDLK_SCROLLOCK:
00331               value = Key::SCROLL_LOCK;
00332               break;
00333           case SDLK_RMETA:
00334               value = Key::RIGHT_META;
00335               break;
00336           case SDLK_LMETA:
00337               value = Key::LEFT_META;
00338               break;
00339           case SDLK_LSUPER:
00340               value = Key::LEFT_SUPER;
00341               break;
00342           case SDLK_RSUPER:
00343               value = Key::RIGHT_SUPER;
00344               break;
00345           case SDLK_MODE:
00346               value = Key::ALT_GR;
00347               break;
00348           case SDLK_UP:
00349               value = Key::UP;
00350               break;
00351           case SDLK_DOWN:
00352               value = Key::DOWN;
00353               break;
00354           case SDLK_LEFT:
00355               value = Key::LEFT;
00356               break;
00357           case SDLK_RIGHT:
00358               value = Key::RIGHT;
00359               break;
00360           case SDLK_RETURN:
00361               value = Key::ENTER;
00362               break;
00363           case SDLK_KP_ENTER:
00364               value = Key::ENTER;
00365               break;
00366 
00367           default:
00368               break;
00369         }
00370 
00371         if (!(keysym.mod & KMOD_NUM))
00372         {
00373             switch (keysym.sym)
00374             {
00375               case SDLK_KP0:
00376                   value = Key::INSERT;
00377                   break;
00378               case SDLK_KP1:
00379                   value = Key::END;
00380                   break;
00381               case SDLK_KP2:
00382                   value = Key::DOWN;
00383                   break;
00384               case SDLK_KP3:
00385                   value = Key::PAGE_DOWN;
00386                   break;
00387               case SDLK_KP4:
00388                   value = Key::LEFT;
00389                   break;
00390               case SDLK_KP5:
00391                   value = 0;
00392                   break;
00393               case SDLK_KP6:
00394                   value = Key::RIGHT;
00395                   break;
00396               case SDLK_KP7:
00397                   value = Key::HOME;
00398                   break;
00399               case SDLK_KP8:
00400                   value = Key::UP;
00401                   break;
00402               case SDLK_KP9:
00403                   value = Key::PAGE_UP;
00404                   break;          
00405               default:
00406                   break;
00407             } 
00408         }
00409 
00410         key.setValue(value);
00411         key.setShiftPressed(keysym.mod & KMOD_SHIFT);
00412         key.setControlPressed(keysym.mod & KMOD_CTRL);
00413         key.setAltPressed(keysym.mod & KMOD_ALT);
00414         key.setMetaPressed(keysym.mod & KMOD_META);
00415 
00416         if (keysym.sym >= SDLK_KP0 && keysym.sym <= SDLK_KP_EQUALS)
00417         {
00418             key.setNumericPad(true);
00419         }
00420     
00421         return key;    
00422     }
00423 }

Generated on Tue May 17 21:23:26 2005 for Guichan by  doxygen 1.4.1