yusei sugimoeo / Mbed OS controllerForMbed_test_Re
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Controller.cpp Source File

Controller.cpp

00001 #include "Controller.h"
00002 
00003 Controller::Controller(PinName tx, PinName rx, int baudrate) : serial(tx, rx, baudrate)
00004 {
00005     conData.ButtonState = 0;
00006     conData.RJoyX = 127, conData.RJoyY = 127, conData.LJoyX = 127, conData.LJoyY = 127;
00007 
00008     lastButtonState = 0;
00009 
00010     comCheck = false;
00011     conAvailable = false;
00012     time_out_ms = -1;
00013 }
00014 
00015 void Controller::init(int _time_out_ms, int _int_time_ms)
00016 {
00017     time_out_ms = _time_out_ms;
00018     int_time_ms = _int_time_ms;
00019     //serial.attach(this, &Controller::update, Serial::RxIrq);
00020     //timer.start();
00021 }
00022 
00023 bool Controller::update()
00024 {
00025     //receptionTime = timer.read();
00026     static int count_ms = time_out_ms, pre_count_ms = 0; //受信時刻と前回の受信時刻
00027     count_ms += int_time_ms;
00028 
00029     char receive_data[10];
00030     unsigned int loop_count = 0, checksum = 0x00;
00031     comCheck = false;
00032 
00033 #if CON_TYPE == CON_ADACHI // 安達君開発のコントローラを使う場合の処理(どのコントローラを使うかはdefine.hで設定)
00034     while (loop_count < 10 && serial.readable()) {
00035         if (serial_recieve() == '\n') {
00036             for (int i = 0; i < 8; i++)
00037                 receive_data[i] = serial_recieve();
00038             for (int i = 0; i < 8; i++)
00039                 receive_data[i] -= 0x20;
00040             for (int i = 0; i < 7; i++)
00041                 checksum ^= receive_data[i];
00042 
00043             if (receive_data[7] == checksum & 0xFF) {
00044                 comCheck = true;
00045 
00046                 //pre_conData.ButtonState = conData.ButtonState;
00047                 lastButtonState = ((receive_data[0] & 0x3F) << 2) | ((receive_data[1] & 0x30) >> 4);
00048                 conData.ButtonState |= lastButtonState;
00049 
00050                 conData.RJoyX = ((receive_data[1] & 0x0F) << 4) | ((receive_data[2] & 0x3C) >> 2);
00051                 conData.RJoyY = ((receive_data[2] & 0x03) << 6) | (receive_data[3] & 0x3F);
00052                 conData.LJoyX = ((receive_data[4] & 0x3F) << 2) | ((receive_data[5] & 0x30) >> 4);
00053                 conData.LJoyY = ((receive_data[5] & 0x0F) << 4) | (receive_data[6] & 0x0F);
00054 
00055                 break;
00056             }
00057 
00058             pre_count_ms = count_ms; //受信時間の更新
00059         }
00060         loop_count++;
00061     }
00062 #elif CON_TYPE == CON_ELECOM // ELECOMのコントローラを使う場合の処理(どのコントローラを使うかはdefine.hで設定)
00063     // コントローラデータを取得する部分
00064     static int recv_num = 0;
00065     char c;
00066     while (serial.readable()) {
00067         c = serial.getc();
00068         if (c == '\n') {
00069             if (recv_num == 10) {
00070                 // チェックサムは無く,9個受信したら値を格納
00071                 for (int i = 0; i < 9; i++)
00072                     checksum += (unsigned int)(receive_data[i] - 0x20); // チェックサムの計算
00073                 if ((checksum & 0x3F) == (receive_data[9] - 0x20)) {
00074                     // チェックサムの計算が合っていた場合のみ値を格納
00075                     comCheck = true;
00076 
00077                     //conData.ButtonState = 0;
00078                     conData.LJoyX = 0, conData.LJoyY = 0, conData.RJoyX = 0, conData.RJoyY = 0;
00079                     lastButtonState = (unsigned int)(receive_data[0] - 0x20);
00080                     lastButtonState |= (unsigned int)(receive_data[1] - 0x20) << 6;
00081                     lastButtonState |= (unsigned int)(receive_data[2] - 0x20) << 12;
00082 
00083                     conData.LJoyX |= (unsigned int)(receive_data[3] - 0x20);
00084                     conData.LJoyX |= (unsigned int)((receive_data[4] - 0x20) & 0x03) << 6;
00085                     conData.LJoyX = abs(conData.LJoyX - 0xFF);
00086 
00087                     conData.LJoyY |= (unsigned int)((receive_data[4] - 0x20) & 0x3C) >> 2;
00088                     conData.LJoyY |= (unsigned int)((receive_data[5] - 0x20) & 0x0F) << 4;
00089                     conData.LJoyY = abs(conData.LJoyY - 0xFF);
00090 
00091                     conData.RJoyX |= (unsigned int)((receive_data[5] - 0x20) & 0x30) >> 4;
00092                     conData.RJoyX |= (unsigned int)((receive_data[6] - 0x20) & 0x3F) << 2;
00093                     conData.RJoyX = abs(conData.RJoyX - 0xFF);
00094 
00095                     conData.RJoyY |= (unsigned int)(receive_data[7] - 0x20);
00096                     conData.RJoyY |= (unsigned int)((receive_data[8] - 0x20) & 0x03) << 6;
00097                     conData.RJoyY = abs(conData.RJoyY - 0xFF);
00098 
00099                     int buttonPushNum = 0;
00100                     for (int i = 0; i < 16; i++) {
00101                         buttonPushNum += (conData.ButtonState >> i) & 0x0001;
00102                     }
00103                     if (buttonPushNum > 5) {
00104                         //conData.ButtonState = pre_conData.ButtonState;
00105                         comCheck = false;
00106                     } else {
00107                         conData.ButtonState |= lastButtonState;
00108                     }
00109 
00110                     pre_count_ms = count_ms; //受信時間の更新
00111                 }
00112             }
00113             recv_num = 0;
00114         } else {
00115             receive_data[recv_num] = c;
00116             recv_num++;
00117         }
00118     }
00119 #elif CON_TYPE == CON_DS4    // DualShock4を使う場合の処理(どのコントローラを使うかはdefine.hで設定)
00120     // コントローラデータを取得する部分
00121     static int recv_num = 0;
00122     char c;
00123     while (serial.readable()) {
00124         c = serial.getc();
00125         //printf("%x ",c);
00126 
00127         if (c == '\n') {
00128             //printf("\t");
00129             if (recv_num == 10) {
00130                 // データ数はチェックサム含めて10個(0~9)
00131                 checksum = 0;
00132                 //for(int i = 0; i<10; i++)printf("%+x ",receive_data[i]);
00133                 for (int i = 0; i < 9; i++)checksum ^= (unsigned int)(receive_data[i] - 0x20); // チェックサムの計算
00134                 //printf(" %+x\n",checksum);
00135                 if ((checksum & 0x3F) == (receive_data[9] - 0x20)) {
00136                     // チェックサムの計算が合っていた場合のみ値を格納
00137                     //printf("checksum ok \n");
00138                     comCheck = true;
00139 
00140                     //conData.ButtonState = 0;
00141                     conData.LJoyX = 0, conData.LJoyY = 0, conData.RJoyX = 0, conData.RJoyY = 0;
00142                     lastButtonState = (unsigned int)(receive_data[0] - 0x20) & 0x3F;
00143                     lastButtonState |= (unsigned int)((receive_data[1] - 0x20) & 0x3F) << 6;
00144                     lastButtonState |= (unsigned int)((receive_data[2] - 0x20) & 0x0F) << 12;
00145 
00146                     conData.LJoyX |= (unsigned int)(receive_data[3] - 0x20) & 0x3F;
00147                     conData.LJoyX |= (unsigned int)((receive_data[4] - 0x20) & 0x03) << 6;
00148                     conData.LJoyX = abs(conData.LJoyX - 0xFF);
00149 
00150                     conData.LJoyY |= (unsigned int)((receive_data[4] - 0x20) & 0x3C) >> 2;
00151                     conData.LJoyY |= (unsigned int)((receive_data[5] - 0x20) & 0x0F) << 4;
00152                     conData.LJoyY = abs(conData.LJoyY - 0xFF);
00153 
00154                     conData.RJoyX |= (unsigned int)((receive_data[5] - 0x20) & 0x30) >> 4;
00155                     conData.RJoyX |= (unsigned int)((receive_data[6] - 0x20) & 0x3F) << 2;
00156                     conData.RJoyX = abs(conData.RJoyX - 0xFF);
00157 
00158                     conData.RJoyY |= (unsigned int)(receive_data[7] - 0x20) & 0x3F;
00159                     conData.RJoyY |= (unsigned int)((receive_data[8] - 0x20) & 0x03) << 6;
00160                     conData.RJoyY = abs(conData.RJoyY - 0xFF);
00161 
00162                     // 通信ミスであり得ない数のボタン数押されていた場合に無視する処理
00163                     int buttonPushNum = 0;
00164                     for (int i = 0; i < 16; i++) {
00165                         buttonPushNum += (lastButtonState >> i) & 0x0001;
00166                     }
00167                     if (buttonPushNum > 5) {
00168                         //conData.ButtonState = pre_conData.ButtonState;
00169                         comCheck = false;
00170                     } else {
00171                         conData.ButtonState = lastButtonState & 0xFFFF;
00172                     }
00173 
00174                     pre_count_ms = count_ms; //受信時間の更新
00175                 }
00176             }
00177             recv_num = 0;
00178         } else {
00179             receive_data[recv_num] = c;
00180             recv_num++;
00181         }
00182         //printf("con\n");
00183     }
00184         //printf("nuketa\n");
00185 
00186 #endif
00187 //printf("g1");
00188     if(!(time_out_ms == -1)) conAvailable = (time_out_ms > (count_ms - pre_count_ms)); //タイムアウトとインターバルの比較
00189     else conAvailable = true;
00190     //printf("g2");
00191     if(count_ms > time_out_ms * 1000) count_ms = time_out_ms; //オーバーフロー対策
00192 //printf("h");
00193     return comCheck;
00194 }
00195 
00196 bool Controller::getComCheck(void)
00197 {
00198     return comCheck;
00199 }
00200 
00201 bool Controller::available(void)
00202 {
00203     return conAvailable;
00204 }
00205 
00206 bool Controller::clearBuffer(void)
00207 {
00208     if(serial.readable()) serial.getc();
00209     return serial.readable();
00210 }
00211 
00212 bool Controller::rate(void)
00213 {
00214     bool _ButtunState = false, _RX = false, _RY = false, _LX = false, _LY = false ;
00215     if(comCheck) {
00216         _ButtunState = (conData.ButtonState != 0)? true : false;
00217         _RX = (conData.RJoyX != 128)? true : false;
00218         _RY = (conData.RJoyY != 128)? true : false;
00219         _LX = (conData.LJoyX != 128)? true : false;
00220         _LY = (conData.LJoyY != 128)? true : false;
00221     }
00222     //printf("%d,%d,%d,%d,%d\n",_ButtunState,_RX,_RY,_LX,_LY);
00223     return _ButtunState | _RX | _RY | _LX | _LY;
00224 }
00225 
00226 bool Controller::readButton_bin(unsigned int ButtonNum)
00227 {
00228     //放しているときは0,押しているときは1
00229     return ((conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1))) ? true : false;
00230 }
00231 
00232 int Controller::readButton(unsigned int ButtonNum)
00233 {
00234     //放しているときは0,押しているときは1,押した瞬間は2,放した瞬間は-1
00235     int result = 0;
00236     if ((conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1)))
00237         result += 2;
00238     if ((pre_conData.ButtonState & (0x0001 << (ButtonNum - 1))) == (0x0001 << (ButtonNum - 1)))
00239         result -= 1;
00240     return result;
00241 }
00242 
00243 unsigned int Controller::getButtonState()
00244 {
00245     return conData.ButtonState;
00246 }
00247 
00248 void Controller::clearButtonState()
00249 {
00250     pre_conData.ButtonState = conData.ButtonState;
00251 }
00252 
00253 ControllerData Controller::getConData()
00254 {
00255     return conData;
00256 }
00257 
00258 double Controller::readJoyRX()
00259 {
00260     if (conData.RJoyX == 127)
00261         return 0;
00262     return ((double)conData.RJoyX - 127.5) / 127.5;
00263 }
00264 
00265 double Controller::readJoyRY()
00266 {
00267     if (conData.RJoyY == 127)
00268         return 0;
00269     return ((double)conData.RJoyY - 127.5) / 127.5;
00270 }
00271 
00272 double Controller::readJoyLX()
00273 {
00274     if (conData.LJoyX == 127)
00275         return 0;
00276     return ((double)conData.LJoyX - 127.5) / 127.5;
00277 }
00278 
00279 double Controller::readJoyLY()
00280 {
00281     if (conData.LJoyY == 127)
00282         return 0;
00283     return ((double)conData.LJoyY - 127.5) / 127.5;
00284 }
00285 
00286 uint8_t Controller::readJoyRXbyte()
00287 {
00288     return conData.RJoyX;
00289 }
00290 
00291 uint8_t Controller::readJoyRYbyte()
00292 {
00293     return conData.RJoyY;
00294 }
00295 
00296 uint8_t Controller::readJoyLXbyte()
00297 {
00298     return conData.LJoyX;
00299 }
00300 
00301 uint8_t Controller::readJoyLYbyte()
00302 {
00303     return conData.LJoyY;
00304 }
00305 
00306 unsigned int Controller::getButtonFlagRise()
00307 {
00308     // 立ち上がり,立下りのフラッギング処理 (フラグクリアは別関数で)
00309     unsigned int buttonFlagRise = 0;
00310     if (pre_conData.ButtonState != conData.ButtonState) {
00311         for (int i = 0; i < 16; i++) {
00312             int mask = 0x01 << i;
00313             if ((conData.ButtonState & mask) != (pre_conData.ButtonState & mask)) {
00314                 if ((conData.ButtonState & mask) == mask)
00315                     buttonFlagRise |= (conData.ButtonState & mask);
00316             }
00317         }
00318     }
00319     return buttonFlagRise;
00320 }
00321 
00322 unsigned int Controller::getButtonFlagFall()
00323 {
00324     unsigned int buttonFlagFall = 0;
00325     if (pre_conData.ButtonState != conData.ButtonState) {
00326         for (int i = 0; i < 16; i++) {
00327             int mask = 0x01 << i;
00328             if ((conData.ButtonState & mask) != (pre_conData.ButtonState & mask)) {
00329                 if ((pre_conData.ButtonState & mask) == mask)
00330                     buttonFlagFall |= (pre_conData.ButtonState & mask);
00331             }
00332         }
00333     }
00334     return buttonFlagFall;
00335 }