Advertisement
SlaskPrask

asdf

Oct 1st, 2019
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.23 KB | None | 0 0
  1. #include <HID-Project.h>
  2. #include <HID-Settings.h>
  3.  
  4. #define PIN_READ (PIND & 0x01)
  5. #define MICROSECOND_NOPS "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
  6.  
  7. #define WAIT_FALLING_EDGE while( !PIN_READ ); while( PIN_READ );
  8.  
  9. #define N64_PIN 3
  10. #define N64_PREFIX 9
  11. #define N64_BITCOUNT 32
  12.  
  13.  
  14. #define ZERO '0' // Use a byte value of 0x00 to represent a bit with value 0.
  15. #define ONE '1' // Use an ASCII one to represent a bit with value 1. This makes Arduino debugging easier.
  16. #define SPLIT '\n' // Use a new-line character to split up the controller state packets.
  17.  
  18. // Declare some space to store the bits we read from a controller.
  19. unsigned char rawData[ 128 ];
  20.  
  21.  
  22. struct state {
  23. char stick_x;
  24. char stick_y;
  25. // bits: 0, 0, 0, start, y, x, b, a
  26. unsigned char data1;
  27. // bits: 1, L, R, Z, Dup, Ddown, Dright, Dleft
  28. unsigned char data2;
  29. } N64_status;
  30.  
  31. void translate_raw_data()
  32. {
  33. memset(&N64_status, 0, sizeof(N64_status));
  34. for (int i = 0; i < 8; i++) {
  35. N64_status.data1 |= rawData[9 + i] ? (0x80 >> i) : 0;
  36. N64_status.data2 |= rawData[17 + i] ? (0x80 >> i) : 0;
  37. N64_status.stick_x |= rawData[25 + i] ? (0x80 >> i) : 0;
  38. N64_status.stick_y |= rawData[33 + i] ? (0x80 >> i) : 0;
  39. }
  40. }
  41.  
  42.  
  43. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  44. // General initialization, just sets all pins to input and starts serial communication.
  45. void setup()
  46. {
  47. Serial.begin( 9600 );
  48.  
  49. digitalWrite(N64_PIN, LOW);
  50. pinMode(N64_PIN, INPUT);
  51. Gamepad.begin();
  52. }
  53.  
  54. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  55. // Performs a read cycle from one of Nintendo's one-wire interface based controllers.
  56. // This includes the N64 and the Gamecube.
  57. // pin = Pin index on Port D where the data wire is attached.
  58. // bits = Number of bits to read from the line.
  59. void read_oneWire( unsigned char bits )
  60. {
  61. unsigned char *rawDataPtr = rawData;
  62.  
  63. read_loop:
  64.  
  65. // Wait for the line to go high then low.
  66. WAIT_FALLING_EDGE;
  67.  
  68. // Wait ~2us between line reads
  69. asm volatile( MICROSECOND_NOPS MICROSECOND_NOPS );
  70.  
  71. // Read a bit from the line and store as a byte in "rawData"
  72. *rawDataPtr = PIN_READ;
  73. ++rawDataPtr;
  74. if( --bits == 0 ) return;
  75.  
  76. goto read_loop;
  77. }
  78.  
  79. // Verifies that the 9 bits prefixing N64 controller data in 'rawData'
  80. // are actually indicative of a controller state signal.
  81. inline bool checkPrefixN64 ()
  82. {
  83. if( rawData[0] != 0 ) return false; // 0
  84. if( rawData[1] != 0 ) return false; // 0
  85. if( rawData[2] != 0 ) return false; // 0
  86. if( rawData[3] != 0 ) return false; // 0
  87. if( rawData[4] != 0 ) return false; // 0
  88. if( rawData[5] != 0 ) return false; // 0
  89. if( rawData[6] != 0 ) return false; // 0
  90. if( rawData[7] == 0 ) return false; // 1
  91. if( rawData[8] == 0 ) return false; // 1
  92. return true;
  93. }
  94.  
  95. void print_N64_status()
  96. {
  97. char out[64];
  98. sprintf(out, "%i%i%i%i%i%i%i%i %i%i%i%i%i%i%i%i %i %i",
  99. N64_status.data1&128?1:0, //A
  100. N64_status.data1&64?1:0, //B
  101. N64_status.data1&32?1:0, //Z
  102. N64_status.data1&16?1:0, //Start
  103. N64_status.data1&8?1:0, //Du
  104. N64_status.data1&4?1:0, //Dd
  105. N64_status.data1&2?1:0, //Dl
  106. N64_status.data1&1?1:0, //Dr
  107.  
  108. N64_status.data2&128?1:0, //Reset
  109. 0,
  110. N64_status.data2&32?1:0, //L
  111. N64_status.data2&16?1:0, //R
  112. N64_status.data2&8?1:0, //Cu
  113. N64_status.data2&4?1:0, //Cd
  114. N64_status.data2&2?1:0, //Cl
  115. N64_status.data2&1?1:0, //Cr
  116.  
  117.  
  118. N64_status.stick_x,
  119. N64_status.stick_y);
  120. Serial.println(out);
  121. }
  122.  
  123. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  124. // Arduino sketch main loop definition.
  125. void loop()
  126. {
  127. noInterrupts();
  128. read_oneWire( N64_PREFIX + N64_BITCOUNT );
  129. interrupts();
  130.  
  131. if( checkPrefixN64() )
  132. {
  133. translate_raw_data();
  134. print_N64_status();
  135. update_joystick();
  136. Gamepad.write();
  137. }
  138.  
  139.  
  140. }
  141.  
  142. void update_joystick()
  143. {
  144. int i;
  145.  
  146. signed char jx=0,jy=0;
  147. jx|=(unsigned char)N64_status.stick_x;
  148. jy|=(unsigned char)N64_status.stick_y;
  149. float JX=jx;
  150. float JY=-jy;
  151. Gamepad.xAxis(4096 * 4 + JX);
  152. Gamepad.yAxis(4096 * 4 + JY);
  153.  
  154. for(i=0;i<8;i++)
  155. {
  156. if (rawData[i+9])
  157. Gamepad.press(i+1);
  158. else
  159. Gamepad.release(i+1);
  160. }
  161.  
  162. for(i=0;i<6;i++)
  163. {
  164. if (rawData[19+i])
  165. Gamepad.press(i+9);
  166. else
  167. Gamepad.release(i+9);
  168. }
  169.  
  170. unsigned char pov_byte=N64_status.data1&0x0F;
  171. int pov=-1;
  172. switch (pov_byte)
  173. {
  174. default: //Centered
  175. pov=0;
  176. break;
  177. case 1: //RIGHT
  178. pov=3;
  179. break;
  180. case 2: //LEFT
  181. pov=7;
  182. break;
  183. case 4: //DOWN
  184. pov=5;
  185. break;
  186. case 8: //UP
  187. pov=1;
  188. break;
  189. case 10: //UP-LEFT
  190. pov=8;
  191. break;
  192. case 6: //DOWN-LEFT
  193. pov=6;
  194. break;
  195. case 9: //UP-RIGHT
  196. pov=2;
  197. break;
  198. case 5: //DOWN-RIGHT
  199. pov=4;
  200. break;
  201. }
  202. Gamepad.dPad1(pov);
  203.  
  204. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement