Use a Wii classic controller with Pokitto
Fork of HelloWorld by
main.cpp@8:4f86dcba69b9, 2018-03-21 (annotated)
- Committer:
- spinal
- Date:
- Wed Mar 21 16:00:24 2018 +0000
- Revision:
- 8:4f86dcba69b9
- Parent:
- 5:c4a0391b43ac
Using a Wii classic controller with Pokitto
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Pokitto | 0:2d2a3994d55d | 1 | #include "Pokitto.h" |
spinal | 8:4f86dcba69b9 | 2 | #include "gfx.h" |
spinal | 8:4f86dcba69b9 | 3 | |
spinal | 8:4f86dcba69b9 | 4 | #define ADDRESS 0xA4 // 0x52 << 1 |
spinal | 8:4f86dcba69b9 | 5 | |
spinal | 8:4f86dcba69b9 | 6 | Pokitto::Core game; |
spinal | 8:4f86dcba69b9 | 7 | I2C i2c(P0_5, P0_4); // sda, scl |
spinal | 8:4f86dcba69b9 | 8 | |
spinal | 8:4f86dcba69b9 | 9 | |
spinal | 8:4f86dcba69b9 | 10 | unsigned char dataFormat; |
spinal | 8:4f86dcba69b9 | 11 | unsigned char controllerType[6]; |
spinal | 8:4f86dcba69b9 | 12 | bool connected, old_connected; |
spinal | 8:4f86dcba69b9 | 13 | uint8_t _data[21]; |
spinal | 8:4f86dcba69b9 | 14 | int w_LX, w_RX, w_LY, w_RY, w_LT, w_RT, w_AX, w_AY, w_AZ; |
spinal | 8:4f86dcba69b9 | 15 | bool w_RIGHT, w_DOWN, w_L, w_MINUS, w_HOME, w_PLUS, w_R, w_LZ, w_B, w_Y, w_A, w_X, w_RZ, w_LEFT, w_UP; |
spinal | 8:4f86dcba69b9 | 16 | int wiiError,oldError; |
spinal | 8:4f86dcba69b9 | 17 | int controlType=-1; |
spinal | 8:4f86dcba69b9 | 18 | |
spinal | 8:4f86dcba69b9 | 19 | unsigned char conTypes[3][6]={ |
spinal | 8:4f86dcba69b9 | 20 | {0x00,0x00,0xA4,0x20,0x00,0x00}, // 0 = Nunchuck |
spinal | 8:4f86dcba69b9 | 21 | {0x00,0x00,0xA4,0x20,0x01,0x01}, // 1 = Classic controller |
spinal | 8:4f86dcba69b9 | 22 | {0x01,0x00,0xA4,0x20,0x01,0x01}, // 2 = Classic controller pro |
spinal | 8:4f86dcba69b9 | 23 | }; |
spinal | 8:4f86dcba69b9 | 24 | char *controller[3] = {"Nunchuck","Classic controller","Classic controller pro"}; |
spinal | 8:4f86dcba69b9 | 25 | void init_classic(); |
spinal | 8:4f86dcba69b9 | 26 | |
spinal | 8:4f86dcba69b9 | 27 | |
spinal | 8:4f86dcba69b9 | 28 | |
spinal | 8:4f86dcba69b9 | 29 | |
spinal | 8:4f86dcba69b9 | 30 | void checkController(){ |
spinal | 8:4f86dcba69b9 | 31 | //game.display.clear(); |
spinal | 8:4f86dcba69b9 | 32 | char tempText[20]; |
spinal | 8:4f86dcba69b9 | 33 | game.display.setCursor(0,77); |
spinal | 8:4f86dcba69b9 | 34 | controlType=-1; |
spinal | 8:4f86dcba69b9 | 35 | for(char s=0; s<3; s++){ |
spinal | 8:4f86dcba69b9 | 36 | unsigned char tempCount=0; |
spinal | 8:4f86dcba69b9 | 37 | for(char t=0; t<6; t++){ |
spinal | 8:4f86dcba69b9 | 38 | // check controller against known models. 5th byte ignored, as it is changed by init process |
spinal | 8:4f86dcba69b9 | 39 | if(t!=4){ if(controllerType[t] == conTypes[s][t]){ tempCount++; } } |
spinal | 8:4f86dcba69b9 | 40 | } |
spinal | 8:4f86dcba69b9 | 41 | if(tempCount==5){controlType=s;} |
spinal | 8:4f86dcba69b9 | 42 | } |
spinal | 8:4f86dcba69b9 | 43 | //Serial.print("Controller:"); |
spinal | 8:4f86dcba69b9 | 44 | if(controlType<0){ |
spinal | 8:4f86dcba69b9 | 45 | game.display.print("Not Connected"); |
spinal | 8:4f86dcba69b9 | 46 | // Serial.println("Not Connected"); |
spinal | 8:4f86dcba69b9 | 47 | }else{ |
spinal | 8:4f86dcba69b9 | 48 | // Serial.println(controller[controlType]); |
spinal | 8:4f86dcba69b9 | 49 | sprintf(tempText,"%s\n",controller[controlType]); |
spinal | 8:4f86dcba69b9 | 50 | game.display.print(tempText); |
spinal | 8:4f86dcba69b9 | 51 | } |
spinal | 8:4f86dcba69b9 | 52 | |
spinal | 8:4f86dcba69b9 | 53 | sprintf(tempText,"DataFormat = %d\n",dataFormat); |
spinal | 8:4f86dcba69b9 | 54 | game.display.print(tempText); |
spinal | 8:4f86dcba69b9 | 55 | |
spinal | 8:4f86dcba69b9 | 56 | } |
spinal | 8:4f86dcba69b9 | 57 | |
spinal | 8:4f86dcba69b9 | 58 | void updateClassic() |
spinal | 8:4f86dcba69b9 | 59 | { |
spinal | 8:4f86dcba69b9 | 60 | i2c.write(ADDRESS, (const char*)0x00, 1); |
spinal | 8:4f86dcba69b9 | 61 | // wait |
spinal | 8:4f86dcba69b9 | 62 | wait_ms(10); |
spinal | 8:4f86dcba69b9 | 63 | if(i2c.read(ADDRESS, (char*)_data, 8)){ |
spinal | 8:4f86dcba69b9 | 64 | connected = 0; |
spinal | 8:4f86dcba69b9 | 65 | }else{ |
spinal | 8:4f86dcba69b9 | 66 | connected = 1; |
Pokitto | 0:2d2a3994d55d | 67 | |
spinal | 8:4f86dcba69b9 | 68 | if(controlType == 0){ |
spinal | 8:4f86dcba69b9 | 69 | // nunchuck |
spinal | 8:4f86dcba69b9 | 70 | // nunchuck only does format 1 |
spinal | 8:4f86dcba69b9 | 71 | w_LX = _data[0]; |
spinal | 8:4f86dcba69b9 | 72 | w_LY = _data[1]; |
spinal | 8:4f86dcba69b9 | 73 | w_AX = (_data[2] << 2) | ((_data[5] >> 2) & 3); |
spinal | 8:4f86dcba69b9 | 74 | w_AY = (_data[3] << 2) | ((_data[5] >> 4) & 3); |
spinal | 8:4f86dcba69b9 | 75 | w_AZ = (_data[4] << 2) | ((_data[5] >> 6) & 3); |
spinal | 8:4f86dcba69b9 | 76 | w_LZ = !((_data[5] >> 0) & 1); |
spinal | 8:4f86dcba69b9 | 77 | w_L = !((_data[5] >> 1) & 1); |
spinal | 8:4f86dcba69b9 | 78 | } |
spinal | 8:4f86dcba69b9 | 79 | if(controlType == 1 || controlType == 2){ |
spinal | 8:4f86dcba69b9 | 80 | // classic controller or classic controller pro |
spinal | 8:4f86dcba69b9 | 81 | w_LX = _data[0]; |
spinal | 8:4f86dcba69b9 | 82 | w_RX = _data[1]; |
spinal | 8:4f86dcba69b9 | 83 | w_LY = _data[2]; |
spinal | 8:4f86dcba69b9 | 84 | w_RY = _data[3]; |
spinal | 8:4f86dcba69b9 | 85 | w_LT = _data[4]; |
spinal | 8:4f86dcba69b9 | 86 | w_RT = _data[5]; |
spinal | 8:4f86dcba69b9 | 87 | w_RIGHT = _data[6]&B10000000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 88 | w_DOWN = _data[6]&B01000000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 89 | w_L = _data[6]&B00100000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 90 | w_MINUS = _data[6]&B00010000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 91 | w_HOME = _data[6]&B00001000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 92 | w_PLUS = _data[6]&B00000100 ? 0:1; |
spinal | 8:4f86dcba69b9 | 93 | w_R = _data[6]&B00000010 ? 0:1; |
spinal | 8:4f86dcba69b9 | 94 | w_LZ = _data[7]&B10000000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 95 | w_B = _data[7]&B01000000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 96 | w_Y = _data[7]&B00100000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 97 | w_A = _data[7]&B00010000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 98 | w_X = _data[7]&B00001000 ? 0:1; |
spinal | 8:4f86dcba69b9 | 99 | w_RZ = _data[7]&B00000100 ? 0:1; |
spinal | 8:4f86dcba69b9 | 100 | w_LEFT = _data[7]&B00000010 ? 0:1; |
spinal | 8:4f86dcba69b9 | 101 | w_UP = _data[7]&B00000001 ? 0:1; |
spinal | 8:4f86dcba69b9 | 102 | } |
spinal | 8:4f86dcba69b9 | 103 | } |
spinal | 8:4f86dcba69b9 | 104 | |
spinal | 8:4f86dcba69b9 | 105 | if(old_connected == 0 && connected == 1){ |
spinal | 8:4f86dcba69b9 | 106 | wait_ms(10); |
spinal | 8:4f86dcba69b9 | 107 | init_classic(); |
spinal | 8:4f86dcba69b9 | 108 | } |
spinal | 8:4f86dcba69b9 | 109 | old_connected = connected; |
spinal | 8:4f86dcba69b9 | 110 | } |
spinal | 8:4f86dcba69b9 | 111 | |
spinal | 8:4f86dcba69b9 | 112 | void init_classic() |
spinal | 8:4f86dcba69b9 | 113 | { |
spinal | 8:4f86dcba69b9 | 114 | i2c.frequency(100000); |
spinal | 8:4f86dcba69b9 | 115 | for(char t=0; t<6; t++){ |
spinal | 8:4f86dcba69b9 | 116 | controllerType[t] = 0x00; |
spinal | 8:4f86dcba69b9 | 117 | } |
spinal | 8:4f86dcba69b9 | 118 | |
spinal | 8:4f86dcba69b9 | 119 | //if(!i2c.write(ADDRESS, NULL, 0)){ |
spinal | 8:4f86dcba69b9 | 120 | |
spinal | 8:4f86dcba69b9 | 121 | char dat[] = {0xF0,0x55,0xFB,0x00,0xFE,0x03}; |
spinal | 8:4f86dcba69b9 | 122 | i2c.write(ADDRESS, &dat[0], 2); |
spinal | 8:4f86dcba69b9 | 123 | i2c.stop(); |
spinal | 8:4f86dcba69b9 | 124 | wait_ms(1); |
spinal | 8:4f86dcba69b9 | 125 | i2c.write(ADDRESS, &dat[2], 2); |
spinal | 8:4f86dcba69b9 | 126 | i2c.stop(); |
spinal | 8:4f86dcba69b9 | 127 | wait_ms(1); |
spinal | 8:4f86dcba69b9 | 128 | i2c.write(ADDRESS, &dat[4], 2); |
spinal | 8:4f86dcba69b9 | 129 | i2c.stop(); |
spinal | 8:4f86dcba69b9 | 130 | wait_ms(1); |
spinal | 8:4f86dcba69b9 | 131 | |
spinal | 8:4f86dcba69b9 | 132 | |
spinal | 8:4f86dcba69b9 | 133 | char cmd[] = {0xFA}; |
spinal | 8:4f86dcba69b9 | 134 | i2c.write(ADDRESS, cmd, sizeof(cmd)); |
spinal | 8:4f86dcba69b9 | 135 | wait_ms(1); |
spinal | 8:4f86dcba69b9 | 136 | if(i2c.read(ADDRESS, (char*)controllerType, 6)){ |
spinal | 8:4f86dcba69b9 | 137 | connected = 0; |
spinal | 8:4f86dcba69b9 | 138 | }else{ |
spinal | 8:4f86dcba69b9 | 139 | connected = 1; |
spinal | 8:4f86dcba69b9 | 140 | } |
spinal | 8:4f86dcba69b9 | 141 | i2c.stop(); |
spinal | 8:4f86dcba69b9 | 142 | |
spinal | 8:4f86dcba69b9 | 143 | dataFormat = controllerType[4]; |
spinal | 8:4f86dcba69b9 | 144 | checkController(); |
spinal | 8:4f86dcba69b9 | 145 | |
spinal | 8:4f86dcba69b9 | 146 | /* |
spinal | 8:4f86dcba69b9 | 147 | Known data types |
spinal | 8:4f86dcba69b9 | 148 | 1. Standard Wii Classic controller |
spinal | 8:4f86dcba69b9 | 149 | 2. ? |
spinal | 8:4f86dcba69b9 | 150 | 3. Classic controller, easier to read, not universally supported by 3rd part controllers |
spinal | 8:4f86dcba69b9 | 151 | 4. Wii Motion Plus |
spinal | 8:4f86dcba69b9 | 152 | */ |
spinal | 8:4f86dcba69b9 | 153 | //update_classic(); |
spinal | 8:4f86dcba69b9 | 154 | // } |
spinal | 8:4f86dcba69b9 | 155 | } |
spinal | 8:4f86dcba69b9 | 156 | |
Pokitto | 0:2d2a3994d55d | 157 | |
Pokitto | 0:2d2a3994d55d | 158 | int main () { |
spinal | 8:4f86dcba69b9 | 159 | game.begin(); |
spinal | 8:4f86dcba69b9 | 160 | |
spinal | 8:4f86dcba69b9 | 161 | game.display.setFont(font3x5); |
spinal | 8:4f86dcba69b9 | 162 | game.display.setInvisibleColor(0); |
spinal | 8:4f86dcba69b9 | 163 | |
spinal | 8:4f86dcba69b9 | 164 | game.display.load565Palette(sprite_pal); |
spinal | 8:4f86dcba69b9 | 165 | |
spinal | 8:4f86dcba69b9 | 166 | while (game.isRunning()) { |
spinal | 8:4f86dcba69b9 | 167 | if (game.update()) { |
spinal | 8:4f86dcba69b9 | 168 | |
spinal | 8:4f86dcba69b9 | 169 | |
spinal | 8:4f86dcba69b9 | 170 | updateClassic(); |
spinal | 8:4f86dcba69b9 | 171 | |
spinal | 8:4f86dcba69b9 | 172 | |
spinal | 8:4f86dcba69b9 | 173 | //game.display.clear(); |
spinal | 8:4f86dcba69b9 | 174 | char tempText[40]; |
spinal | 8:4f86dcba69b9 | 175 | |
spinal | 8:4f86dcba69b9 | 176 | sprintf(tempText,"%03d\n%03d\n%03d\n%03d\n%03d\n%03d\n%03d\n%03d\n%03d\n \n%03d\n", connected, _data[0],_data[1],_data[2],_data[3],_data[4],_data[5],_data[6],_data[7],controllerType[4]); |
spinal | 8:4f86dcba69b9 | 177 | game.display.setCursor(0,0); |
spinal | 8:4f86dcba69b9 | 178 | game.display.print(tempText); |
spinal | 8:4f86dcba69b9 | 179 | sprintf(tempText,"%s\n",controller[controlType]); |
spinal | 8:4f86dcba69b9 | 180 | game.display.setCursor(0,120); |
spinal | 8:4f86dcba69b9 | 181 | game.display.print(tempText); |
spinal | 8:4f86dcba69b9 | 182 | |
spinal | 8:4f86dcba69b9 | 183 | |
spinal | 8:4f86dcba69b9 | 184 | char ox=8, oy=16; |
spinal | 8:4f86dcba69b9 | 185 | // draw background! |
spinal | 8:4f86dcba69b9 | 186 | for(char t=0; t<3; t++){ |
spinal | 8:4f86dcba69b9 | 187 | game.display.drawBitmap(ox+24+t*16,oy+w_LT/60,sprite_buttons[12+t+(w_L*8)]); |
spinal | 8:4f86dcba69b9 | 188 | game.display.drawBitmap(ox+136+t*16,oy+w_RT/60,sprite_buttons[16+t+(w_R*8)]); |
spinal | 8:4f86dcba69b9 | 189 | } |
spinal | 8:4f86dcba69b9 | 190 | |
spinal | 8:4f86dcba69b9 | 191 | for(uint8_t y=0; y<12; y++){ |
spinal | 8:4f86dcba69b9 | 192 | for(uint8_t x=0; x<25; x++){ |
spinal | 8:4f86dcba69b9 | 193 | game.display.drawBitmap(ox+x*8,oy+y*8,sprites[sprite_map[x+25*y]]); |
spinal | 8:4f86dcba69b9 | 194 | } |
spinal | 8:4f86dcba69b9 | 195 | } |
spinal | 8:4f86dcba69b9 | 196 | |
spinal | 8:4f86dcba69b9 | 197 | game.display.drawBitmap(ox+64+(w_LX-127)/10,oy+56+(127-w_LY)/10,sprite_circle); |
spinal | 8:4f86dcba69b9 | 198 | game.display.drawBitmap(ox+120+(w_RX-127)/10,oy+56+(127-w_RY)/10,sprite_circle); |
spinal | 8:4f86dcba69b9 | 199 | if(w_RIGHT)game.display.drawBitmap(ox+45,oy+32, sprite_buttons[11]); |
spinal | 8:4f86dcba69b9 | 200 | if(w_DOWN)game.display.drawBitmap(ox+36,oy+41, sprite_buttons[9]); |
spinal | 8:4f86dcba69b9 | 201 | if(w_LEFT)game.display.drawBitmap(ox+27,oy+32, sprite_buttons[10]); |
spinal | 8:4f86dcba69b9 | 202 | if(w_UP)game.display.drawBitmap(ox+36,oy+23, sprite_buttons[8]); |
spinal | 8:4f86dcba69b9 | 203 | if(w_MINUS)game.display.drawBitmap(ox+80,oy+32,sprite_buttons[6]); |
spinal | 8:4f86dcba69b9 | 204 | if(w_HOME)game.display.drawBitmap(ox+96,oy+32,sprite_buttons[5]); |
spinal | 8:4f86dcba69b9 | 205 | if(w_PLUS)game.display.drawBitmap(ox+112,oy+32,sprite_buttons[6]); |
spinal | 8:4f86dcba69b9 | 206 | if(w_X)game.display.drawBitmap(ox+152,oy+16,sprite_buttons[0]); |
spinal | 8:4f86dcba69b9 | 207 | if(w_Y)game.display.drawBitmap(ox+136,oy+28,sprite_buttons[1]); |
spinal | 8:4f86dcba69b9 | 208 | if(w_A)game.display.drawBitmap(ox+168,oy+28,sprite_buttons[2]); |
spinal | 8:4f86dcba69b9 | 209 | if(w_B)game.display.drawBitmap(ox+152,oy+40,sprite_buttons[3]); |
spinal | 8:4f86dcba69b9 | 210 | if(w_LZ)game.display.drawBitmap(ox+77,oy+2,sprite_buttons[7]); |
spinal | 8:4f86dcba69b9 | 211 | if(w_RZ)game.display.drawBitmap(ox+110,oy+2,sprite_buttons[7]); |
spinal | 8:4f86dcba69b9 | 212 | |
spinal | 8:4f86dcba69b9 | 213 | |
spinal | 8:4f86dcba69b9 | 214 | |
spinal | 8:4f86dcba69b9 | 215 | |
spinal | 8:4f86dcba69b9 | 216 | |
Pokitto | 0:2d2a3994d55d | 217 | } |
Pokitto | 0:2d2a3994d55d | 218 | } |
Pokitto | 0:2d2a3994d55d | 219 | |
Pokitto | 0:2d2a3994d55d | 220 | } |