ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

touchcontrols.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #if defined(__ANDROID__)
00024 
00025 #include "common/fs.h"
00026 #include "common/stream.h"
00027 #include "common/archive.h"
00028 #include "image/tga.h"
00029 
00030 #include "backends/platform/android/events.h"
00031 #include "backends/platform/android/texture.h"
00032 #include "backends/platform/android/touchcontrols.h"
00033 
00034 static Common::Rect clipFor(const Common::KeyCode &cs) {
00035     switch (cs) {
00036     case Common::KEYCODE_UP:
00037     case Common::KEYCODE_PAGEUP:
00038         return Common::Rect(0, 0, 128, 128);
00039     case Common::KEYCODE_RIGHT:
00040         return Common::Rect(128, 0, 256, 128);
00041     case Common::KEYCODE_DOWN:
00042     case Common::KEYCODE_PAGEDOWN:
00043         return Common::Rect(256, 0, 384, 128);
00044     case Common::KEYCODE_LEFT:
00045         return Common::Rect(384, 0, 512, 128);
00046     case Common::KEYCODE_i:
00047         return Common::Rect(0, 128, 128, 256);
00048     case Common::KEYCODE_p:
00049         return Common::Rect(128, 128, 256, 256);
00050     case Common::KEYCODE_u:
00051         return Common::Rect(256, 128, 384, 256);
00052     case Common::KEYCODE_e:
00053     case Common::KEYCODE_l:
00054         return Common::Rect(384, 128, 512, 256);
00055     default: // unreachable
00056         return Common::Rect(0, 0, 1, 1);
00057     }
00058 }
00059 
00060 TouchControls::TouchControls() :
00061     _arrows_texture(NULL),
00062     _joystickPressing(Common::KEYCODE_INVALID),
00063     _centerPressing(Common::KEYCODE_INVALID),
00064     _rightPressing(Common::KEYCODE_INVALID),
00065     _key_receiver(NULL),
00066     _screen_width(0),
00067     _screen_height(0) {
00068 
00069     for (int p = 0; p < kNumPointers; ++p) {
00070         Pointer &pp = _pointers[p];
00071         pp.currentX = pp.currentY = pp.startX = pp.startY = 0;
00072         pp.active = false;
00073         pp.function = kTouchAreaNone;
00074     }
00075 
00076     for (int i = 0; i < 4; ++i)
00077         _activePointers[i] = -1;
00078 }
00079 
00080 TouchControls::~TouchControls() {
00081     if (_arrows_texture) {
00082         delete _arrows_texture;
00083         _arrows_texture = 0;
00084     }
00085 }
00086 
00087 uint16 TouchControls::getTouchArea(int x, int y) {
00088     float xPercent = float(x) / _screen_width;
00089 
00090     if (xPercent < 0.3)
00091         return kTouchAreaJoystick;
00092     else if (xPercent < 0.8)
00093         return kTouchAreaCenter;
00094     else
00095         return kTouchAreaRight;
00096 }
00097 
00098 static Common::KeyCode determineKey(int dX, int dY, Common::KeyCode def = Common::KEYCODE_INVALID) {
00099     if (dX * dX + dY * dY < 50 * 50)
00100         return def;
00101 
00102     if (dY > abs(dX))
00103         return Common::KEYCODE_DOWN;
00104     if (dX > abs(dY))
00105         return Common::KEYCODE_RIGHT;
00106     if (-dY > abs(dX))
00107         return Common::KEYCODE_UP;
00108     if (-dX > abs(dY))
00109         return Common::KEYCODE_LEFT;
00110 
00111     return Common::KEYCODE_INVALID;
00112 }
00113 
00114 static GLES8888Texture *loadBuiltinTexture(const char *filename) {
00115     Common::ArchiveMemberPtr member = SearchMan.getMember(filename);
00116     Common::SeekableReadStream *str = member->createReadStream();
00117     Image::TGADecoder dec;
00118     dec.loadStream(*str);
00119     const void *pixels = dec.getSurface()->getPixels();
00120 
00121     GLES8888Texture *ret = new GLES8888Texture();
00122     uint16 w = dec.getSurface()->w;
00123     uint16 h = dec.getSurface()->h;
00124     uint16 pitch = dec.getSurface()->pitch;
00125     ret->allocBuffer(w, h);
00126     ret->updateBuffer(0, 0, w, h, pixels, pitch);
00127 
00128     delete str;
00129     return ret;
00130 }
00131 
00132 void TouchControls::init(KeyReceiver *kr, int width, int height) {
00133     _arrows_texture = loadBuiltinTexture("arrows.tga");
00134     _screen_width = width;
00135     _screen_height = height;
00136     _key_receiver = kr;
00137 }
00138 
00139 const uint _numRightKeycodes = 4;
00140 const Common::KeyCode _rightKeycodes[] = { Common::KEYCODE_i, Common::KEYCODE_p, Common::KEYCODE_u, Common::KEYCODE_e };
00141 
00142 void TouchControls::draw() {
00143     if (_joystickPressing != Common::KEYCODE_INVALID) {
00144         Common::Rect clip = clipFor(_joystickPressing);
00145         _arrows_texture->drawTexture(2 * _screen_width / 10, _screen_height / 2, 64, 64, clip);
00146     }
00147 
00148     if (_centerPressing != Common::KEYCODE_INVALID) {
00149         Common::Rect clip = clipFor(_centerPressing);
00150         _arrows_texture->drawTexture(_screen_width / 2, _screen_height / 2, 64, 64, clip);
00151     }
00152 
00153     if (_rightPressing != Common::KEYCODE_INVALID) {
00154         Common::Rect clip = clipFor(_rightPressing);
00155         _arrows_texture->drawTexture( 8 * _screen_width / 10, _screen_height / 2, 64, 64, clip);
00156     }
00157 }
00158 
00159 void TouchControls::update(int ptr, int action, int x, int y) {
00160     if (ptr > kNumPointers)
00161         return;
00162 
00163     TouchArea touchArea = (TouchArea) getTouchArea(x, y);
00164 
00165     switch (action) {
00166     case JACTION_POINTER_DOWN:
00167     case JACTION_DOWN:
00168         if (touchArea > kTouchAreaNone && -1 == pointerFor(touchArea)) {
00169             pointerFor(touchArea) = ptr;
00170             _pointers[ptr].active = true;
00171             _pointers[ptr].function = touchArea;
00172             _pointers[ptr].startX = _pointers[ptr].currentX = x;
00173             _pointers[ptr].startY = _pointers[ptr].currentY = y;
00174             // fall through to move case to initialize _{joy,center,right}Pressing
00175         } else {
00176             return;
00177         }
00178 
00179     case JACTION_MOVE: {
00180         _pointers[ptr].currentX = x;
00181         _pointers[ptr].currentY = y;
00182         int dX = x - _pointers[ptr].startX;
00183         int dY = y - _pointers[ptr].startY;
00184 
00185         switch (_pointers[ptr].function) {
00186         case kTouchAreaJoystick: {
00187             Common::KeyCode newPressing = determineKey(dX, dY);
00188             if (newPressing != _joystickPressing) {
00189                 _key_receiver->keyPress(_joystickPressing, KeyReceiver::UP);
00190                 _key_receiver->keyPress(newPressing, KeyReceiver::DOWN);
00191                 _joystickPressing = newPressing;
00192             } else if(abs(dY) > 150) {
00193                _key_receiver->keyPress(Common::KEYCODE_LSHIFT, KeyReceiver::DOWN);
00194             } else if(abs(dY) <= 150){
00195                _key_receiver->keyPress(Common::KEYCODE_LSHIFT, KeyReceiver::UP);
00196             }
00197             return;
00198         }
00199 
00200         case kTouchAreaCenter:
00201             _centerPressing = determineKey(dX, dY, Common::KEYCODE_RETURN);
00202             return;
00203 
00204         case kTouchAreaRight:
00205             _rightPressing = determineKey(dX, dY, Common::KEYCODE_i);
00206             switch (_rightPressing) {
00207             case Common::KEYCODE_LEFT:
00208             case Common::KEYCODE_RIGHT:
00209                 _rightPressing = _rightKeycodes[abs(dX / 100) % _numRightKeycodes];
00210                 break;
00211 
00212             case Common::KEYCODE_UP:
00213                 _rightPressing = Common::KEYCODE_PAGEUP;
00214                 break;
00215 
00216             case Common::KEYCODE_DOWN:
00217                 _rightPressing = Common::KEYCODE_PAGEDOWN;
00218                 break;
00219 
00220             default:
00221                 break;
00222             }
00223 
00224         default:
00225             return;
00226         }
00227         return;
00228     }
00229 
00230     case JACTION_UP:
00231     case JACTION_POINTER_UP: {
00232         switch (_pointers[ptr].function) {
00233         case kTouchAreaJoystick:
00234             pointerFor(kTouchAreaJoystick) = -1;
00235             if (_joystickPressing != Common::KEYCODE_INVALID) {
00236                 _key_receiver->keyPress(_joystickPressing, KeyReceiver::UP);
00237                 _joystickPressing = Common::KEYCODE_INVALID;
00238                 _key_receiver->keyPress(Common::KEYCODE_LSHIFT, KeyReceiver::UP);
00239             }
00240             break;
00241 
00242         case kTouchAreaCenter:
00243             pointerFor(kTouchAreaCenter) = -1;
00244             _key_receiver->keyPress(_centerPressing);
00245             _centerPressing = Common::KEYCODE_INVALID;
00246             break;
00247 
00248         case kTouchAreaRight:
00249             pointerFor(kTouchAreaRight) = -1;
00250             _key_receiver->keyPress(_rightPressing);
00251             _rightPressing = Common::KEYCODE_INVALID;
00252             break;
00253 
00254         case kTouchAreaNone:
00255         default:
00256             break;
00257         }
00258         _pointers[ptr].active = false;
00259         _pointers[ptr].function = kTouchAreaNone;
00260         return;
00261     }
00262     }
00263 }
00264 
00265 int &TouchControls::pointerFor(TouchArea ta) {
00266     return _activePointers[ta - kTouchAreaNone];
00267 }
00268 
00269 #endif


Generated on Sat Feb 16 2019 05:01:09 for ResidualVM by doxygen 1.7.1
curved edge   curved edge