├── usart.h ├── makefile ├── .gitignore ├── main.h ├── macros.h ├── wiimote.h ├── usart.c ├── config.h ├── README ├── pindef.h ├── commands.s ├── wiimote.c ├── LICENSE ├── main.c └── wm_crypto.h /usart.h: -------------------------------------------------------------------------------- 1 | #ifndef _USART_H_ 2 | #define _USART_H_ 3 | 4 | void initUSART(); 5 | void USART_Write(char); 6 | void USART_WriteStr(char*); 7 | void printHex8(unsigned char a); 8 | void printHex16(unsigned int a); 9 | void printEndl(); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | F_CPU = 16000000 2 | 3 | default: 4 | avr-gcc -mmcu=atmega328p -DF_CPU=$(F_CPU) -o main.elf --std=c99 -O2 main.c commands.s usart.c wiimote.c 5 | avr-objcopy -O ihex main.elf main.hex 6 | avr-size main.elf 7 | 8 | clean: 9 | rm -rf *.elf *.o *.hex 10 | 11 | d: 12 | avrdude -p atmega328p -P /dev/ttyACM0 -c avrispv2 -F -u -U flash:w:main.hex 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | #ifndef main_h 2 | 3 | #if F_CPU == NULL 4 | #error "define your clock speed" 5 | #endif 6 | 7 | #include 8 | 9 | #include "config.h" 10 | #include "pindef.h" 11 | #include "macros.h" 12 | 13 | #ifdef USE_SERPORT 14 | #include "ser.c" 15 | #include "ser.h" 16 | #endif 17 | 18 | #include "wiimote.h" 19 | 20 | #define main_h 21 | #endif 22 | -------------------------------------------------------------------------------- /macros.h: -------------------------------------------------------------------------------- 1 | #ifndef macros_h 2 | 3 | /* old macros */ 4 | 5 | // Macros 6 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) // clear bit 7 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) // set bit 8 | #define tog(sfr, bit) (_SFR_BYTE(sfr) ^= _BV(bit)) // toggle bit 9 | #define wdr() __asm__ __volatile__ ("wdr") // watchdog reset 10 | #define nop() __asm__ __volatile__ ("nop") // no operation 11 | 12 | #define macros_h 13 | #endif 14 | -------------------------------------------------------------------------------- /wiimote.h: -------------------------------------------------------------------------------- 1 | #ifndef wiimote_h 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define twi_port PORTC 10 | #define twi_ddr DDRC 11 | #define twi_scl_pin 5 12 | #define twi_sda_pin 4 13 | 14 | #define dev_detect_port PORTD 15 | #define dev_detect_ddr DDRD 16 | #define dev_detect_pin 4 17 | 18 | // initialize wiimote interface with id, starting data, and calibration data 19 | void wm_init(unsigned char *, unsigned char *, unsigned char *, void (*)(void)); 20 | 21 | // set button data 22 | void wm_newaction(unsigned char *); 23 | 24 | #define wiimote_h 25 | #endif 26 | -------------------------------------------------------------------------------- /usart.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void initUSART() { 4 | 5 | UCSR0A = 0; 6 | UCSR0B = (1 << TXEN0); 7 | UCSR0C = (1 << UCSZ01)|(1 << UCSZ00); 8 | 9 | UBRR0H = 0; 10 | UBRR0L = 8; 11 | 12 | } 13 | 14 | void USART_Write(char a) { 15 | 16 | while(!(UCSR0A & (1 << UDRE0))); 17 | 18 | UDR0 = a; 19 | 20 | } 21 | 22 | void USART_WriteStr(char* str) { 23 | 24 | while(*str) { 25 | USART_Write(*str); 26 | str++; 27 | } 28 | } 29 | 30 | void printHex8(unsigned char a) { 31 | 32 | char lookup[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; 33 | 34 | USART_Write(lookup[a >> 4]); 35 | USART_Write(lookup[a & 0xF]); 36 | } 37 | 38 | void printHex16(unsigned int a) { 39 | 40 | printHex8(a >> 8); 41 | printHex8(a & 0xFF); 42 | 43 | } 44 | 45 | void printEndl() { 46 | USART_Write('\n'); 47 | USART_Write('\r'); 48 | } 49 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | // enables serial port functions 2 | //#define USE_SERPORT 3 | 4 | // enables the + - up down left right buttons if defined 5 | //#define GHWT 6 | 7 | // trigger on either rising or falling edge (never both please) 8 | // these only apply to the 5 pads, buttons and bass pedals are always falling edge 9 | // pull_up_res will enable internal pull-up resistors for the pad pins 10 | // does not effect buttons and bass pedals 11 | //#define trig_on_rise 12 | #define trig_on_fall 13 | //#define pull_up_res 14 | 15 | // guarantee the release of a pad before the next hit if defined 16 | //#define GUARANTEE_RELEASE 17 | 18 | // minimum pulse time (x = actual pulse time / 0.005) 19 | // keep at 5, raise if you see double hits 20 | #define hit_min_time 4 21 | 22 | // hit softness (0 = max, 7 = min, just make it 0) 23 | #define default_hit_softness 0 24 | 25 | // simulated degree of thumb stick movement (something under 32) 26 | #define thumbstick_speed 16 27 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | 3 | This code will read in a Nintendo 64 controller and fake it as being a wii classic controller using an ATmega microcontroller. 4 | The wii remote extension should be connected to the SCL and SDA ports on the AVR and the N64 data pin should be connected to PD1. 5 | 6 | This code has only been tested with an ATMega328p(Arduino), but should work with most ATmegas. 7 | It also requires that the ATMega be clocked at 16MHz as much of the controller timing is down to the cycle. 8 | 9 | The code now works with Gamecube controllers. By default a gamecube controller is used. To switch to a Nintendo 64 controller, jump pins 4 and 5 together. The Gamecube controller is connected in the same way that Nintendo 64 controllers are. At this point Rumble is not supported. 10 | 11 | The code used to communicate with the wiimote is a modified version of Frank Zhao's wii drum controller code which can be found at https://code.google.com/p/circle-of-current/. This project would not have been possible without it. 12 | 13 | This code is licensed under the Apache License 2.0 which can be found here: www.apache.org/licenses/LICENSE-2.0 14 | 15 | -------------------------------------------------------------------------------- /pindef.h: -------------------------------------------------------------------------------- 1 | #ifndef pindef_h 2 | 3 | #define twi_port PORTC 4 | #define twi_ddr DDRC 5 | #define twi_scl_pin 5 6 | #define twi_sda_pin 4 7 | 8 | #define dev_detect_port PORTD 9 | #define dev_detect_ddr DDRD 10 | #define dev_detect_pin 4 11 | 12 | #define uart_port PORTD 13 | #define uart_rx_pin 0 14 | 15 | #define LED_pin 0 16 | #define LED_port PORTB 17 | #define LED_ddr DDRB 18 | 19 | #define power_detect_pin 2 20 | #define power_detect_port PORTD 21 | #define power_detect_ddr DDRD 22 | #define power_detect_input PIND 23 | 24 | #define adc_port PORTC 25 | #define adc_ddr DDRC 26 | 27 | // for the bit numbers, go to 28 | // http://wiibrew.org/wiki/Wiimote/Extension_Controllers 29 | 30 | #define drum_port PORTC 31 | #define drum_ddr DDRC 32 | #define drum_in_reg PINC 33 | 34 | #define bass_port PORTB 35 | #define bass_ddr DDRB 36 | #define bass_in_reg PINB 37 | 38 | #define green_bit 4 39 | #define green_pin 3 40 | 41 | #define red_bit 6 42 | #define red_pin 2 43 | 44 | #define yellow_bit 5 45 | #define yellow_pin 1 46 | 47 | #define blue_bit 3 48 | #define blue_pin 0 49 | 50 | #define orange_bit 7 51 | #define orange_pin 4 52 | 53 | #define bass_bit 2 54 | 55 | #define bass1_pin 1 56 | #define bass2_pin 2 57 | 58 | #define plusminus_port PORTA 59 | #define plusminus_ddr DDRA 60 | #define plusminus_in_reg PINA 61 | 62 | #define stick_in_reg PINA 63 | #define stick_port PORTA 64 | #define stick_ddr DDRA 65 | 66 | #define plus_bit 2 67 | #define plus_pin 6 68 | 69 | #define minus_bit 4 70 | #define minus_pin 7 71 | 72 | #define up_stick_pin 6 73 | #define down_stick_pin 6 74 | #define left_stick_pin 6 75 | #define right_stick_pin 6 76 | 77 | #define pindef_h 78 | #endif 79 | -------------------------------------------------------------------------------- /commands.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | DDRB = 0x4 4 | PORTB = 0x5 5 | PINB = 0x3 6 | 7 | DDRD = 0xA 8 | PORTD = 0xB 9 | PIND = 0x9 10 | PD3 = 3 11 | 12 | DDRB = 0x4 13 | PINB = 0x3 14 | PB1 = 2 15 | PB2 = 4 16 | 17 | __SREG__ = 0x3f 18 | __SP_H__ = 0x3e 19 | __SP_L__ = 0x3d 20 | __CCP__ = 0x34 21 | __tmp_reg__ = 0 22 | __zero_reg__ = 1 23 | 24 | #n64DataStart = 0x200 25 | .extern n64DataStart 26 | 27 | .global inputDataBytes 28 | 29 | inputDataBytes: 30 | .space 4 31 | 32 | ;Assume Z already PORTD, 2 cycles 33 | .macro outputHigh 34 | ldi r25,0 35 | out DDRB,r25 36 | .endm 37 | 38 | ;3 cycles 39 | .macro outputLow 40 | ldi r25,2 41 | out DDRB,r25 42 | .endm 43 | 44 | ;1 Cycle 45 | .macro readData 46 | in r25,PINB 47 | .endm 48 | 49 | 50 | ;16 cycles 51 | .macro delayMicro 52 | nop 53 | nop 54 | nop 55 | nop 56 | nop 57 | nop 58 | nop 59 | nop 60 | nop 61 | nop 62 | nop 63 | nop 64 | nop 65 | nop 66 | nop 67 | nop 68 | .endm 69 | 70 | ;8 cycles 71 | .macro delayHalf 72 | nop 73 | nop 74 | nop 75 | nop 76 | nop 77 | nop 78 | nop 79 | nop 80 | .endm 81 | 82 | 83 | ;Waits until the n64 is finished sending a command 84 | .global sync 85 | .global _Z4syncv 86 | 87 | _Z4syncv: 88 | sync: 89 | push r16 90 | ;Should wait for 6 microseconds 91 | outputLow 92 | ldi r16,0x5A 93 | 94 | syncLoop: 95 | ;Check the signal line 96 | readData 97 | andi r25,PB1 98 | ;if the signal line is low then jump back to sync 99 | breq sync 100 | 101 | ;decrement the count 102 | dec r16 103 | brne syncLoop 104 | 105 | pop r16 106 | ret 107 | 108 | 109 | ;reads 4 Bytes from the signal line 110 | ;Bytes stored in inputDataBytes 111 | .global readConsoleData 112 | 113 | readConsoleData: 114 | 115 | ldi r24,0x0 116 | ldi r27,0x8 117 | 118 | readConsoleDataLoop: 119 | ldi r26,64 120 | readConsoleDataDown: 121 | readData 122 | dec r26 123 | breq readConsoleDataError 124 | andi r25,PB1 125 | breq readConsoleDataDown 126 | 127 | ;Wait for the signal line to drop 128 | ldi r26,200 129 | readConsoleDataWaitUp: 130 | readData 131 | dec r26 132 | breq readConsoleDataError2 133 | andi r25,PB1 134 | brne readConsoleDataWaitUp 135 | 136 | 137 | 138 | ;Delay 2.5 microseconds to align with the data 139 | delayMicro 140 | delayMicro 141 | 142 | 143 | readData 144 | lsr r25 145 | andi r25,0x1 146 | lsl r24 147 | or r24,r25 148 | 149 | ;Check for the end 150 | ;3 151 | dec r27 152 | brne readConsoleDataLoop 153 | 154 | ret 155 | 156 | readConsoleDataError: 157 | #Impossible value to read 158 | ldi r24, 0x7D 159 | ret 160 | 161 | readConsoleDataError2: 162 | ldi r24, 0x7D 163 | ret 164 | 165 | .global detectFallingEdge 166 | 167 | detectFallingEdge: 168 | 169 | detectFallingEdgeUp: 170 | readData 171 | andi r25,0x2 172 | breq detectFallingEdgeUp 173 | 174 | detectFallingEdgeDown: 175 | readData 176 | andi r25,0x2 177 | brne detectFallingEdgeDown 178 | 179 | ret 180 | 181 | 182 | ;Sends One byte to the n64 Console 183 | ;Byte stored in r24 184 | .global sendByte 185 | .global sendByteConsecutive 186 | 187 | sendByte: 188 | 189 | outputHigh 190 | 191 | ;Be sure that the signal is high 192 | delayMicro 193 | delayMicro 194 | 195 | sendByteConsecutive: 196 | 197 | ldi r19,0x8 198 | mov r18,r24 199 | 200 | sendByteLoop: 201 | andi r18,0x80 ;1 202 | brne sendByteOne ;1/2 203 | sendByteZero: 204 | ;10 in 205 | nop 206 | nop 207 | nop 208 | outputLow 209 | 210 | delayMicro 211 | delayMicro 212 | delayHalf 213 | 214 | nop ;9 215 | nop ;10 216 | nop ;11 217 | nop ;12 218 | nop ;13 219 | 220 | outputHigh 221 | jmp sendByteFinish ;2 222 | 223 | sendByteOne: 224 | ;11 in 225 | nop 226 | nop 227 | outputLow 228 | delayHalf 229 | 230 | nop ;9 231 | nop ;10 232 | nop ;11 233 | nop ;12 234 | nop ;13 235 | 236 | outputHigh 237 | 238 | delayMicro 239 | delayMicro 240 | nop 241 | nop 242 | nop 243 | 244 | sendByteFinish: 245 | lsl r24 ;1 246 | mov r18,r24 247 | 248 | dec r19 ;1 249 | breq sendByteNoJmpBack ;1 250 | sendByteJmpBack: 251 | 252 | jmp sendByteLoop ;2 253 | 254 | sendByteNoJmpBack: 255 | 256 | ;Technically not the end, but I wanted to leave some 257 | ;leeway for future calls 258 | ret 259 | 260 | 261 | .global sendStopBit 262 | 263 | sendStopBit: 264 | 265 | outputLow 266 | delayMicro 267 | delayHalf 268 | nop 269 | nop 270 | nop 271 | nop 272 | nop 273 | outputHigh 274 | 275 | ret 276 | 277 | .global sendFourBytes 278 | sendFourBytes: 279 | 280 | push r18 281 | push r20 282 | push r22 283 | 284 | call sendByte 285 | 286 | pop r24 287 | call sendByteConsecutive 288 | 289 | pop r24 290 | call sendByteConsecutive 291 | 292 | pop r24 293 | call sendByteConsecutive 294 | 295 | call sendStopBit 296 | 297 | ret 298 | 299 | .global getControllerData 300 | 301 | getControllerData: 302 | 303 | #ldi r24, 0x01 304 | #call sendByte 305 | #call sendStopBit 306 | 307 | call readConsoleData 308 | push r24 309 | call readConsoleData 310 | push r24 311 | call readConsoleData 312 | push r24 313 | call readConsoleData 314 | mov r25, r24 315 | pop r24 316 | pop r23 317 | pop r22 318 | 319 | ret 320 | -------------------------------------------------------------------------------- /wiimote.c: -------------------------------------------------------------------------------- 1 | #include "wiimote.h" 2 | #include "wm_crypto.h" 3 | 4 | 5 | // pointer to user function 6 | static void (*wm_sample_event)(); 7 | 8 | // crypto data 9 | static volatile unsigned char wm_rand[10]; 10 | static volatile unsigned char wm_key[6]; 11 | static volatile unsigned char wm_ft[8]; 12 | static volatile unsigned char wm_sb[8]; 13 | 14 | // virtual register 15 | static volatile unsigned char twi_reg[256]; 16 | static volatile unsigned int twi_reg_addr; 17 | 18 | static volatile unsigned char twi_first_addr_flag; // set address flag 19 | static volatile unsigned char twi_rw_len; // length of most recent operation 20 | 21 | extern volatile int n64DataInterrupted; 22 | 23 | void twi_slave_init(unsigned char addr) 24 | { 25 | // initialize stuff 26 | twi_reg_addr = 0; 27 | 28 | // set slave address 29 | TWAR = addr << 1; 30 | 31 | // enable twi module, acks, and twi interrupt 32 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); 33 | 34 | // enable interrupts 35 | sei(); 36 | } 37 | 38 | void twi_clear_int(unsigned char ack) 39 | { 40 | // get ready by clearing interrupt, with or without ack 41 | if(ack != 0) 42 | { 43 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); 44 | } 45 | else 46 | { 47 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); 48 | } 49 | } 50 | 51 | /* 52 | 53 | I'd like to thank Hector Martin for posting his encryption method! 54 | His website is http://www.marcansoft.com/ 55 | Decryption method found at http://www.derkeiler.com/pdf/Newsgroups/sci.crypt/2008-11/msg00110.pdf 56 | 57 | */ 58 | 59 | unsigned char wm_ror8(unsigned char a, unsigned char b) 60 | { 61 | // bit shift with roll-over 62 | return (a >> b) | ((a << (8 - b)) & 0xFF); 63 | } 64 | 65 | void wm_gentabs() 66 | { 67 | unsigned char idx; 68 | 69 | // check all idx 70 | for(idx = 0; idx < 7; idx++) 71 | { 72 | // generate test key 73 | unsigned char ans[6]; 74 | unsigned char tkey[6]; 75 | unsigned char t0[10]; 76 | 77 | for(unsigned char i = 0; i < 6; i++) 78 | { 79 | ans[i] = pgm_read_byte(&(ans_tbl[idx][i])); 80 | } 81 | for(unsigned char i = 0; i < 10; i++) 82 | { 83 | t0[i] = pgm_read_byte(&(sboxes[0][wm_rand[i]])); 84 | } 85 | 86 | tkey[0] = ((wm_ror8((ans[0] ^ t0[5]), (t0[2] % 8)) - t0[9]) ^ t0[4]); 87 | tkey[1] = ((wm_ror8((ans[1] ^ t0[1]), (t0[0] % 8)) - t0[5]) ^ t0[7]); 88 | tkey[2] = ((wm_ror8((ans[2] ^ t0[6]), (t0[8] % 8)) - t0[2]) ^ t0[0]); 89 | tkey[3] = ((wm_ror8((ans[3] ^ t0[4]), (t0[7] % 8)) - t0[3]) ^ t0[2]); 90 | tkey[4] = ((wm_ror8((ans[4] ^ t0[1]), (t0[6] % 8)) - t0[3]) ^ t0[4]); 91 | tkey[5] = ((wm_ror8((ans[5] ^ t0[7]), (t0[8] % 8)) - t0[5]) ^ t0[9]); 92 | 93 | // compare with actual key 94 | if(memcmp(tkey, wm_key, 6) == 0) break; // if match, then use this idx 95 | } 96 | 97 | // generate encryption from idx key and rand 98 | wm_ft[0] = pgm_read_byte(&(sboxes[idx + 1][wm_key[4]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[3]])); 99 | wm_ft[1] = pgm_read_byte(&(sboxes[idx + 1][wm_key[2]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[5]])); 100 | wm_ft[2] = pgm_read_byte(&(sboxes[idx + 1][wm_key[5]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[7]])); 101 | wm_ft[3] = pgm_read_byte(&(sboxes[idx + 1][wm_key[0]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[2]])); 102 | wm_ft[4] = pgm_read_byte(&(sboxes[idx + 1][wm_key[1]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[4]])); 103 | wm_ft[5] = pgm_read_byte(&(sboxes[idx + 1][wm_key[3]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[9]])); 104 | wm_ft[6] = pgm_read_byte(&(sboxes[idx + 1][wm_rand[0]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[6]])); 105 | wm_ft[7] = pgm_read_byte(&(sboxes[idx + 1][wm_rand[1]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[8]])); 106 | 107 | wm_sb[0] = pgm_read_byte(&(sboxes[idx + 1][wm_key[0]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[1]])); 108 | wm_sb[1] = pgm_read_byte(&(sboxes[idx + 1][wm_key[5]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[4]])); 109 | wm_sb[2] = pgm_read_byte(&(sboxes[idx + 1][wm_key[3]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[0]])); 110 | wm_sb[3] = pgm_read_byte(&(sboxes[idx + 1][wm_key[2]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[9]])); 111 | wm_sb[4] = pgm_read_byte(&(sboxes[idx + 1][wm_key[4]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[7]])); 112 | wm_sb[5] = pgm_read_byte(&(sboxes[idx + 1][wm_key[1]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[8]])); 113 | wm_sb[6] = pgm_read_byte(&(sboxes[idx + 1][wm_rand[3]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[5]])); 114 | wm_sb[7] = pgm_read_byte(&(sboxes[idx + 1][wm_rand[2]])) ^ pgm_read_byte(&(sboxes[idx + 2][wm_rand[6]])); 115 | } 116 | 117 | void wm_slaveTxStart(unsigned char addr) 118 | { 119 | if(addr >= 0x00 && addr < 0x06) 120 | { 121 | // call user event 122 | wm_sample_event(); 123 | } 124 | } 125 | 126 | void wm_slaveRx(unsigned char addr, unsigned char l) 127 | { 128 | // if encryption data is sent, store them accordingly 129 | if(addr >= 0x40 && addr < 0x46) 130 | { 131 | for(unsigned int i = 0; i < 6; i++) 132 | { 133 | wm_rand[9 - i] = twi_reg[0x40 + i]; 134 | } 135 | } 136 | else if(addr >= 0x46 && addr < 0x4C) 137 | { 138 | for(unsigned int i = 6; i < 10; i++) 139 | { 140 | wm_rand[9 - i] = twi_reg[0x40 + i]; 141 | } 142 | for(unsigned int i = 0; i < 2; i++) 143 | { 144 | wm_key[5 - i] = twi_reg[0x40 + 10 + i]; 145 | } 146 | } 147 | else if(addr >= 0x4C && addr < 0x50) 148 | { 149 | for(unsigned int i = 2; i < 6; i++) 150 | { 151 | wm_key[5 - i] = twi_reg[0x40 + 10 + i]; 152 | } 153 | if(addr + l == 0x50) 154 | { 155 | // generate decryption once all data is loaded 156 | wm_gentabs(); 157 | } 158 | } 159 | } 160 | 161 | void wm_newaction(unsigned char * d) 162 | { 163 | // load button data from user application 164 | memcpy(twi_reg, d, 6); 165 | } 166 | 167 | void wm_init(unsigned char * id, unsigned char * t, unsigned char * cal_data, void (*function)(void)) 168 | { 169 | // link user function 170 | wm_sample_event = function; 171 | 172 | // start state 173 | wm_newaction(t); 174 | twi_reg[0xF0] = 0; // disable encryption 175 | 176 | // set id 177 | for(unsigned int i = 0, j = 0xFA; i < 6; i++, j++) 178 | { 179 | twi_reg[j] = id[i]; 180 | } 181 | 182 | // set calibration data 183 | for(unsigned int i = 0, j = 0x20; i < 6; i++, j++) 184 | { 185 | twi_reg[j] = cal_data[i]; 186 | } 187 | 188 | // initialize device detect pin 189 | dev_detect_port &= 0xFF ^ _BV(dev_detect_pin); 190 | dev_detect_ddr |= _BV(dev_detect_pin); 191 | _delay_ms(500); // delay to simulate disconnect 192 | 193 | // ready twi bus, no pull-ups 194 | twi_port &= 0xFF ^ _BV(twi_scl_pin); 195 | twi_port &= 0xFF ^ _BV(twi_sda_pin); 196 | 197 | // start twi slave, link events 198 | twi_slave_init(0x52); 199 | 200 | // make the wiimote think something is connected 201 | dev_detect_port |= _BV(dev_detect_pin); 202 | } 203 | 204 | ISR(TWI_vect) 205 | { 206 | n64DataInterrupted = 1; 207 | switch(TW_STATUS) 208 | { 209 | // Slave Rx 210 | case TW_SR_SLA_ACK: // addressed, returned ack 211 | case TW_SR_GCALL_ACK: // addressed generally, returned ack 212 | case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack 213 | case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration generally, returned ack 214 | // get ready to receive pointer 215 | twi_first_addr_flag = 0; 216 | // ack 217 | twi_clear_int(1); 218 | break; 219 | case TW_SR_DATA_ACK: // data received, returned ack 220 | case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack 221 | if(twi_first_addr_flag != 0) 222 | { 223 | // put byte in register 224 | unsigned char t = TWDR; 225 | if(twi_reg[0xF0] == 0xAA && twi_reg_addr != 0xF0) // if encryption is on 226 | { 227 | // decrypt 228 | twi_reg[twi_reg_addr] = (t ^ wm_sb[twi_reg_addr % 8]) + wm_ft[twi_reg_addr % 8]; 229 | } 230 | else 231 | { 232 | twi_reg[twi_reg_addr] = t; 233 | } 234 | twi_reg_addr++; 235 | twi_rw_len++; 236 | } 237 | else 238 | { 239 | // set address 240 | twi_reg_addr = TWDR; 241 | twi_first_addr_flag = 1; 242 | twi_rw_len = 0; 243 | } 244 | twi_clear_int(1); // ack 245 | break; 246 | case TW_SR_STOP: // stop or repeated start condition received 247 | // run user defined function 248 | wm_slaveRx(twi_reg_addr - twi_rw_len, twi_rw_len); 249 | twi_clear_int(1); // ack future responses 250 | break; 251 | case TW_SR_DATA_NACK: // data received, returned nack 252 | case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack 253 | twi_clear_int(0); // nack back at master 254 | break; 255 | 256 | // Slave Tx 257 | case TW_ST_SLA_ACK: // addressed, returned ack 258 | case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack 259 | // run user defined function 260 | wm_slaveTxStart(twi_reg_addr); 261 | twi_rw_len = 0; 262 | case TW_ST_DATA_ACK: // byte sent, ack returned 263 | // ready output byte 264 | if(twi_reg[0xF0] == 0xAA) // encryption is on 265 | { 266 | // encrypt 267 | TWDR = (twi_reg[twi_reg_addr] - wm_ft[twi_reg_addr % 8]) ^ wm_sb[twi_reg_addr % 8]; 268 | } 269 | else 270 | { 271 | TWDR = twi_reg[twi_reg_addr]; 272 | } 273 | twi_reg_addr++; 274 | twi_rw_len++; 275 | twi_clear_int(1); // ack 276 | break; 277 | case TW_ST_DATA_NACK: // received nack, we are done 278 | case TW_ST_LAST_DATA: // received ack, but we are done already! 279 | // ack future responses 280 | twi_clear_int(1); 281 | break; 282 | default: 283 | twi_clear_int(0); 284 | break; 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Code originally from Frank Zhao's wii drum controller project. This file was heavily modified. 3 | */ 4 | 5 | #include "main.h" 6 | #include 7 | 8 | #include "usart.h" 9 | 10 | #define DELAY_TIME 16 11 | 12 | #define N64_BUT_A 0x80 13 | #define N64_BUT_B 0x40 14 | #define N64_BUT_Z 0x20 15 | #define N64_BUT_START 0x10 16 | #define N64_BUT_L 0x2000 17 | #define N64_BUT_R 0x1000 18 | 19 | #define N64_PAD_UP 0x8 20 | #define N64_PAD_DOWN 0x4 21 | #define N64_PAD_LEFT 0x2 22 | #define N64_PAD_RIGHT 0x1 23 | 24 | #define N64_CAM_UP 0x800 25 | #define N64_CAM_DOWN 0x400 26 | #define N64_CAM_LEFT 0x200 27 | #define N64_CAM_RIGHT 0x100 28 | 29 | #define GAMECUBE_BUT_Y 0x08 30 | #define GAMECUBE_BUT_X 0x04 31 | #define GAMECUBE_BUT_B 0x02 32 | #define GAMECUBE_BUT_A 0x01 33 | #define GAMECUBE_BUT_START 0x10 34 | #define GAMECUBE_BUT_L 0x4000 35 | #define GAMECUBE_BUT_R 0x2000 36 | #define GAMECUBE_BUT_Z 0x1000 37 | 38 | #define GAMECUBE_PAD_UP 0x800 39 | #define GAMECUBE_PAD_DOWN 0x400 40 | #define GAMECUBE_PAD_RIGHT 0x820 41 | #define GAMECUBE_PAD_LEFT 0x100 42 | 43 | #define CLASSIC_BUT_A 0x10 44 | #define CLASSIC_BUT_B 0x40 45 | #define CLASSIC_BUT_X 0x08 46 | #define CLASSIC_BUT_Y 0x20 47 | #define CLASSIC_BUT_RT 0x02 48 | #define CLASSIC_BUT_LT 0x20 49 | #define CLASSIC_BUT_ZR 0x04 50 | #define CLASSIC_BUT_ZL 0x80 51 | #define CLASSIC_BUT_PLUS 0x04 52 | #define CLASSIC_BUT_MINUS 0x10 53 | 54 | #define CLASSIC_PAD_UP 0x01 55 | #define CLASSIC_PAD_DOWN 0x40 56 | #define CLASSIC_PAD_LEFT 0x02 57 | #define CLASSIC_PAD_RIGHT 0x80 58 | 59 | #define BUTTON_MAP(n64But, classicBut, classicByte) \ 60 | if(n64Data & (n64But)) { \ 61 | classicData[(classicByte)] &= ~(classicBut); \ 62 | } else { \ 63 | classicData[(classicByte)] |= (classicBut); \ 64 | } 65 | 66 | #define BUTTON_MAP(n64But, classicBut, classicByte) \ 67 | if(n64Data & (n64But)) { \ 68 | classicData[(classicByte)] &= ~(classicBut); \ 69 | } else { \ 70 | classicData[(classicByte)] |= (classicBut); \ 71 | } 72 | 73 | // most of this data is found on 74 | // http://wiibrew.org/wiki/Wiimote/Extension_Controllers 75 | 76 | const unsigned char drum_id[6] = {0x00, 0x00, 0xA4, 0x20, 0x01, 0x01}; 77 | 78 | // calibration data 79 | const unsigned char cal_data[32] = { 80 | 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x00, 82 | 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 84 | 0x00, 0x00, 0x00, 0x00, 85 | 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x00, 0x00 88 | }; 89 | 90 | unsigned long int getControllerData(); 91 | unsigned char readConsoleData(); 92 | void sendData(unsigned char); 93 | void sendStopBit(); 94 | volatile int n64DataInterrupted; 95 | 96 | void dummyFunc() {}; 97 | 98 | void convertN64ToClassic(unsigned long int n64Data, unsigned char* classicData) { 99 | 100 | BUTTON_MAP(N64_BUT_A, CLASSIC_BUT_A, 5); 101 | BUTTON_MAP(N64_BUT_B, CLASSIC_BUT_X, 5); 102 | BUTTON_MAP(N64_BUT_R, CLASSIC_BUT_RT, 4); 103 | BUTTON_MAP(N64_BUT_Z, CLASSIC_BUT_ZL, 5); 104 | BUTTON_MAP(N64_BUT_START, CLASSIC_BUT_PLUS, 4); 105 | BUTTON_MAP(N64_BUT_L, CLASSIC_PAD_RIGHT, 4); 106 | BUTTON_MAP(N64_CAM_DOWN, CLASSIC_BUT_B, 5); 107 | BUTTON_MAP(N64_CAM_LEFT, CLASSIC_BUT_Y, 5); 108 | 109 | unsigned char analog = ((n64Data >> 16) + 0x40); 110 | analog = (analog > 0xE0) ? 0 : ((analog > 0x7F) ? 0x7F : analog); 111 | analog >>= 1; 112 | classicData[0] = analog; 113 | 114 | analog = ((n64Data >> 24) + 0x40); 115 | analog = (analog > 0xE0) ? 8 : ((analog > 0x7F) ? 0x78 : analog); 116 | analog >>= 1; 117 | classicData[1] = analog; 118 | 119 | classicData[2] = 0x10; 120 | classicData[0] |= 0x80; 121 | } 122 | 123 | void convertN64ToClassicSmash(unsigned long int n64Data, unsigned char* classicData) { 124 | 125 | BUTTON_MAP(N64_BUT_A, CLASSIC_BUT_A, 5); 126 | BUTTON_MAP(N64_BUT_B, CLASSIC_BUT_B, 5); 127 | BUTTON_MAP(N64_BUT_R, CLASSIC_BUT_ZR, 5); 128 | BUTTON_MAP(N64_BUT_Z, CLASSIC_BUT_RT, 4); 129 | BUTTON_MAP(N64_BUT_START, CLASSIC_BUT_PLUS, 4); 130 | 131 | if(n64Data & (N64_CAM_UP | N64_CAM_DOWN | N64_CAM_RIGHT | N64_CAM_LEFT)) { 132 | classicData[5] &= ~(CLASSIC_BUT_X); 133 | } else { 134 | classicData[5] |= CLASSIC_BUT_X; 135 | } 136 | 137 | unsigned char analog = ((n64Data >> 16) + 0x40); 138 | analog = (analog > 0xE0) ? 0 : ((analog > 0x7F) ? 0x7F : analog); 139 | analog >>= 1; 140 | classicData[0] = analog; 141 | 142 | analog = ((n64Data >> 24) + 0x40); 143 | analog = (analog > 0xE0) ? 8 : ((analog > 0x7F) ? 0x78 : analog); 144 | analog >>= 1; 145 | classicData[1] = analog; 146 | 147 | //classicData[0] = (n64Data >> 18) & 0x3F; 148 | //classicData[1] = (n64Data >> 26) & 0x3F; 149 | 150 | } 151 | 152 | void convertGamecubeToClassicSmash(unsigned long int n64Data, unsigned long int extendedData, unsigned char* classicData) { 153 | 154 | static int CamXWasNeg = 0; 155 | static int CamYWasNeg = 0; 156 | 157 | BUTTON_MAP(GAMECUBE_BUT_A, CLASSIC_BUT_A, 5); 158 | BUTTON_MAP(GAMECUBE_BUT_B, CLASSIC_BUT_B, 5); 159 | BUTTON_MAP(GAMECUBE_BUT_L, CLASSIC_BUT_LT, 4); 160 | BUTTON_MAP(GAMECUBE_BUT_R, CLASSIC_BUT_RT, 4); 161 | BUTTON_MAP(GAMECUBE_BUT_Z, CLASSIC_BUT_ZR, 5); 162 | BUTTON_MAP(GAMECUBE_BUT_START, CLASSIC_BUT_PLUS, 4); 163 | BUTTON_MAP(GAMECUBE_BUT_X, CLASSIC_BUT_X, 5); 164 | BUTTON_MAP(GAMECUBE_BUT_Y, CLASSIC_BUT_Y, 5); 165 | 166 | BUTTON_MAP(GAMECUBE_PAD_UP, CLASSIC_PAD_UP, 5); 167 | BUTTON_MAP(GAMECUBE_PAD_DOWN, CLASSIC_PAD_DOWN, 4); 168 | BUTTON_MAP(GAMECUBE_PAD_LEFT, CLASSIC_PAD_LEFT, 5); 169 | BUTTON_MAP(GAMECUBE_PAD_RIGHT, CLASSIC_PAD_RIGHT, 4); 170 | 171 | unsigned char analog = (n64Data >> 16) & 0xFF; 172 | classicData[0] = analog >> 2; 173 | 174 | analog = (n64Data >> 24) & 0xFF; 175 | classicData[1] = analog >> 2; 176 | 177 | classicData[2] = 0; 178 | classicData[3] = 0; 179 | 180 | //Cam Horizontal 181 | analog = extendedData & 0xFF; 182 | if(CamXWasNeg && !(analog & 0x80)) { 183 | //Just for show 184 | classicData[0] |= 0x00; 185 | classicData[1] |= 0x00; 186 | classicData[2] |= 0x00; 187 | } else if (!CamXWasNeg & (analog & 0x80)) { 188 | classicData[0] |= 0xC0; 189 | classicData[1] |= 0xC0; 190 | classicData[2] |= 0xC0; 191 | } else if (analog & 0x80) { 192 | CamXWasNeg = 1; 193 | if(analog < 0x81) { 194 | classicData[0] |= 0; 195 | classicData[1] |= 0; 196 | classicData[2] |= 0; 197 | } else { 198 | analog += 0x80; 199 | analog >>= 3; 200 | classicData[0] |= (analog & 0x18) << 3; 201 | classicData[1] |= (analog & 0x06) << 5; 202 | classicData[2] |= (analog & 0x01) << 7; 203 | } 204 | 205 | } else { 206 | CamXWasNeg = 0; 207 | if (analog > 0x7F) { 208 | classicData[0] |= 0xC0; 209 | classicData[1] |= 0xC0; 210 | classicData[2] |= 0xC0; 211 | } else { 212 | analog += 0x80; 213 | analog >>= 3; 214 | classicData[0] |= (analog & 0x18) << 3; 215 | classicData[1] |= (analog & 0x06) << 5; 216 | classicData[2] |= (analog & 0x01) << 7; 217 | } 218 | } 219 | 220 | //Cam Vertical 221 | analog = (extendedData << 8) & 0xFF; 222 | if(CamYWasNeg && !(analog & 0x80)) { 223 | //Just for show 224 | classicData[2] |= 0x00; 225 | } else if (!CamYWasNeg & (analog & 0x80)) { 226 | classicData[2] |= 0x1F; 227 | } else if (analog & 0x80) { 228 | CamYWasNeg = 1; 229 | if(analog < 0x81) { 230 | classicData[2] |= 0; 231 | } else { 232 | analog += 0x80; 233 | analog >>= 3; 234 | classicData[2] |= analog & 0x1F; 235 | } 236 | 237 | } else { 238 | CamYWasNeg = 0; 239 | if (analog > 0x7F) { 240 | classicData[2] |= 0x1F; 241 | } else { 242 | analog += 0x80; 243 | analog >>= 3; 244 | classicData[2] |= analog & 0x1F; 245 | } 246 | } 247 | } 248 | 249 | int main() 250 | { 251 | volatile char reason = MCUSR; 252 | MCUSR = 0; 253 | initUSART(); 254 | 255 | DDRD |= (1 << 6)|(1<< 4); 256 | DDRD &= ~((1 << 7)|(1 << 5)); 257 | PORTD |= (1 << 7)|(1 << 5); 258 | DDRD &= ~((1 << 6)|(1 << 4)); 259 | 260 | unsigned char classicData[6] = {0,0,0,0,0xFF,0xFF}; 261 | 262 | // make wiimote think this is a classic controller 263 | wm_init(drum_id, classicData, cal_data, dummyFunc); 264 | 265 | unsigned int i = 0; 266 | 267 | USART_WriteStr("Start: "); 268 | printEndl(); 269 | 270 | while(1) { 271 | if(PIND & (1 << 5)) { 272 | //sendByte(0x01); 273 | sendByte(0x40); 274 | sendByteConsecutive(0x03); 275 | sendByteConsecutive(0x0); 276 | sendStopBit(); 277 | unsigned long int n64Data = getControllerData(); 278 | unsigned long int extendedData = getControllerData(); 279 | 280 | _delay_ms(1); 281 | 282 | sendByte(0x40); 283 | sendByteConsecutive(0x03); 284 | sendByteConsecutive(0x0); 285 | sendStopBit(); 286 | unsigned long int n64Data2 = getControllerData(); 287 | unsigned long int extendedData2 = getControllerData(); 288 | 289 | int valid = 1; 290 | 291 | for(i = 0; i < 4; i++) { 292 | if(((n64Data >> (i * 8)) & 0xFF) == 0x7D) { 293 | valid = 0; 294 | } 295 | if(((extendedData >> (i * 8)) & 0xFF) == 0x7D) { 296 | valid = 0; 297 | } 298 | } 299 | if(!valid) { 300 | valid = 1; 301 | n64Data = n64Data2; 302 | extendedData = extendedData2; 303 | for(i = 0; i < 4; i++) { 304 | if(((n64Data >> (i * 8)) & 0xFF) == 0x7D) { 305 | valid = 0; 306 | } 307 | if(((extendedData >> (i * 8)) & 0xFF) == 0x7D) { 308 | valid = 0; 309 | } 310 | } 311 | } 312 | 313 | if(valid) { 314 | printHex8((n64Data >> 0) & 0xFF); 315 | printHex8((n64Data >> 8) & 0xFF); 316 | printHex8((n64Data >> 16) & 0xFF); 317 | printHex8((n64Data >> 24) & 0xFF); 318 | USART_Write(' '); 319 | printHex8((extendedData >> 0) & 0xFF); 320 | printHex8((extendedData >> 8) & 0xFF); 321 | printHex8((extendedData >> 16) & 0xFF); 322 | printHex8((extendedData >> 24) & 0xFF); 323 | printEndl(); 324 | if(PIND & (1 << 7)) { 325 | convertGamecubeToClassicSmash(n64Data, extendedData, classicData); 326 | } else { 327 | //convertN64ToClassic(n64Data, classicData); 328 | } 329 | } 330 | } else { 331 | sendByte(0x01); 332 | sendStopBit(); 333 | unsigned long int n64Data = getControllerData(); 334 | int valid = 1; 335 | 336 | for(i = 0; i < 4; i++) { 337 | if(((n64Data >> (i * 8)) & 0xFF) == 0x7D) { 338 | valid = 0; 339 | } 340 | } 341 | if(valid) { 342 | printHex8((n64Data >> 0) & 0xFF); 343 | printHex8((n64Data >> 8) & 0xFF); 344 | printHex8((n64Data >> 16) & 0xFF); 345 | printHex8((n64Data >> 24) & 0xFF); 346 | printEndl(); 347 | if(PIND & (1 << 7)) { 348 | convertN64ToClassicSmash(n64Data, classicData); 349 | } else { 350 | convertN64ToClassic(n64Data, classicData); 351 | } 352 | } 353 | } 354 | 355 | wm_newaction(classicData); 356 | 357 | _delay_ms(DELAY_TIME); 358 | 359 | } 360 | 361 | return 0; 362 | } 363 | 364 | 365 | #ifdef trig_on_fall 366 | #ifdef trig_on_rise 367 | #error "cannot define both trig_on_fall and trig_on_rise" 368 | #endif 369 | #endif 370 | -------------------------------------------------------------------------------- /wm_crypto.h: -------------------------------------------------------------------------------- 1 | #ifndef wm_crypto_h 2 | 3 | #include 4 | 5 | /* 6 | 7 | I'd like to thank Hector Martin for posting his encryption method! 8 | His website is http://www.marcansoft.com/ 9 | Decryption method found at http://www.derkeiler.com/pdf/Newsgroups/sci.crypt/2008-11/msg00110.pdf 10 | 11 | */ 12 | 13 | const unsigned char ans_tbl[7][6] PROGMEM = { 14 | {0xA8,0x77,0xA6,0xE0,0xF7,0x43}, 15 | {0x5A,0x35,0x85,0xE2,0x72,0x97}, 16 | {0x8F,0xB7,0x1A,0x62,0x87,0x38}, 17 | { 0xD,0x67,0xC7,0xBE,0x4F,0x3E}, 18 | {0x20,0x76,0x37,0x8F,0x68,0xB7}, 19 | {0xA9,0x26,0x3F,0x2B,0x10,0xE3}, 20 | {0x30,0x7E,0x90, 0xE,0x85, 0xA}, 21 | }; 22 | 23 | const unsigned char sboxes[10][256] PROGMEM = { 24 | { 25 | 0x70,0x51, 3,0x86,0x40, 0xD,0x4F,0xEB,0x3E,0xCC,0xD1,0x87,0x35,0xBD,0xF5, 0xB, 26 | 0x5E,0xD0,0xF8,0xF2,0xD5,0xE2,0x6C,0x31, 0xC,0xAD,0xFC,0x21,0xC3,0x78,0xC1, 6, 27 | 0xC2,0x4C,0x55,0xE6,0x4A,0x34,0x48,0x11,0x1E,0xDA,0xE7,0x1A,0x84,0xA0,0x96,0xA7, 28 | 0xE3,0x7F,0xAF,0x63,0x9C,0xFA,0x23,0x5B,0x79,0xC8,0x9E,0xBA,0xB2,0xC9,0x22,0x12, 29 | 0x4B,0xB3,0xA1,0xB6,0x32,0x49,0xA2,0xE1,0x89,0x39,0x10,0x66,0xC5, 7,0x8F,0x54, 30 | 0xEA,0x91,0xCA,0x3F,0xF9,0x19,0xF0,0xD7,0x46,0xBC,0x28,0x1B,0x61,0xE8,0x2F,0x6A, 31 | 0xAE,0x9D,0xF6,0x4E, 9,0x14,0x77,0x4D,0xDB,0x1F,0x2E,0x7B,0x7C,0xF1,0x43,0xA3, 32 | 0,0xB8,0x13,0x8C,0x85,0xB9,0x29,0x75,0x88,0xFD,0xD2,0x56,0x1C,0x50,0x97,0x41, 33 | 0xE5,0x3B,0x60,0xB5,0xC0,0x64,0xEE,0x98,0xD6,0x2D,0x25,0xA4,0xAA,0xCD,0x7D,0xA8, 34 | 0x83,0xC6,0xAB,0xBE,0x44,0x99,0x26,0x3C,0xCE,0x9F,0xBF,0xD3,0xCB,0x76,0x7A,0x7E, 35 | 0x82, 1,0x8A,0x9A,0x80,0x1D, 0xE,0xB0,0x5C,0xD4,0x38,0x62,0xF4,0x30,0xE0,0x8E, 36 | 0x53,0xB7, 2,0x57,0xAC,0xA6,0x52, 0xA,0x6D,0x92,0x65,0x17,0x24,0x33,0x45,0x72, 37 | 0x74,0xB1,0xB4,0xF7,0x5D,0xED,0x2C,0xFF,0x47,0x37,0x5A,0x90,0xBB,0xDF,0x2A,0x16, 38 | 0x59,0x95,0xD9,0xC4,0x27,0x67,0x73,0xC7,0x68,0xFE,0xA5,0xDD,0x6B,0x5F,0x93,0xD8, 39 | 0xEC, 5,0x3A,0x8D,0x6E,0xFB,0x3D,0xA9,0x69,0x36,0xF3,0x94,0xDE,0xEF,0x15,0x6F, 40 | 0x8B,0x9B, 8, 0xF,0xDC,0x81,0x18,0x20, 4,0xE4,0x71,0xCF,0xE9,0x2B,0x42,0x58, 41 | }, 42 | { 43 | 1,0xA0,0xA9,0x62,0xD6,0x3F,0x85,0xA7,0xB6,0xD4,0xFA,0x15,0x66,0x17, 9,0xBD, 44 | 0x5D,0x14,0x34,0x26,0x59,0x72,0x91,0x54, 6,0x4F,0xF8,0xB0,0x5B,0x74,0x93,0x99, 45 | 0x8C,0xF2,0x45,0xCD,0xEA,0x4E,0xAD,0x10,0x4A,0xE5,0xCA,0xEE,0xDF,0xC6,0x6F,0x9F, 46 | 0x88,0x8E, 2,0xCC, 8,0xA8,0x77,0x94,0x6D,0x21,0xB1,0x28,0xE4,0x39,0x79,0x96, 47 | 0x60,0x71,0x81,0x16,0x2E,0xE6,0x78,0xB9,0xC4,0x46,0x9A,0x42,0xAE,0xB7,0x7C,0x43, 48 | 0xB3,0x22,0x1A,0x86,0xC2,0x32,0x3D,0x2D,0x9C,0xD2,0x29,0xE9,0x63,0x9B,0xD1,0x31, 49 | 0x38,0x5E,0x1E,0x36,0x41,0xBB, 3,0x18,0x2B,0x3E,0xBF,0x68,0x61,0xFC,0x52,0xC0, 50 | 0xDE,0xE0, 0xA,0x58,0x13,0x5A, 0,0xBE,0x1C,0x90, 0xE,0x53,0x12,0xFD,0xE2,0x6E, 51 | 0xBA,0xCE,0x24,0x27,0x44,0x7F,0x87,0xA3,0xA1,0xD5,0x50,0x40,0xE3,0xF9,0x83,0xF7, 52 | 0xC7,0xA2,0x35,0xC8,0xDB,0x19,0xAB,0x2F,0x11,0x25,0xED,0x33,0x9E,0x55,0xE1,0x48, 53 | 0xAF,0x73,0x84,0xDA,0x2A,0xAA,0x51,0xEB,0x9D,0x95,0xB2,0xCB,0xE7,0x70,0x80,0xFE, 54 | 0x4C,0x65, 4,0xEF,0xC5,0xF1,0xC3,0x3A,0xB4,0xF5,0x5F,0x23,0x89,0xDD,0x30,0xA5, 55 | 0x8B,0xD3,0xF6,0xDC,0x4D,0x64,0xD7,0xF0,0x8F,0xEC,0x56,0x37,0x5C,0xA4, 0xD, 7, 56 | 0x76,0x8A,0x2C, 0xB,0xB5,0xD8,0xC1,0x1F,0xE8,0x3B,0xF4,0x4B,0x1B,0x47,0x6C,0x49, 57 | 0x67,0x7B,0x92,0xCF,0x75,0x7E,0x20,0xD9,0x7D,0x3C,0x97,0x7A,0xD0, 5,0x6B, 0xF, 58 | 0x1D,0xFB,0x82,0x98,0x57,0x8D,0xF3,0x6A,0xBC,0xAC,0xC9,0xA6,0xFF,0xB8,0x69, 0xC, 59 | }, 60 | { 61 | 0x4C,0x4D,0x72, 7,0x5A,0x49,0x33,0x8D,0xA2,0xAB,0x46,0x3D,0x63, 0xD,0xA0,0x97, 62 | 0xFF,0xF0,0xF5,0xFA,0xC0,0xE9,0xDB,0x62,0xE4,0xE1,0x74,0x43,0xDC,0x86,0x18,0x29, 63 | 0x37,0xF4, 6,0xE2,0xED,0x6F,0x90,0x48,0x1E,0x2D,0x1D,0xEA,0x73,0x94,0x54,0xDF, 64 | 0x25,0xF6,0x47,0x27,0xD9,0x11,0x77,0xC9,0x84,0x1C,0x5B,0x5C,0x51,0x81,0xA6,0x22, 65 | 0x3E,0x24,0x96,0xC8,0x8A,0xEC,0x82,0x7C, 9,0xB8,0x45,0x4A,0x57,0xBB,0x2F,0x50, 66 | 0x75,0x8E,0x61,0x70,0x8C,0x6C,0xAF,0xD0,0xFD,0xB4,0x1B,0xAE,0xDE,0xFE,0x3B,0xB5, 67 | 0x36,0xBD,0x55, 1, 0xE,0x9C,0x41,0x56,0x5F,0xB3,0x26, 3,0x83,0xBA,0x13,0x4B, 68 | 0xCA,0xC5, 0xA,0xF8,0x60,0xA5,0xB9,0xC7,0xC3,0x98,0x32,0xFB,0x12,0xF9,0xA7,0x92, 69 | 0xAA,0x68,0xF3,0x78,0x7E, 5,0x20,0x21, 2,0xE8,0xBF,0xF2,0xB0,0x59,0x8F,0xD2, 70 | 0xCB,0x87,0x65,0x15,0xF1,0x1A,0xB2,0x30,0xAD,0xEE,0x58,0xA3,0x8B,0x66,0x1F,0x2C, 71 | 0xD7,0x5D,0x19,0x85,0xA8,0xE6,0xD3,0x6B,0xA1, 0xC,0x91,0x93,0x6A,0x5E, 0xB,0x79, 72 | 0xE3,0xDD, 0,0x4F,0x3C,0x89,0x6E,0x71,0x69,0xA9,0xAC,0x40,0xE5,0x99,0x28,0xC6, 73 | 0x31,0x4E,0x7A,0xCD, 8,0x9E,0x7D,0xEF,0x17,0xFC,0x88,0xD8,0xA4,0x6D,0x44,0x95, 74 | 0xD1,0xB7,0xD4,0x9B,0xBE,0x2A,0x34,0x64,0x2B,0xCF,0x2E,0xEB,0x38,0xCE,0x23,0xE0, 75 | 0x3A,0x3F,0xF7,0x7B,0x9F,0x10,0x53,0xBC,0x52,0x67,0x16,0xE7,0x80,0x76, 4,0xC4, 76 | 0xB6,0xC1,0xC2,0x7F,0x9A,0xDA,0xD5,0x39,0x42,0x14,0x9D,0xB1, 0xF,0x35,0xD6,0xCC, 77 | }, 78 | { 79 | 0xB9,0xDA,0x38, 0xC,0xA2,0x9C, 9,0x1F, 6,0xB1,0xB6,0xFD,0x1A,0x69,0x23,0x30, 80 | 0xC4,0xDE, 1,0xD1,0xF4,0x58,0x29,0x37,0x1C,0x7D,0xD5,0xBF,0xFF,0xBD,0xC8,0xC9, 81 | 0xCF,0x65,0xBE,0x7B,0x78,0x97,0x98,0x67, 8,0xB3,0x26,0x57,0xF7,0xFA,0x40,0xAD, 82 | 0x8E,0x75,0xA6,0x7C,0xDB,0x91,0x8B,0x51,0x99,0xD4,0x17,0x7A,0x90,0x8D,0xCE,0x63, 83 | 0xCB,0x4E,0xA0,0xAB,0x18,0x3A,0x5B,0x50,0x7F,0x21,0x74,0xC1,0xBB,0xB8,0xB7,0xBA, 84 | 0xB,0x35,0x95,0x31,0x59,0x9A,0x4D, 4, 7,0x1E,0x5A,0x76,0x13,0xF3,0x71,0x83, 85 | 0xD0,0x86, 3,0xA8,0x39,0x42,0xAA,0x28,0xE6,0xE4,0xD8,0x5D,0xD3,0xD0,0x6E,0x6F, 86 | 0x96,0xFB,0x5E,0xBC,0x56,0xC2,0x5F,0x85,0x9B,0xE7,0xAF,0xD2,0x3B,0x84,0x6A,0xA7, 87 | 0x53,0xC5,0x44,0x49,0xA5,0xF9,0x36,0x72,0x3D,0x2C,0xD9,0x1B,0xA1,0xF5,0x4F,0x93, 88 | 0x9D,0x68,0x47,0x41,0x16,0xCA,0x2A,0x4C,0xA3,0x87,0xD6,0xE5,0x19,0x2E,0x77,0x15, 89 | 0x6D,0x70,0xC0,0xDF,0xB2, 0,0x46,0xED,0xC6,0x6C,0x43,0x60,0x92,0x2D,0xA9,0x22, 90 | 0x45,0x8F,0x34,0x55,0xAE,0xA4, 0xA,0x66,0x32,0xE0,0xDC, 2,0xAC,0xE8,0x20,0x8C, 91 | 0x89,0x62,0x4A,0xFE,0xEE,0xC3,0xE3,0x3C,0xF1,0x79, 5,0xE9,0xF6,0x27,0x33,0xCC, 92 | 0xF2,0x9E,0x11,0x81,0x7E,0x80,0x10,0x8A,0x82,0x9F,0x48, 0xD,0xD7,0xB4,0xFC,0x2F, 93 | 0xB5,0xC7,0xDD,0x88,0x14,0x6B,0x2B,0x54,0xEA,0x1D,0x94,0x5C,0xB0,0xEF,0x12,0x24, 94 | 0xCD,0xEB,0xE1,0xE2,0x64,0x73,0x3F, 0xE,0x52,0x61,0x25,0x3E,0xF8, 0xF,0x4B,0xEC, 95 | }, 96 | { 97 | 0xC0, 0,0x30,0xF6, 2,0x49,0x3D,0x10,0x6E,0x20,0xC9,0xA6,0x2F,0xFE,0x2C,0x2B, 98 | 0x75,0x2E,0x45,0x26,0xAB,0x48,0xA9,0x80,0xFC, 4,0xCC,0xD3,0xB5,0xBA,0xA3,0x38, 99 | 0x31,0x7D, 1,0xD9,0xA7,0x7B,0x96,0xB6,0x63,0x69,0x4E,0xF7,0xDE,0xE0,0x78,0xCA, 100 | 0x50,0xAA,0x41,0x91,0x65,0x88,0xE4,0x21,0x85,0xDA,0x3A,0x27,0xBE,0x1C,0x3E,0x42, 101 | 0x5E,0x17,0x52,0x7F,0x1F,0x89,0x24,0x6F,0x8F,0x5C,0x67,0x74, 0xE,0x12,0x87,0x8D, 102 | 0xE9,0x34,0xED,0x73,0xC4,0xF8,0x61,0x5B, 5,0xDF,0x59,0x4C,0x97,0x79,0x83,0x18, 103 | 0xA4,0x55,0x95,0xEB,0xBD,0x53,0xF5,0xF1,0x57,0x66,0x46,0x9F,0xB2,0x81, 9,0x51, 104 | 0x86,0x22,0x16,0xDD,0x23,0x93,0x76,0x29,0xC2,0xD7,0x1D,0xD4,0xBF,0x36,0x3F,0xEA, 105 | 0x4B,0x11,0x32,0xB9,0x62,0x54,0x60,0xD6,0x6D,0x43,0x9A, 0xD,0x92,0x9C,0xB0,0xEF, 106 | 0x58,0x6C,0x9D,0x77,0x2D,0x70,0xFA,0xF3,0xB3, 0xB,0xE2,0x40,0x7E,0xF4,0x8A,0xE5, 107 | 0x8C,0x3C,0x56,0x71,0xD1,0x64,0xE1,0x82, 0xA,0xCB,0x13,0x15,0x90,0xEC, 3,0x99, 108 | 0xAF,0x14,0x5D, 0xF,0x33,0x4A,0x94,0xA5,0xA8,0x35,0x1B,0xE3,0x6A,0xC6,0x28,0xFF, 109 | 0x4D,0xE7,0x25,0x84,0xAC, 8,0xAE,0xC5,0xA2,0x2A,0xB8,0x37, 0xC,0x7A,0xA0,0xC3, 110 | 0xCE,0xAD, 6,0x1A,0x9E,0x8B,0xFB,0xD5,0xD0,0xC1,0x1E,0xD0,0xB4,0x9B,0xB1,0x44, 111 | 0xF2,0x47,0xC7,0x68,0xCF,0x72,0xBB,0x4F,0x5A,0xF9,0xDC,0x6B,0xDB,0xD2,0xE8,0x7C, 112 | 0xC8,0xEE,0x98,0xA1,0xE6,0xD8,0x39, 7,0x5F,0xFD,0x8E,0x19,0xB7,0x3B,0xBC,0xCD, 113 | }, 114 | { 115 | 0x7C,0xE3,0x81,0x73,0xB2,0x11,0xBF,0x6F,0x20,0x98,0xFE,0x75,0x96,0xEF,0x6C,0xDA, 116 | 0x50,0xE1, 9,0x72,0x54,0x45,0xBA,0x34,0x80,0x5B,0xED,0x3E,0x53,0x2C,0x87,0xA4, 117 | 0x57,0xF3,0x33,0x3F,0x3C,0xB7,0x67,0xB4,0xA3,0x25,0x60,0x4F, 7,0x6B,0x1B,0x47, 118 | 0x15, 0xF,0xE4, 0xA,0xEA,0xD1,0x32,0x78,0x36,0x49,0x8D,0x4B,0xD2,0xBC,0xA5,0xDC, 119 | 0x1D, 0xD,0x4D,0xCD,0x9A,0x82,0x5F,0xFC,0x94,0x65,0xBE,0xE2,0xF4,0xC9,0x1E,0x44, 120 | 0xCB,0x9E, 0xC,0x64,0x71,0x26,0x63,0xB3,0x14,0xE8,0x40,0x70,0x8A, 0xE,0x19,0x42, 121 | 0x6D,0xAC,0x88,0x10,0x5C,0xDF,0x41,0xA9,0xAD,0xE5,0xFB,0x74,0xCC,0xD5, 6,0x8E, 122 | 0x59,0x86,0xCE,0x1F,0x3D,0x76,0xE0,0x8F,0xB9,0x77,0x27,0x7B,0xA6,0xD8,0x29,0xD3, 123 | 0xEC,0xB8,0x13,0xF7,0xFA,0xC3,0x51,0x6A,0xDE,0x4A,0x5A,0xEB,0xC2,0x8B,0x23,0x48, 124 | 0x92,0xCF,0x62,0xA8,0x99,0xF8,0xD0,0x2E,0x85,0x61,0x43,0xC8,0xBD,0xF0, 5,0x93, 125 | 0xCA,0x4E,0xF1,0x7D,0x30,0xFD,0xC4,0x69,0x66,0x2F, 8,0xB1,0x52,0xF9,0x21,0xE6, 126 | 0x7A,0x2B,0xDD,0x39,0x84,0xFF,0xC0,0x91,0xD6,0x37,0xD4,0x7F,0x2D,0x9B,0x5D,0xA1, 127 | 0x3B,0x6E,0xB5,0xC5,0x46, 4,0xF5,0x90,0xEE,0x7E,0x83,0x1C, 3,0x56,0xB6,0xAA, 128 | 0,0x17, 1,0x35,0x55,0x79, 0xB,0x12,0xBB,0x1A,0x31,0xE7, 2,0x28,0x16,0xC1, 129 | 0xF6,0xA2,0xDB,0x18,0x9C,0x89,0x68,0x38,0x97,0xAB,0xC7,0x2A,0xD7,0x3A,0xF2,0xC6, 130 | 0x24,0x4C,0xB0,0x58,0xA0,0x22,0x5E,0x9D,0xD9,0xA7,0xE9,0xAE,0xAF,0x8C,0x95,0x9F, 131 | }, 132 | { 133 | 0x28,0xB7,0x20,0xD7,0xB0,0x30,0xC3, 9,0x19,0xC0,0x67,0xD6, 0,0x3C,0x7E,0xE7, 134 | 0xE9,0xF4, 8,0x5A,0xF8,0xB8,0x2E, 5,0xA6,0x25,0x9E,0x5C,0xD8,0x15, 0xD,0xE1, 135 | 0xF6,0x11,0x54,0x6B,0xCD,0x21,0x46,0x66,0x5E,0x84,0xAD, 6,0x38,0x29,0x44,0xC5, 136 | 0xA2,0xCE,0xF1,0xAA,0xC1,0x40,0x71,0x86,0xB5,0xEF,0xFC,0x36,0xA8,0xCB, 0xA,0x48, 137 | 0x27,0x45,0x64,0xA3,0xAF,0x8C,0xB2,0xC6,0x9F, 7,0x89,0xDC,0x17,0xD3,0x49,0x79, 138 | 0xFB,0xFE,0x1D,0xD0,0xB9,0x88,0x43,0x52,0xBC, 1,0x78,0x2B,0x7D,0x94,0xC7, 0xE, 139 | 0xDE,0xA5,0xD5,0x9B,0xCC,0xF7,0x61,0x7A,0xC2,0x74,0x81,0x39, 3,0xAB,0x96,0xA0, 140 | 0x37,0xBD,0x2D,0x72,0x75,0x3F,0xC9,0xD4,0x8E,0x6F,0xF9,0x8D,0xED,0x62,0xDB,0x1C, 141 | 0xDF, 4,0xAC,0x1B,0x6C,0x14,0x4B,0x63,0xD0,0xBF,0xB4,0x82,0xEC,0x7B,0x1A,0x59, 142 | 0x92,0xD2,0x10,0x60,0xB6,0x3D,0x5F,0xE6,0x80,0x6E,0x70,0xC4,0xF2,0x35,0xD9,0x7C, 143 | 0xEE,0xE5,0x41,0xA4,0x5B,0x50,0xDD,0xBB,0x4C,0xF3,0x1F,0x9D,0x5D,0x57,0x55,0x51, 144 | 0x97,0xE3,0x58,0x42,0x4D,0x9C,0x73,0xBA,0xC8,0x77,0x31,0x69,0x26,0xAE,0xEA,0x8A, 145 | 0xDA,0x22,0xB3,0x87,0x56,0xFA,0x93, 0xB,0x34,0x16,0x33,0xE8,0xE4,0x53,0xBE,0xA9, 146 | 0xB1,0x3A,0x3E,0xF5,0x90,0x6A,0xCF,0x3B,0x12,0xFD,0x8F,0x9A,0xA7,0x47,0x91,0x99, 147 | 0xEB, 0xF,0x24,0xFF,0x23,0x18,0x85,0x4E,0x7F, 0xC,0xE0,0xA1,0xD2,0xD1,0x2C,0x2A, 148 | 0x4A, 2,0x4F,0x1E,0x95,0x68,0x8B,0x98,0x83,0x6D,0x76,0xCA,0x65,0x32,0x13,0x2F, 149 | }, 150 | { 151 | 0xC3,0x82,0x9A,0xA4,0xBA,0x81,0x60,0x37,0x34,0x35,0xFC,0x80,0xA8,0x51,0x65,0x67, 152 | 0xED,0x30,0x5F,0x10,0xD3,0x4A,0x27,0x2F,0x13,0xB9,0x2A,0xD2,0xCC,0xE1,0xEF,0xAE, 153 | 0xEB,0xBE,0xF4,0xBD,0xCF,0x43,0xB3,0xC5,0x88,0x84,0xB7,0xDD,0x39,0x40,0xCE,0x48, 154 | 0x6D,0x9B,0x72,0x61,0x7E,0xE7,0xA1,0x4E,0x53,0x2E,0x77,0x3B,0xE2,0xC9,0x36,0x22, 155 | 0x1B,0x6E,0x73,0xB1, 3,0xB2,0x4C,0x87,0xA9,0xD4,0x4D, 0xF,0xD8,0x15,0x6C,0xAA, 156 | 0x18,0xF6,0x49,0x57,0x5D,0xFB,0x7A,0x14,0x94,0x63,0xA0,0x11,0xB0,0x9E,0xDE, 5, 157 | 0x46,0xC8,0xEE,0x47,0xDB,0xDC,0x24,0x89,0x9C,0x91,0x97,0x29,0xE9,0x7B,0xC1, 7, 158 | 0x1E,0xB8,0xFD,0xFE,0xAC,0xC6,0x62,0x98,0x4F,0xF1,0x79,0xE0,0xE8,0x6B,0x78,0x56, 159 | 0xB6,0x8D, 4,0x50,0x86,0xCA,0x6F,0x20,0xE6,0xEA,0xE5,0x76,0x17,0x1C,0x74,0x7F, 160 | 0xBC, 0xD,0x2C,0x85,0xF7,0x66,0x96,0xE4,0x8B,0x75,0x3F,0x4B,0xD9,0x38,0xAF,0x7C, 161 | 0xDA, 0xB,0x83,0x2D,0x31,0x32,0xA2,0xF5,0x1D,0x59,0x41,0x45,0xBF,0x3C,0x1F,0xF8, 162 | 0xF9,0x8A,0xD0,0x16,0x25,0x69,0x12,0x99,0x9D,0x21,0x95,0xAB, 1,0xA6,0xD7,0xB5, 163 | 0xC0,0x7D,0xFF,0x58, 0xE,0x3A,0x92,0xD1,0x55,0xE3, 8,0x9F,0xD6,0x3E,0x52,0x8E, 164 | 0xFA,0xA3,0xC7, 2,0xCD,0xDF,0x8F,0x64,0x19,0x8C,0xF3,0xA7, 0xC,0x5E, 0xA,0x6A, 165 | 9,0xF0,0x93,0x5B,0x42,0xC2, 6,0x23,0xEC,0x71,0xAD,0xB4,0xCB,0xBB,0x70,0x28, 166 | 0xD5,0x1A,0x5C,0x33,0x68,0x5A, 0,0x44,0x90,0xA5,0xC4,0x26,0x3D,0x2B,0xF2,0x54, 167 | }, 168 | { 169 | 0x96,0xAD,0xDA,0x1F,0xED,0x33,0xE1,0x81,0x69, 8, 0xD, 0xA,0xDB,0x35,0x77,0x9A, 170 | 0x64,0xD1,0xFC,0x78,0xAA,0x1B,0xD0,0x67,0xA0,0xDD,0xFA,0x6C,0x63,0x71, 5,0x84, 171 | 0x17,0x6A,0x89,0x4F,0x66,0x7F,0xC6,0x50,0x55,0x92,0x6F,0xBD,0xE7,0xD2,0x40,0x72, 172 | 0x8D,0xBB,0xEC, 6,0x42,0x8A,0xE4,0x88,0x9D,0x7E,0x7A,0x82,0x27,0x13,0x41,0x1A, 173 | 0xAF,0xC8,0xA4,0x76,0xB4,0xC2,0xFE,0x6D,0x1C,0xD9,0x61,0x30,0xB3,0x7C,0xEA,0xF7, 174 | 0x29, 0xF,0xF2,0x3B,0x51,0xC1,0xDE,0x5F,0xE5,0x2A,0x2F,0x99, 0xB,0x5D,0xA3,0x2B, 175 | 0x4A,0xAB,0x95,0xA5,0xD3,0x58,0x56,0xEE,0x28,0x31, 0,0xCC,0x15,0x46,0xCA,0xE6, 176 | 0x86,0x38,0x3C,0x65,0xF5,0xE3,0x9F,0xD6,0x5B, 9,0x49,0x83,0x70,0x2D,0x53,0xA9, 177 | 0x7D,0xE2,0xC4,0xAC,0x8E,0x5E,0xB8,0x25,0xF4,0xB9,0x57,0xF3,0xF1,0x68,0x47,0xB2, 178 | 0xA2,0x59,0x20,0xCE,0x34,0x79,0x5C,0x90, 0xE,0x1E,0xBE,0xD5,0x22,0x23,0xB1,0xC9, 179 | 0x18,0x62,0x16,0x2E,0x91,0x3E, 7,0x8F,0xD8,0x3F,0x93,0x3D,0xD4,0x9B,0xDF,0x85, 180 | 0x21,0xFB,0x11,0x74,0x97,0xC7,0xD7,0xDC,0x4C,0x19,0x45,0x98,0xE9,0x43, 2,0x4B, 181 | 0xBC,0xC3, 4,0x9C,0x6B,0xF0,0x75,0x52,0xA7,0x26,0xF6,0xC5,0xBA,0xCF,0xB0,0xB7, 182 | 0xAE,0x5A,0xA1,0xBF, 3,0x8B,0x80,0x12,0x6E, 0xC,0xEB,0xF9,0xC0,0x44,0x24,0xEF, 183 | 0x10,0xF8,0xA8,0x8C,0xE8,0x7B,0xFF,0x9E,0x2C,0xCD,0x60,0x36,0x87,0xB5,0x94,0xA6, 184 | 0x54,0x73,0x3A,0x14,0x4E, 1,0x1D,0xB6,0xFD,0x37,0x48,0x4D,0x39,0xCB,0xE0,0x32, 185 | } 186 | }; 187 | 188 | #define wm_crypto_h 189 | #endif 190 | --------------------------------------------------------------------------------