wii_anal_lcd.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include "wii_anal.h"
  2. #include "gfx/images.h" // Images
  3. //----------------------------------------------------------------------------- ----------------------------------------
  4. // A couple of monospaced hex fonts
  5. //
  6. const image_t* img_6x8[16] = {
  7. &img_6x8_0, &img_6x8_1, &img_6x8_2, &img_6x8_3, &img_6x8_4, &img_6x8_5, &img_6x8_6, &img_6x8_7,
  8. &img_6x8_8, &img_6x8_9, &img_6x8_A, &img_6x8_B, &img_6x8_C, &img_6x8_D, &img_6x8_E, &img_6x8_F,
  9. };
  10. const image_t* img_5x7[16] = {
  11. &img_5x7_0, &img_5x7_1, &img_5x7_2, &img_5x7_3, &img_5x7_4, &img_5x7_5, &img_5x7_6, &img_5x7_7,
  12. &img_5x7_8, &img_5x7_9, &img_5x7_A, &img_5x7_B, &img_5x7_C, &img_5x7_D, &img_5x7_E, &img_5x7_F,
  13. };
  14. //+============================================================================ ========================================
  15. // void backlightOn (void)
  16. // {
  17. // // Acquire a handle for the system notification queue
  18. // // Do this ONCE ... at plugin startup
  19. // NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION);
  20. //
  21. // // Pat the backlight watchdog
  22. // // Send the (predefined) message sequence {backlight_on, end}
  23. // // --> applications/notification/*.c
  24. // notification_message(notifications, &sequence_display_backlight_on);
  25. //
  26. // // Release the handle for the system notification queue
  27. // // Do this ONCE ... at plugin quit
  28. // furi_record_close(RECORD_NOTIFICATION);
  29. // }
  30. void patBacklight (state_t* state)
  31. {
  32. notification_message(state->notify, &sequence_display_backlight_on);
  33. }
  34. //============================================================================= ========================================
  35. // Show a hex number in an inverted box (for ananlogue readings)
  36. //
  37. void showHex ( Canvas* const canvas, uint8_t x, uint8_t y,
  38. const uint32_t val, const uint8_t cnt, const int b )
  39. {
  40. canvas_set_color(canvas, ColorBlack);
  41. canvas_draw_box(canvas, x++,y++, 1 +(cnt *(6 +1)), 10);
  42. // thicken border
  43. if (b == 2) canvas_draw_frame(canvas, x-2,y-2, 1 +(cnt *(6 +1))+2, 10+2);
  44. for (int i = (cnt -1) *4; i >= 0; i -= 4, x += 6+1)
  45. show(canvas, x,y, img_6x8[(val >>i) &0xF], SHOW_SET_WHT) ;
  46. }
  47. //============================================================================= ========================================
  48. // Show the up/down "peak hold" controls in the bottom right
  49. //
  50. void showPeakHold (state_t* const state, Canvas* const canvas, const int hold)
  51. {
  52. switch (hold) {
  53. case 0:
  54. show(canvas, 119,51, &img_key_U, SHOW_CLR_BLK);
  55. show(canvas, 119,56, &img_key_D, SHOW_CLR_BLK);
  56. break;
  57. case +1:
  58. canvas_set_color(canvas, ColorBlack);
  59. canvas_draw_box(canvas, 120,52, 7,6);
  60. show(canvas, 119,51, &img_key_U, SHOW_CLR_WHT);
  61. show(canvas, 119,56, &img_key_D, SHOW_CLR_BLK);
  62. break;
  63. case -1:
  64. show(canvas, 119,51, &img_key_U, SHOW_CLR_BLK);
  65. canvas_draw_box(canvas, 120,57, 7,6);
  66. show(canvas, 119,56, &img_key_D, SHOW_CLR_WHT);
  67. break;
  68. default:
  69. break;
  70. }
  71. canvas_set_color(canvas, ColorBlack);
  72. canvas_draw_frame(canvas, 119,51, 9,13);
  73. // calibration indicator
  74. show( canvas, 108,55,
  75. ((state->calib & CAL_RANGE) && (++state->flash &8)) ? &img_key_OKi : &img_key_OK,
  76. SHOW_SET_BLK );
  77. }
  78. //============================================================================= ========================================
  79. // This code performs a FULL calibration on the device EVERY time it draws a joystick
  80. //...This is NOT a good way forward for anything other than a test tool.
  81. //
  82. // Realistically you would do all the maths when the controller is connected
  83. // or, if you prefer (and it IS a good thing), have a "calibrate controller" menu option
  84. // ...and then just use a lookup table, or trivial formual
  85. //
  86. // THIS algorithm chops the joystick in to one of 9 zones
  87. // Eg. {FullLeft, Left3, Left2, Left1, Middle, Right1, Right2, Right3, FullRight}
  88. // FullLeft and FullRight have a deadzone of N [qv. xDead] ..a total of N+1 positions
  89. // Middle has a deadzone of N EACH WAY ...a total of 2N+1 positions
  90. //
  91. // If the remaining range does not divide evenly in to three zones,
  92. // the first remainder is added to zone3,
  93. // and the second remainder (if there is one) is added to zone2
  94. // ...giving finer control near the centre of the joystick
  95. //
  96. // The value of the deadzone is based on the number of bits in the
  97. // joystcik {x,y} values - the larger the range, the larger the deadzone.
  98. //
  99. // 03 15 29
  100. // |<<| Calibration points |==| |>>|
  101. // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
  102. // |---| |________________________| |------| |______________________________| |---|
  103. // |r=2| | range = 9 | | r=3 | | range = 11 | |r=2|
  104. // Zones: |-4 | |-3 |-2 |-1 | |0 | |+1 |+2 |+3 | |+4 |
  105. //
  106. // This is not "the right way to do it" ...this is "one way to do it"
  107. // Consider you application, and what the user is trying to achieve
  108. // Aim a gun - probably need to be more accurate
  109. // Turn and object - this is probably good enough
  110. // Start slowly & pick up speed - how about a log or sine curve?
  111. //
  112. void showJoy ( Canvas* const canvas, const uint8_t x, const uint8_t y, // x,y is the CENTRE of the Joystick
  113. const uint8_t xMin, const uint8_t xMid, const uint8_t xMax,
  114. const uint8_t yMin, const uint8_t yMid, const uint8_t yMax,
  115. const uint8_t xPos, const uint8_t yPos, const uint8_t bits )
  116. {
  117. int xOff = 0; // final offset of joystick hat image
  118. int yOff = 0;
  119. int xDead = (bits < 7) ? (1<<0) : (1<<3); // dead zone (centre & limits)
  120. int yDead = xDead;
  121. // This code is NOT optimised ...and it's still barely readable!
  122. if ((xPos >= (xMid -xDead)) && (xPos <= (xMid +xDead))) xOff = 0 ; // centre [most likely]
  123. else if (xPos <= (xMin +xDead)) xOff = -4 ; // full left
  124. else if (xPos >= (xMax -xDead)) xOff = +4 ; // full right
  125. else if (xPos < (xMid -xDead)) { // part left
  126. // very much hard-coded for 3 interim positions
  127. int lo = (xMin +xDead) +1; // lowest position
  128. int hi = (xMid -xDead) -1; // highest position
  129. // this is the only duplicated bit of code
  130. int range = (hi -lo) +1; // range covered
  131. int div = range /3; // each division (base amount, eg. 17/3==5)
  132. int rem = range -(div *3); // remainder (ie. range%3)
  133. // int hi1 = hi; // lowest value for zone #-1
  134. // int lo1 = hi1 -div +1; // highest value for zone #-1
  135. // int hi2 = lo1 -1; // lowest value for zone #-2
  136. // int lo2 = hi2 -div +1 -(rem==2); // highest value for zone #-2 expand out remainder
  137. // int hi3 = lo2 -1; // lowest value for zone #-3
  138. // int lo3 = hi3 -div +1 -(rem>=1); // highest value for zone #-3 expand out remainder
  139. int lo1 = hi -div +1; // (in brevity)
  140. int hi3 = hi -div -div -(rem==2); // ...
  141. if (xPos <= hi3) xOff = -3 ; // zone #-3
  142. else if (xPos >= lo1) xOff = -1 ; // zone #-1
  143. else xOff = -2 ; // zone #-2
  144. } else /*if (xPos > (xMid +xDead))*/ { // part right
  145. // very much hard-coded for 3 interim positions
  146. int lo = (xMid +xDead) +1; // lowest position
  147. int hi = (xMax -xDead) -1; // highest position
  148. int range = (hi -lo) +1; // range covered
  149. int div = range /3; // each division (base amount, eg. 17/3==5)
  150. int rem = range -(div *3); // remainder (ie. range%3)
  151. // int lo1 = lo; // lowest value for zone #+1
  152. // int hi1 = lo +div -1; // highest value for zone #+1
  153. // int lo2 = hi1 +1; // lowest value for zone #+2
  154. // int hi2 = lo2 +div -1 +(rem==2); // highest value for zone #+2 expand out remainder
  155. // int lo3 = hi2 +1; // lowest value for zone #+3
  156. // int hi3 = lo3 +div -1 +(rem>=1); // highest value for zone #+3 expand out remainder
  157. int hi1 = lo +div -1; // (in brevity)
  158. int lo3 = lo +div +div +(rem==2); // ...
  159. if (xPos <= hi1) xOff = 1 ; // zone #1
  160. else if (xPos >= lo3) xOff = 3 ; // zone #3
  161. else xOff = 2 ; // zone #2
  162. }
  163. // All this to print a 3x3 square (in the right place) - LOL!
  164. if ((yPos >= (yMid -yDead)) && (yPos <= (yMid +yDead))) yOff = 0 ; // centre [most likely]
  165. else if (yPos <= (yMin +yDead)) yOff = +4 ; // full down
  166. else if (yPos >= (yMax -yDead)) yOff = -4 ; // full up
  167. else if (yPos < (yMid -yDead)) { // part down
  168. int lo = (yMin +yDead) +1; // lowest position
  169. int hi = (yMid -yDead) -1; // highest position
  170. int range = (hi -lo) +1; // range covered
  171. int div = range /3; // each division (base amount, eg. 17/3==5)
  172. int rem = range -(div *3); // remainder (ie. range%3)
  173. int lo1 = hi -div +1; // (in brevity)
  174. int hi3 = hi -div -div -(rem==2); // ...
  175. if (yPos <= hi3) yOff = +3 ; // zone #3
  176. else if (yPos >= lo1) yOff = +1 ; // zone #1
  177. else yOff = +2 ; // zone #2
  178. } else /*if (yPos > (yMid +yDead))*/ { // part up
  179. int lo = (yMid +yDead) +1; // lowest position
  180. int hi = (yMax -yDead) -1; // highest position
  181. int range = (hi -lo) +1; // range covered
  182. int div = range /3; // each division (base amount, eg. 17/3==5)
  183. int rem = range -(div *3); // remainder (ie. range%3)
  184. int hi1 = lo +div -1; // (in brevity)
  185. int lo3 = lo +div +div +(rem==2); // ...
  186. if (yPos <= hi1) yOff = -1 ; // zone #-1
  187. else if (yPos >= lo3) yOff = -3 ; // zone #-3
  188. else yOff = -2 ; // zone #-2
  189. }
  190. show(canvas, x-(img_cc_Joy.w/2),y-(img_cc_Joy.h/2), &img_cc_Joy, SHOW_SET_BLK);
  191. // All ^that^ for v-this-v - LOL!!
  192. canvas_draw_box(canvas, (x-1)+xOff,(y-1)+yOff, 3,3);
  193. }