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

allegroinput.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 <allegro.h>
00060 
00061 #include "guichan/exception.hpp"
00062 #include "guichan/allegro/allegroinput.hpp"
00063 
00064 namespace gcn
00065 {
00066     AllegroInput::AllegroInput()
00067     {
00068         mMouseButton1 = mMouseButton2 = mMouseButton3 = false;
00069         mLastMouseZ = 0;
00070         mLastMouseX = 0;
00071         mLastMouseY = 0;        
00072     }
00073         
00074     bool AllegroInput::isKeyQueueEmpty()
00075     {
00076         return mKeyQueue.empty();
00077     }
00078     
00079     KeyInput AllegroInput::dequeueKeyInput()
00080     {
00081         if (isKeyQueueEmpty())
00082         {
00083             throw GCN_EXCEPTION("Key queue is empty.");
00084         }
00085 
00086         KeyInput ki = mKeyQueue.front();
00087         mKeyQueue.pop();
00088         
00089         return ki;
00090     }
00091     
00092     bool AllegroInput::isMouseQueueEmpty()
00093     {
00094         return mMouseQueue.empty();
00095     }    
00096     
00097     MouseInput AllegroInput::dequeueMouseInput()
00098     {
00099         if (isMouseQueueEmpty())
00100         {
00101             throw GCN_EXCEPTION("Mouse queue is empty.");
00102         }
00103 
00104         MouseInput mi = mMouseQueue.front();
00105         mMouseQueue.pop();
00106         
00107         return mi;    
00108     }
00109     
00110     void AllegroInput::_pollInput()
00111     {
00112         pollMouseInput();
00113         pollKeyInput();
00114     }
00115     
00116     void AllegroInput::pollMouseInput()
00117     {
00118         if (mouse_needs_poll())
00119         {
00120             poll_mouse();
00121         }        
00122         int mouseX = mouse_x;
00123         int mouseY = mouse_y;
00124         int mouseZ = mouse_z;
00125         int mouseB1 = mouse_b & 1;
00126         int mouseB2 = mouse_b & 2;
00127         int mouseB3 = mouse_b & 4;        
00128 
00129         // Check mouse movement
00130         if (mouseX != mLastMouseX || mouseY != mLastMouseY)
00131         {
00132             mMouseQueue.push(MouseInput(MouseInput::EMPTY,
00133                                         MouseInput::MOTION,
00134                                         mouseX,
00135                                         mouseY,
00136                                         0));
00137             mLastMouseX = mouseX;
00138             mLastMouseY = mouseY;
00139         }
00140 
00141         // Check mouse Wheel
00142         while (mLastMouseZ < mouseZ)
00143         {
00144             mMouseQueue.push(MouseInput(MouseInput::WHEEL_UP,
00145                                         MouseInput::PRESS,
00146                                         mouseX,
00147                                         mouseY,
00148                                         0));
00149             
00150             mMouseQueue.push(MouseInput(MouseInput::WHEEL_UP,
00151                                         MouseInput::RELEASE,
00152                                         mouseX,
00153                                         mouseY,
00154                                         0));
00155             
00156             mLastMouseZ++;
00157         }
00158         
00159         while (mLastMouseZ > mouseZ)
00160         {
00161             mMouseQueue.push(MouseInput(MouseInput::WHEEL_DOWN,
00162                                         MouseInput::PRESS,
00163                                         mouseX,
00164                                         mouseY,
00165                                         0));
00166             
00167             mMouseQueue.push(MouseInput(MouseInput::WHEEL_DOWN,
00168                                         MouseInput::RELEASE,
00169                                         mouseX,
00170                                         mouseY,
00171                                         0));
00172             
00173             mLastMouseZ--;
00174         }
00175 
00176         // Check mouse buttons
00177         if (!mMouseButton1 && mouseB1)
00178         {
00179             mMouseQueue.push(MouseInput(MouseInput::LEFT,
00180                                         MouseInput::PRESS,
00181                                         mouseX,
00182                                         mouseY,
00183                                         0));            
00184         }
00185 
00186         if (mMouseButton1 && !mouseB1)
00187         {
00188             mMouseQueue.push(MouseInput(MouseInput::LEFT,
00189                                         MouseInput::RELEASE,
00190                                         mouseX,
00191                                         mouseY,
00192                                         0));
00193         }
00194 
00195         
00196         if (!mMouseButton2 && mouseB2)
00197         {
00198             mMouseQueue.push(MouseInput(MouseInput::RIGHT,
00199                                         MouseInput::PRESS,
00200                                         mouseX,
00201                                         mouseY,
00202                                         0));
00203         }
00204 
00205         if (mMouseButton2 && !mouseB2)
00206         {
00207             mMouseQueue.push(MouseInput(MouseInput::RIGHT,
00208                                         MouseInput::RELEASE,
00209                                         mouseX,
00210                                         mouseY,
00211                                         0));
00212         }
00213 
00214         
00215         if (!mMouseButton3 && mouseB3)
00216         {
00217             mMouseQueue.push(MouseInput(MouseInput::MIDDLE,
00218                                         MouseInput::PRESS,
00219                                         mouseX,
00220                                         mouseY,
00221                                         0));
00222         }
00223 
00224         if (mMouseButton3 && !mouseB3)
00225         {
00226             mMouseQueue.push(MouseInput(MouseInput::MIDDLE,
00227                                         MouseInput::RELEASE,
00228                                         mouseX,
00229                                         mouseY,
00230                                         0));
00231         }
00232 
00233         mMouseButton1 = mouseB1;
00234         mMouseButton2 = mouseB2;
00235         mMouseButton3 = mouseB3;        
00236     }
00237 
00238     void AllegroInput::pollKeyInput()
00239     {
00240         int unicode, scancode;
00241 
00242         if (keyboard_needs_poll())
00243         {
00244             poll_keyboard();
00245         }
00246         
00247         while (keypressed())
00248         {
00249             unicode = ureadkey(&scancode);
00250             Key keyObj = convertToKey(scancode, unicode);
00251             
00252             mKeyQueue.push(
00253                 KeyInput(keyObj, KeyInput::PRESS));
00254             
00255             mPressedKeys[scancode] = keyObj;
00256         }
00257     
00258          // Check for released keys
00259         std::map<int, Key>::iterator iter, tempIter;
00260         for (iter = mPressedKeys.begin(); iter != mPressedKeys.end(); )
00261          {
00262             if (!key[iter->first])
00263             {
00264                  mKeyQueue.push(
00265                     KeyInput(iter->second, KeyInput::RELEASE));
00266                 
00267                 tempIter = iter;
00268                 iter++;
00269                 mPressedKeys.erase(tempIter);
00270             }
00271             else
00272             {
00273                 iter++;
00274             }
00275         }
00276     }
00277     
00278     Key AllegroInput::convertToKey(int scancode, int unicode)
00279     {
00280         int keysym;
00281         bool pad = false;
00282 
00283         switch(scancode)
00284         {
00285           case KEY_ESC:
00286               keysym = Key::ESCAPE;
00287               break;
00288                 
00289           case KEY_ALT:
00290               keysym = Key::LEFT_ALT;
00291               break;
00292 
00293           case KEY_ALTGR:
00294               keysym = Key::RIGHT_ALT;
00295               break;
00296 
00297           case KEY_LSHIFT:
00298               keysym = Key::LEFT_SHIFT;
00299               break;
00300 
00301           case KEY_RSHIFT:
00302               keysym = Key::RIGHT_SHIFT;
00303               break;
00304                 
00305           case KEY_LCONTROL:
00306               keysym = Key::LEFT_CONTROL;
00307               break;
00308                 
00309           case KEY_RCONTROL:
00310               keysym = Key::RIGHT_CONTROL;
00311               break;
00312 
00313           case KEY_LWIN:
00314               keysym = Key::LEFT_META;
00315               break;
00316                 
00317           case KEY_RWIN:
00318               keysym = Key::RIGHT_META;
00319               break;
00320 
00321           case KEY_INSERT:
00322               keysym = Key::INSERT;
00323               break;
00324 
00325           case KEY_HOME:
00326               keysym = Key::HOME;
00327               break;
00328 
00329           case KEY_PGUP:
00330               keysym = Key::PAGE_UP;
00331               break;
00332 
00333           case KEY_PGDN:
00334               keysym = Key::PAGE_DOWN;
00335               break;
00336 
00337           case KEY_DEL:
00338               keysym = Key::DELETE;
00339               break;
00340                 
00341           case KEY_DEL_PAD:
00342               keysym = Key::DELETE;
00343               pad = true;
00344               break;
00345 
00346           case KEY_END:
00347               keysym = Key::END;
00348               break;
00349 
00350           case KEY_CAPSLOCK:
00351               keysym = Key::CAPS_LOCK;
00352               break;
00353 
00354           case KEY_BACKSPACE:
00355               keysym = Key::BACKSPACE;
00356               break;
00357 
00358           case KEY_F1:
00359               keysym = Key::F1;
00360               break;
00361 
00362           case KEY_F2:
00363               keysym = Key::F2;
00364               break;
00365 
00366           case KEY_F3:
00367               keysym = Key::F3;
00368               break;
00369 
00370           case KEY_F4:
00371               keysym = Key::F4;
00372               break;
00373 
00374           case KEY_F5:
00375               keysym = Key::F5;
00376               break;
00377 
00378           case KEY_F6:
00379               keysym = Key::F6;
00380               break;
00381 
00382           case KEY_F7:
00383               keysym = Key::F7;
00384               break;
00385                 
00386           case KEY_F8:
00387               keysym = Key::F8;
00388               break;
00389 
00390           case KEY_F9:
00391               keysym = Key::F9;
00392               break;
00393 
00394           case KEY_F10:
00395               keysym = Key::F10;
00396               break;
00397 
00398           case KEY_F11:
00399               keysym = Key::F11;
00400               break;
00401 
00402           case KEY_F12:
00403               keysym = Key::F12;
00404               break;
00405 
00406           case KEY_PRTSCR:
00407               keysym = Key::PRINT_SCREEN;
00408               break;
00409                 
00410           case KEY_PAUSE:
00411               keysym = Key::PAUSE;
00412               break;
00413 
00414           case KEY_SCRLOCK:
00415               keysym = Key::SCROLL_LOCK;
00416               break;
00417 
00418           case KEY_NUMLOCK:
00419               keysym = Key::NUM_LOCK;
00420               break;
00421 
00422           case KEY_LEFT:
00423               keysym = Key::LEFT;
00424               break;
00425 
00426           case KEY_RIGHT:
00427               keysym = Key::RIGHT;
00428               break;
00429 
00430           case KEY_UP:
00431               keysym = Key::UP;
00432               break;
00433 
00434           case KEY_DOWN:
00435               keysym = Key::DOWN;
00436               break;
00437 
00438           case KEY_ENTER_PAD:
00439               pad = true;                
00440           case KEY_ENTER:
00441               keysym = Key::ENTER;
00442               break;
00443 
00444           case KEY_0_PAD:
00445           case KEY_1_PAD:
00446           case KEY_2_PAD:
00447           case KEY_3_PAD:
00448           case KEY_4_PAD:
00449           case KEY_5_PAD:
00450           case KEY_6_PAD:
00451           case KEY_7_PAD:
00452           case KEY_8_PAD:
00453           case KEY_9_PAD:
00454           case KEY_SLASH_PAD:
00455           case KEY_MINUS_PAD:
00456           case KEY_PLUS_PAD:
00457               pad = true;
00458               // no brakes! no brakes!
00459 
00460           default:
00461               keysym = unicode;
00462         }
00463 
00464         Key k = Key(keysym);
00465         k.setNumericPad(pad);
00466 
00467         k.setShiftPressed(key_shifts & KB_SHIFT_FLAG);
00468         k.setAltPressed(key_shifts & KB_ALT_FLAG);
00469         k.setControlPressed(key_shifts & KB_CTRL_FLAG);
00470 #ifdef KB_COMMAND_FLAG
00471         k.setMetaPressed(key_shifts & (KB_COMMAND_FLAG |
00472                                        KB_LWIN_FLAG |
00473                                        KB_RWIN_FLAG));
00474 #else
00475         k.setMetaPressed(key_shifts & (KB_LWIN_FLAG |
00476                                        KB_RWIN_FLAG));
00477 #endif
00478         
00479         return k;
00480 
00481         //Now, THAT was fun to code! =D =D =D
00482     }
00483 }

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