allegroinput.cpp

00001 /*      _______   __   __   __   ______   __   __   _______   __   __
00002  *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
00003  *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
00004  *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
00005  *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
00006  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
00007  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
00008  *
00009  * Copyright (c) 2004, 2005, 2006 Olof Naessén and Per Larsson
00010  *
00011  *                                                         Js_./
00012  * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
00013  * Olof Naessén a.k.a jansem/yakslem                _asww7!uY`>  )\a//
00014  *                                                 _Qhm`] _f "'c  1!5m
00015  * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
00016  *                                               .)j(] .d_/ '-(  P .   S
00017  * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
00018  * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
00019  * binary forms, with or without                 )4d[#7r, .   '     )d`)[
00020  * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
00021  * that the following conditions are met:       j<<WP+k/);.        _W=j f
00022  * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
00023  *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
00024  *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
00025  *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
00026  * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
00027  *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
00028  *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
00029  *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
00030  *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
00031  *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
00032  * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
00033  *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
00034  *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
00035  *    from this software without specific        (js, \[QQW$QWW#?!V"".
00036  *    prior written permission.                    ]y:.<\..          .
00037  *                                                 -]n w/ '         [.
00038  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
00039  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
00040  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
00041  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
00042  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
00043  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
00044  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
00045  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
00046  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
00047  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
00048  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
00049  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
00050  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00051  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00052  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00053  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00054  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00055  */
00056 
00057 /*
00058  * For comments regarding functions please see the header file.
00059  */
00060 
00061 #include "guichan/allegro/allegroinput.hpp"
00062 
00063 #include <allegro.h>
00064 
00065 #include "guichan/exception.hpp"
00066 
00067 namespace gcn
00068 {
00069     AllegroInput::AllegroInput()
00070     {
00071         mMouseButton1 = mMouseButton2 = mMouseButton3 = false;
00072         mLastMouseZ = 0;
00073         mLastMouseX = 0;
00074         mLastMouseY = 0;
00075     }
00076 
00077     bool AllegroInput::isKeyQueueEmpty()
00078     {
00079         return mKeyQueue.empty();
00080     }
00081 
00082     KeyInput AllegroInput::dequeueKeyInput()
00083     {
00084         if (isKeyQueueEmpty())
00085         {
00086             throw GCN_EXCEPTION("Key queue is empty.");
00087         }
00088 
00089         KeyInput ki = mKeyQueue.front();
00090         mKeyQueue.pop();
00091 
00092         return ki;
00093     }
00094 
00095     bool AllegroInput::isMouseQueueEmpty()
00096     {
00097         return mMouseQueue.empty();
00098     }
00099 
00100     MouseInput AllegroInput::dequeueMouseInput()
00101     {
00102         if (isMouseQueueEmpty())
00103         {
00104             throw GCN_EXCEPTION("Mouse queue is empty.");
00105         }
00106 
00107         MouseInput mi = mMouseQueue.front();
00108         mMouseQueue.pop();
00109 
00110         return mi;
00111     }
00112 
00113     void AllegroInput::_pollInput()
00114     {
00115         pollMouseInput();
00116         pollKeyInput();
00117     }
00118 
00119     void AllegroInput::pollMouseInput()
00120     {
00121         if (mouse_needs_poll())
00122         {
00123             poll_mouse();
00124         }
00125         int mouseX = mouse_x;
00126         int mouseY = mouse_y;
00127         int mouseZ = mouse_z;
00128         int mouseB1 = mouse_b & 1;
00129         int mouseB2 = mouse_b & 2;
00130         int mouseB3 = mouse_b & 4;
00131 
00132         // Check mouse movement
00133         if (mouseX != mLastMouseX || mouseY != mLastMouseY)
00134         {
00135             mMouseQueue.push(MouseInput(MouseInput::EMPTY,
00136                                         MouseInput::MOTION,
00137                                         mouseX,
00138                                         mouseY,
00139                                         0));
00140             mLastMouseX = mouseX;
00141             mLastMouseY = mouseY;
00142         }
00143 
00144         // Check mouse Wheel
00145         while (mLastMouseZ < mouseZ)
00146         {
00147             mMouseQueue.push(MouseInput(MouseInput::WHEEL_UP,
00148                                         MouseInput::PRESS,
00149                                         mouseX,
00150                                         mouseY,
00151                                         0));
00152 
00153             mMouseQueue.push(MouseInput(MouseInput::WHEEL_UP,
00154                                         MouseInput::RELEASE,
00155                                         mouseX,
00156                                         mouseY,
00157                                         0));
00158 
00159             mLastMouseZ++;
00160         }
00161 
00162         while (mLastMouseZ > mouseZ)
00163         {
00164             mMouseQueue.push(MouseInput(MouseInput::WHEEL_DOWN,
00165                                         MouseInput::PRESS,
00166                                         mouseX,
00167                                         mouseY,
00168                                         0));
00169 
00170             mMouseQueue.push(MouseInput(MouseInput::WHEEL_DOWN,
00171                                         MouseInput::RELEASE,
00172                                         mouseX,
00173                                         mouseY,
00174                                         0));
00175 
00176             mLastMouseZ--;
00177         }
00178 
00179         // Check mouse buttons
00180         if (!mMouseButton1 && mouseB1)
00181         {
00182             mMouseQueue.push(MouseInput(MouseInput::LEFT,
00183                                         MouseInput::PRESS,
00184                                         mouseX,
00185                                         mouseY,
00186                                         0));
00187         }
00188 
00189         if (mMouseButton1 && !mouseB1)
00190         {
00191             mMouseQueue.push(MouseInput(MouseInput::LEFT,
00192                                         MouseInput::RELEASE,
00193                                         mouseX,
00194                                         mouseY,
00195                                         0));
00196         }
00197 
00198 
00199         if (!mMouseButton2 && mouseB2)
00200         {
00201             mMouseQueue.push(MouseInput(MouseInput::RIGHT,
00202                                         MouseInput::PRESS,
00203                                         mouseX,
00204                                         mouseY,
00205                                         0));
00206         }
00207 
00208         if (mMouseButton2 && !mouseB2)
00209         {
00210             mMouseQueue.push(MouseInput(MouseInput::RIGHT,
00211                                         MouseInput::RELEASE,
00212                                         mouseX,
00213                                         mouseY,
00214                                         0));
00215         }
00216 
00217 
00218         if (!mMouseButton3 && mouseB3)
00219         {
00220             mMouseQueue.push(MouseInput(MouseInput::MIDDLE,
00221                                         MouseInput::PRESS,
00222                                         mouseX,
00223                                         mouseY,
00224                                         0));
00225         }
00226 
00227         if (mMouseButton3 && !mouseB3)
00228         {
00229             mMouseQueue.push(MouseInput(MouseInput::MIDDLE,
00230                                         MouseInput::RELEASE,
00231                                         mouseX,
00232                                         mouseY,
00233                                         0));
00234         }
00235 
00236         mMouseButton1 = mouseB1;
00237         mMouseButton2 = mouseB2;
00238         mMouseButton3 = mouseB3;
00239     }
00240 
00241     void AllegroInput::pollKeyInput()
00242     {
00243         int unicode, scancode;
00244 
00245         if (keyboard_needs_poll())
00246         {
00247             poll_keyboard();
00248         }
00249 
00250         while (keypressed())
00251         {
00252             unicode = ureadkey(&scancode);
00253             Key keyObj = convertToKey(scancode, unicode);
00254 
00255             mKeyQueue.push(
00256                 KeyInput(keyObj, KeyInput::PRESS));
00257 
00258             mPressedKeys[scancode] = keyObj;
00259         }
00260 
00261          // Check for released keys
00262         std::map<int, Key>::iterator iter, tempIter;
00263         for (iter = mPressedKeys.begin(); iter != mPressedKeys.end(); )
00264          {
00265             if (!key[iter->first])
00266             {
00267                  mKeyQueue.push(
00268                     KeyInput(iter->second, KeyInput::RELEASE));
00269 
00270                 tempIter = iter;
00271                 iter++;
00272                 mPressedKeys.erase(tempIter);
00273             }
00274             else
00275             {
00276                 iter++;
00277             }
00278         }
00279     }
00280 
00281     Key AllegroInput::convertToKey(int scancode, int unicode)
00282     {
00283         int keysym;
00284         bool pad = false;
00285 
00286         switch(scancode)
00287         {
00288           case KEY_ESC:
00289               keysym = Key::ESCAPE;
00290               break;
00291 
00292           case KEY_ALT:
00293               keysym = Key::LEFT_ALT;
00294               break;
00295 
00296           case KEY_ALTGR:
00297               keysym = Key::RIGHT_ALT;
00298               break;
00299 
00300           case KEY_LSHIFT:
00301               keysym = Key::LEFT_SHIFT;
00302               break;
00303 
00304           case KEY_RSHIFT:
00305               keysym = Key::RIGHT_SHIFT;
00306               break;
00307 
00308           case KEY_LCONTROL:
00309               keysym = Key::LEFT_CONTROL;
00310               break;
00311 
00312           case KEY_RCONTROL:
00313               keysym = Key::RIGHT_CONTROL;
00314               break;
00315 
00316           case KEY_LWIN:
00317               keysym = Key::LEFT_META;
00318               break;
00319 
00320           case KEY_RWIN:
00321               keysym = Key::RIGHT_META;
00322               break;
00323 
00324           case KEY_INSERT:
00325               keysym = Key::INSERT;
00326               break;
00327 
00328           case KEY_HOME:
00329               keysym = Key::HOME;
00330               break;
00331 
00332           case KEY_PGUP:
00333               keysym = Key::PAGE_UP;
00334               break;
00335 
00336           case KEY_PGDN:
00337               keysym = Key::PAGE_DOWN;
00338               break;
00339 
00340           case KEY_DEL:
00341               keysym = Key::DELETE;
00342               break;
00343 
00344           case KEY_DEL_PAD:
00345               keysym = Key::DELETE;
00346               pad = true;
00347               break;
00348 
00349           case KEY_END:
00350               keysym = Key::END;
00351               break;
00352 
00353           case KEY_CAPSLOCK:
00354               keysym = Key::CAPS_LOCK;
00355               break;
00356 
00357           case KEY_BACKSPACE:
00358               keysym = Key::BACKSPACE;
00359               break;
00360 
00361           case KEY_F1:
00362               keysym = Key::F1;
00363               break;
00364 
00365           case KEY_F2:
00366               keysym = Key::F2;
00367               break;
00368 
00369           case KEY_F3:
00370               keysym = Key::F3;
00371               break;
00372 
00373           case KEY_F4:
00374               keysym = Key::F4;
00375               break;
00376 
00377           case KEY_F5:
00378               keysym = Key::F5;
00379               break;
00380 
00381           case KEY_F6:
00382               keysym = Key::F6;
00383               break;
00384 
00385           case KEY_F7:
00386               keysym = Key::F7;
00387               break;
00388 
00389           case KEY_F8:
00390               keysym = Key::F8;
00391               break;
00392 
00393           case KEY_F9:
00394               keysym = Key::F9;
00395               break;
00396 
00397           case KEY_F10:
00398               keysym = Key::F10;
00399               break;
00400 
00401           case KEY_F11:
00402               keysym = Key::F11;
00403               break;
00404 
00405           case KEY_F12:
00406               keysym = Key::F12;
00407               break;
00408 
00409           case KEY_PRTSCR:
00410               keysym = Key::PRINT_SCREEN;
00411               break;
00412 
00413           case KEY_PAUSE:
00414               keysym = Key::PAUSE;
00415               break;
00416 
00417           case KEY_SCRLOCK:
00418               keysym = Key::SCROLL_LOCK;
00419               break;
00420 
00421           case KEY_NUMLOCK:
00422               keysym = Key::NUM_LOCK;
00423               break;
00424 
00425           case KEY_LEFT:
00426               keysym = Key::LEFT;
00427               break;
00428 
00429           case KEY_RIGHT:
00430               keysym = Key::RIGHT;
00431               break;
00432 
00433           case KEY_UP:
00434               keysym = Key::UP;
00435               break;
00436 
00437           case KEY_DOWN:
00438               keysym = Key::DOWN;
00439               break;
00440 
00441           case KEY_ENTER_PAD:
00442               pad = true;
00443           case KEY_ENTER:
00444               keysym = Key::ENTER;
00445               break;
00446 
00447           case KEY_0_PAD:
00448           case KEY_1_PAD:
00449           case KEY_2_PAD:
00450           case KEY_3_PAD:
00451           case KEY_4_PAD:
00452           case KEY_5_PAD:
00453           case KEY_6_PAD:
00454           case KEY_7_PAD:
00455           case KEY_8_PAD:
00456           case KEY_9_PAD:
00457           case KEY_SLASH_PAD:
00458           case KEY_MINUS_PAD:
00459           case KEY_PLUS_PAD:
00460               pad = true;
00461               // no brakes! no brakes!
00462 
00463           default:
00464               keysym = unicode;
00465         }
00466 
00467         Key k = Key(keysym);
00468         k.setNumericPad(pad);
00469 
00470         k.setShiftPressed(key_shifts & KB_SHIFT_FLAG);
00471         k.setAltPressed(key_shifts & KB_ALT_FLAG);
00472         k.setControlPressed(key_shifts & KB_CTRL_FLAG);
00473 #ifdef KB_COMMAND_FLAG
00474         k.setMetaPressed(key_shifts & (KB_COMMAND_FLAG |
00475                                        KB_LWIN_FLAG |
00476                                        KB_RWIN_FLAG));
00477 #else
00478         k.setMetaPressed(key_shifts & (KB_LWIN_FLAG |
00479                                        KB_RWIN_FLAG));
00480 #endif
00481 
00482         return k;
00483 
00484         //Now, THAT was fun to code! =D =D =D
00485     }
00486 }

Generated on Sat Jul 29 19:38:48 2006 for Guichan by  doxygen 1.4.7