mv logo.png icon.png
[qzeecontrol] / btconnector.cpp
1 /*
2  *  Copyright 2012 Ruediger Gad
3  *
4  *  This file is part of QZeeControl.
5  *
6  *  QZeeControl is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  QZeeControl is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with QZeeControl.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "btconnector.h"
21
22 BtConnector::BtConnector(QObject *parent)
23     : QObject(parent){
24     _threshold = 50;
25
26     _up = false;
27     _down = false;
28     _left = false;
29     _right = false;
30
31     _a = false;
32     _b = false;
33     _c = false;
34     _d = false;
35
36     _x = 0;
37     _y = 0;
38     oldButtonMap = 0;
39 }
40
41 void BtConnector::connect(QString address, int port){
42     qDebug("Trying to connect to: %s--%d", address.toUtf8().constData(), port);
43
44     if(socket)
45         delete socket;
46
47     socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket);
48     QObject::connect(socket, SIGNAL(connected()), this, SIGNAL(connected()));
49     QObject::connect(socket, SIGNAL(disconnected()), this, SIGNAL(disconnected()));
50     QObject::connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SIGNAL(error(QBluetoothSocket::SocketError)));
51
52     qDebug("Connecting...");
53     socket->connectToService(QBluetoothAddress(address), port);
54     qDebug("Connected.");
55
56     QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
57 }
58
59 void BtConnector::disconnect(){
60     if(!socket)
61         return;
62
63     if(socket->isOpen())
64         socket->close();
65
66     delete socket;
67     socket = 0;
68
69     /*
70      * Explicitly set D to false in case the remote was shut off
71      * using the power key, which equals the 'D' key.
72      * Well, good intention but doesn't seem to work.
73      */
74     setD(false);
75 }
76
77 void BtConnector::readData(){
78 //        qDebug("readData...");
79     QByteArray data = socket->readAll();
80 //        qDebug("read %d bytes.", data.size());
81
82 /*
83     for(int i=0; i < data.size(); i++){
84         qDebug("%d: %d", i, ((signed char)data.at(i)));
85     }
86 */
87
88     /*
89      * Actually it seems like that the first three bytes are used for
90      * identifying the "type" of data sent. However, for now using the
91      * first seems to suffice.
92      */
93     if(data.at(0) == 5){
94         /*
95          * Joystick movement
96          *
97          * X-Axis: positive values -> right, negative values -> left
98          * Y-Axis: positive values -> down, negative values -> up
99          */
100
101         setX((int)(signed char) data.at(4));
102         setY((int)(signed char) data.at(5));
103
104         emit(stickMoved(_x, _y));
105
106         /*
107          * Emulate a digital joystick.
108          */
109         if(_up && (_y > -threshold())){
110             setUp(false);
111         }else if(!_up && (_y < -threshold())){
112             setUp(true);
113         }
114
115         if(_down && (_y < threshold())){
116             setDown(false);
117         }else if(!_down && (_y > threshold())){
118             setDown(true);
119         }
120
121         if(_left && (_x > -threshold())){
122             setLeft(false);
123         }else if(!_left && (_x < -threshold())){
124             setLeft(true);
125         }
126
127         if(_right && (_x < threshold())){
128             setRight(false);
129         }else if(!_right && (_x > threshold())){
130             setRight(true);
131         }
132     }else if(data.at(0) == 8){ 
133         /*
134          * Button presses
135          *
136          * A -> 0, B -> 1, C -> 2, D ->3
137          * At index 3 to 6 (inclusive)
138          */
139
140         char buttonMap = 0;
141
142         for(int i = 3; i <= 6; i++){
143             for(int b = 0; b <= 3; b++){
144                 if(data.at(i) == b){
145                     buttonMap ^= (1 << b);
146                 }
147             }
148         }
149
150 //            qDebug("Button map: %d", buttonMap);
151         emit(buttonsChanged(buttonMap & 0x01, buttonMap & 0x02, buttonMap & 0x04, buttonMap & 0x08));
152
153         for(int i = 0; i <= 3; i++){
154             if(((buttonMap | oldButtonMap) & (1 << i)) > 0){
155                 bool val = (buttonMap & (1 << i)) > 0;
156                 switch (i){
157                 case 0:
158                     setA(val);
159                     break;
160                 case 1:
161                     setB(val);
162                     break;
163                 case 2:
164                     setC(val);
165                     break;
166                 case 3:
167                     setD(val);
168                     break;
169                 }
170             }
171         }
172
173         oldButtonMap = buttonMap;
174     }
175 }