Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Updated to Myles' TVout beta. Added Classic Controller compatibility.…

… Added nunchuck compatibility, and music, to Myles' Tetris implementation. Updated example sketches to work with the new TVout beta.
  • Loading branch information...
commit 15c0a6ac6ad90994dcce7068eb168ba1748f93cf 1 parent 8b43f07
Adam authored

Showing 69 changed files with 6,552 additions and 2,484 deletions. Show diff stats Hide diff stats

  1. +335 0 ClassicController/ClassicController.cpp
  2. +175 0 ClassicController/ClassicController.h
  3. +9 0 ClassicController/README
  4. +174 0 ClassicController/examples/classic_controller_demo/classic_controller_demo.pde
  5. +44 0 ClassicController/keywords.txt
  6. +6 3 Nunchuck/README
  7. +22 3 Nunchuck/examples/nunchuck_demo/nunchuck_demo.pde
  8. +14 13 Nunchuck/nunchuck.cpp
  9. +9 9 Nunchuck/nunchuck.h
  10. +1 1  README
  11. +877 0 TVout/TVout.cpp
  12. +177 0 TVout/TVout.h
  13. +380 0 TVout/TVoutPrint.cpp
  14. +217 0 TVout/examples/DemoNTSC/DemoNTSC.pde
  15. +37 0 TVout/examples/DemoNTSC/TVOlogo.cpp
  16. +6 0 TVout/examples/DemoNTSC/TVOlogo.h
  17. +101 0 TVout/examples/DemoNTSC/schematic.cpp
  18. +6 0 TVout/examples/DemoNTSC/schematic.h
  19. +217 0 TVout/examples/DemoPAL/DemoPAL.pde
  20. +37 0 TVout/examples/DemoPAL/TVOlogo.cpp
  21. +6 0 TVout/examples/DemoPAL/TVOlogo.h
  22. +101 0 TVout/examples/DemoPAL/schematic.cpp
  23. +6 0 TVout/examples/DemoPAL/schematic.h
  24. +4 3 {tvout → TVout}/examples/NTSCserialTerm/NTSCserialTerm.pde
  25. +50 0 TVout/keywords.txt
  26. 0  {tvout → TVout}/spec/asm_macros.h
  27. +23 8 {tvout → TVout}/spec/hardware_setup.h
  28. +1 0  {tvout → TVout}/spec/video_properties.h
  29. +17 0 {tvout → TVout}/version history.txt
  30. +35 20 {tvout → TVout}/video_gen.cpp
  31. +8 14 {tvout → TVout}/video_gen.h
  32. +671 0 TVoutfonts/font4x6.cpp
  33. +7 0 TVoutfonts/font4x6.h
  34. +104 2 tvout/fonts/ascii5x7.h → TVoutfonts/font6x8.cpp
  35. +8 0 TVoutfonts/font6x8.h
  36. +6 1 tvout/fonts/ascii8x8.h → TVoutfonts/font8x8.cpp
  37. +7 0 TVoutfonts/font8x8.h
  38. +261 0 TVoutfonts/font8x8ext.cpp
  39. +7 0 TVoutfonts/font8x8ext.h
  40. +9 0 TVoutfonts/fontALL.h
  41. +5 0 TVoutfonts/keywords.txt
  42. +49 40 VideoGameHelper/VideoGameHelper.cpp
  43. +67 0 VideoGameHelper/examples/tetris/bitmaps.cpp
  44. +7 0 VideoGameHelper/examples/tetris/bitmaps.h
  45. +45 0 VideoGameHelper/examples/tetris/platform.h
  46. +640 0 VideoGameHelper/examples/tetris/stc.cpp
  47. +253 0 VideoGameHelper/examples/tetris/stc.h
  48. +659 0 VideoGameHelper/examples/tetris/tetris.pde
  49. +436 0 VideoGameHelper/examples/tetris/tones.h
  50. +19 15 VideoGameHelper/examples/tv_2p_pong/tv_2p_pong.pde
  51. +13 12 VideoGameHelper/examples/tv_2p_test/tv_2p_test.pde
  52. +0 161 VideoGameHelper/examples/tv_audio_demo/tv_audio_demo.pde
  53. +13 11 VideoGameHelper/examples/tv_data_collection/tv_data_collection.pde
  54. +67 59 VideoGameHelper/examples/tv_life/help.pde
  55. +28 16 VideoGameHelper/examples/tv_life/tv_life.pde
  56. +32 26 VideoGameHelper/examples/tv_snake/tv_snake.pde
  57. +21 9 Nunchuck/utility/twimaster.c → i2cmaster/i2cmaster.cpp
  58. +23 12 {Nunchuck/utility → i2cmaster}/i2cmaster.h
  59. +0 205 tvout/Print.cpp
  60. +0 62 tvout/Print.h
  61. +0 884 tvout/TVout.cpp
  62. +0 146 tvout/TVout.h
  63. +0 96 tvout/bitmaps/demobmp.h
  64. +0 44 tvout/examples/DemoNTSC/DemoNTSC.pde
  65. +0 44 tvout/examples/DemoPAL/DemoPAL.pde
  66. +0 374 tvout/fonts/ascii3x5.h
  67. +0 32 tvout/keywords.txt
  68. +0 111 tvout/pollserial.cpp
  69. +0 48 tvout/pollserial.h
335 ClassicController/ClassicController.cpp
... ... @@ -0,0 +1,335 @@
  1 +/*
  2 + ClassicController.cpp - Library for the Nintendo Wii Classic Controller
  3 + Created by Adam Wolf and Matthew Beckler of Wayne and Layne, LLC
  4 + http://wayneandlayne.com/projects/video-game-shield/
  5 + Last updated: October 31, 2010
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 2 of the License, or
  10 + (at your option) any later version.
  11 +
  12 + This program is distributed in the hope that it will be useful,
  13 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + GNU General Public License for more details.
  16 +
  17 + You should have received a copy of the GNU General Public License along
  18 + with this program; if not, write to the Free Software Foundation, Inc.,
  19 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20 +
  21 + Some information taken from http://www.arduino.cc/playground/Main/WiiClassicController
  22 + */
  23 +
  24 +#include "WProgram.h" // needed for the arduino functions map() and constrain()
  25 +#include "ClassicController.h"
  26 +
  27 +#include <i2cmaster.h>
  28 +
  29 +// returns 0=success, 1=could not access device
  30 +// Provide a 0 or 1 to which_controller to specify which player this is
  31 +// 0 means "Player 1", 1 means "Player 2"
  32 +unsigned char ClassicController::begin(unsigned char which_controller)
  33 +{
  34 + // set default values
  35 + joy_left_left_max = CLASSICCONTROLLER_JOY_LEFT_MAX;
  36 + joy_left_right_min = CLASSICCONTROLLER_JOY_RIGHT_MIN;
  37 + joy_left_down_max = CLASSICCONTROLLER_JOY_DOWN_MAX;
  38 + joy_left_up_min = CLASSICCONTROLLER_JOY_UP_MIN;
  39 + joy_left_center_radius = CLASSICCONTROLLER_JOY_CENTER_RADIUS;
  40 +
  41 + joy_left_x_min = CLASSICCONTROLLER_JOY_X_MIN;
  42 + joy_left_x_max = CLASSICCONTROLLER_JOY_X_MAX;
  43 + joy_left_y_min = CLASSICCONTROLLER_JOY_Y_MIN;
  44 + joy_left_y_max = CLASSICCONTROLLER_JOY_Y_MAX;
  45 +
  46 + joy_left_x_scaled_min = CLASSICCONTROLLER_JOY_X_SCALED_MIN;
  47 + joy_left_x_scaled_max = CLASSICCONTROLLER_JOY_X_SCALED_MAX;
  48 + joy_left_y_scaled_min = CLASSICCONTROLLER_JOY_Y_SCALED_MIN;
  49 + joy_left_y_scaled_max = CLASSICCONTROLLER_JOY_Y_SCALED_MAX;
  50 +
  51 + // set default values
  52 + joy_right_left_max = CLASSICCONTROLLER_JOY_LEFT_MAX;
  53 + joy_right_right_min = CLASSICCONTROLLER_JOY_RIGHT_MIN;
  54 + joy_right_down_max = CLASSICCONTROLLER_JOY_DOWN_MAX;
  55 + joy_right_up_min = CLASSICCONTROLLER_JOY_UP_MIN;
  56 + joy_right_center_radius = CLASSICCONTROLLER_JOY_CENTER_RADIUS;
  57 +
  58 + joy_right_x_min = CLASSICCONTROLLER_JOY_X_MIN;
  59 + joy_right_x_max = CLASSICCONTROLLER_JOY_X_MAX;
  60 + joy_right_y_min = CLASSICCONTROLLER_JOY_Y_MIN;
  61 + joy_right_y_max = CLASSICCONTROLLER_JOY_Y_MAX;
  62 +
  63 + joy_right_x_scaled_min = CLASSICCONTROLLER_JOY_X_SCALED_MIN;
  64 + joy_right_x_scaled_max = CLASSICCONTROLLER_JOY_X_SCALED_MAX;
  65 + joy_right_y_scaled_min = CLASSICCONTROLLER_JOY_Y_SCALED_MIN;
  66 + joy_right_y_scaled_max = CLASSICCONTROLLER_JOY_Y_SCALED_MAX;
  67 +
  68 +
  69 + DDRB |= 0x10; // set DDRB4 bit = make it an output (used for controller select)
  70 + this_controller = which_controller;
  71 +
  72 + if (this_controller == WII_PLAYER_2)
  73 + WII_SELECT_P2;
  74 + else
  75 + WII_SELECT_P1;
  76 +
  77 + i2cmaster::i2c_init(); // this is non-blocking, it just sets up the baud rate generator and internal pullups
  78 + if (i2cmaster::i2c_start_wait(WII_I2C_ADDR + I2C_WRITE, 10) == 1)
  79 + {
  80 + // could not access device
  81 + return 1;
  82 + }
  83 + i2cmaster::i2c_write(0x40);
  84 + i2cmaster::i2c_write(0x00);
  85 + i2cmaster::i2c_stop();
  86 +
  87 + return 0;
  88 +}
  89 +
  90 +void ClassicController::update()
  91 +{
  92 + if (this_controller == WII_PLAYER_2)
  93 + WII_SELECT_P2;
  94 + else
  95 + WII_SELECT_P1;
  96 +
  97 + i2cmaster::i2c_start_wait(WII_I2C_ADDR + I2C_WRITE, 0xFFFF);
  98 + i2cmaster::i2c_write(0x00);
  99 + i2cmaster::i2c_stop();
  100 +
  101 + delayMicroseconds(1000); // TODO is this needed?
  102 +
  103 + i2cmaster::i2c_start_wait(WII_I2C_ADDR + I2C_READ, 0xFFFF);
  104 + for (unsigned char i = 0; i < 5; i++)
  105 + {
  106 + data[i] = _decode_byte(i2cmaster::i2c_readAck());
  107 + }
  108 + data[5] = _decode_byte(i2cmaster::i2c_readNak());
  109 + i2cmaster::i2c_stop();
  110 +}
  111 +
  112 +unsigned char* ClassicController::get_data()
  113 +{
  114 + return data;
  115 +}
  116 +
  117 +#define check_button(byte, bit) !((data[(byte)] >> (bit)) & 1)
  118 +
  119 +// Buttons
  120 +bool ClassicController::button_a()
  121 +{
  122 + return check_button(5, 4);
  123 +}
  124 +bool ClassicController::button_b()
  125 +{
  126 + return check_button(5, 6);
  127 +}
  128 +bool ClassicController::button_y()
  129 +{
  130 + return check_button(5, 5);
  131 +}
  132 +bool ClassicController::button_x()
  133 +{
  134 + return check_button(5, 3);
  135 +}
  136 +
  137 +// Top buttons
  138 +bool ClassicController::button_zr()
  139 +{
  140 + return check_button(5, 2);
  141 +}
  142 +bool ClassicController::button_zl()
  143 +{
  144 + return check_button(5, 7);
  145 +}
  146 +bool ClassicController::button_r()
  147 +{
  148 + return check_button(4, 1);
  149 +}
  150 +bool ClassicController::button_l()
  151 +{
  152 + return check_button(4, 5);
  153 +}
  154 +
  155 +// D-pad buttons
  156 +bool ClassicController::button_up()
  157 +{
  158 + return check_button(5, 0);
  159 +}
  160 +bool ClassicController::button_left()
  161 +{
  162 + return check_button(5, 1);
  163 +}
  164 +bool ClassicController::button_down()
  165 +{
  166 + return check_button(4, 6);
  167 +}
  168 +bool ClassicController::button_right()
  169 +{
  170 + return check_button(4, 7);
  171 +}
  172 +
  173 +// Middle buttons
  174 +bool ClassicController::button_plus_start()
  175 +{
  176 + return check_button(4, 2);
  177 +}
  178 +bool ClassicController::button_home()
  179 +{
  180 + return check_button(4, 3);
  181 +}
  182 +bool ClassicController::button_minus_select()
  183 +{
  184 + return check_button(4, 4);
  185 +}
  186 +
  187 +// Left and right joysticks
  188 +unsigned char ClassicController::joy_left_x()
  189 +{
  190 + return (data[0] & 0x3F);
  191 +}
  192 +unsigned char ClassicController::joy_left_y()
  193 +{
  194 + return (data[1] & 0x3F);
  195 +}
  196 +unsigned char ClassicController::joy_right_x()
  197 +{
  198 + return ((data[0] & 0xC0) >> 2) +
  199 + ((data[1] & 0xC0) >> 3) +
  200 + ((data[2] & 0x80) >> 6);
  201 +}
  202 +unsigned char ClassicController::joy_right_y()
  203 +{
  204 + return (data[2] & 0x1F) << 1;
  205 +}
  206 +
  207 +// Left and right shoulder button pressure
  208 +unsigned char ClassicController::shoulder_left()
  209 +{
  210 + return ((data[2] & 0x60) >> 2) +
  211 + ((data[3] & 0xE0) >> 5);
  212 +}
  213 +unsigned char ClassicController::shoulder_right()
  214 +{
  215 + return (data[3] & 0x1F);
  216 +}
  217 +
  218 +// higher level functions
  219 +void ClassicController::joy_left_set_threshold(unsigned char left_max, unsigned char right_min, unsigned char down_max, unsigned char up_min, unsigned char center_radius)
  220 +{
  221 + joy_left_left_max = left_max;
  222 + joy_left_right_min = right_min;
  223 + joy_left_down_max = down_max;
  224 + joy_left_up_min = up_min;
  225 + joy_left_center_radius = center_radius;
  226 +}
  227 +bool ClassicController::joy_left_left()
  228 +{
  229 + return joy_left_x() <= joy_left_left_max;
  230 +}
  231 +bool ClassicController::joy_left_right()
  232 +{
  233 + return joy_left_x() >= joy_left_right_min;
  234 +}
  235 +bool ClassicController::joy_left_down()
  236 +{
  237 + return joy_left_y() <= joy_left_down_max;
  238 +}
  239 +bool ClassicController::joy_left_up()
  240 +{
  241 + return joy_left_y() >= joy_left_up_min;
  242 +}
  243 +bool ClassicController::joy_left_center()
  244 +{
  245 + return ( (joy_left_x() >= 32 - joy_left_center_radius) &&
  246 + (joy_left_x() <= 32 + joy_left_center_radius) &&
  247 + (joy_left_y() >= 32 - joy_left_center_radius) &&
  248 + (joy_left_y() <= 32 + joy_left_center_radius) );
  249 +}
  250 +void ClassicController::joy_right_set_threshold(unsigned char left_max, unsigned char right_min, unsigned char down_max, unsigned char up_min, unsigned char center_radius)
  251 +{
  252 + joy_right_left_max = left_max;
  253 + joy_right_right_min = right_min;
  254 + joy_right_down_max = down_max;
  255 + joy_right_up_min = up_min;
  256 + joy_right_center_radius = center_radius;
  257 +}
  258 +bool ClassicController::joy_right_left()
  259 +{
  260 + return joy_right_x() <= joy_right_left_max;
  261 +}
  262 +bool ClassicController::joy_right_right()
  263 +{
  264 + return joy_right_x() >= joy_right_right_min;
  265 +}
  266 +bool ClassicController::joy_right_down()
  267 +{
  268 + return joy_right_y() <= joy_right_down_max;
  269 +}
  270 +bool ClassicController::joy_right_up()
  271 +{
  272 + return joy_right_y() >= joy_right_up_min;
  273 +}
  274 +bool ClassicController::joy_right_center()
  275 +{
  276 + return ( (joy_right_x() >= 32 - joy_right_center_radius) &&
  277 + (joy_right_x() <= 32 + joy_right_center_radius) &&
  278 + (joy_right_y() >= 32 - joy_right_center_radius) &&
  279 + (joy_right_y() <= 32 + joy_right_center_radius) );
  280 +}
  281 +
  282 +// scaled joystick functions
  283 +void ClassicController::joy_left_set_min_max(unsigned char x_min, unsigned char x_max, unsigned char y_min, unsigned char y_max)
  284 +{
  285 + joy_left_x_min = x_min;
  286 + joy_left_x_max = x_max;
  287 + joy_left_y_min = y_min;
  288 + joy_left_y_max = y_max;
  289 +}
  290 +void ClassicController::joy_left_set_scaled_min_max(unsigned char x_scaled_min, unsigned char x_scaled_max, unsigned char y_scaled_min, unsigned char y_scaled_max)
  291 +{
  292 + joy_left_x_scaled_min = x_scaled_min;
  293 + joy_left_x_scaled_max = x_scaled_max;
  294 + joy_left_y_scaled_min = y_scaled_min;
  295 + joy_left_y_scaled_max = y_scaled_max;
  296 +}
  297 +unsigned char ClassicController::joy_left_x_scaled()
  298 +{
  299 + return map(constrain(joy_left_x(), joy_left_x_min, joy_left_x_max), joy_left_x_min, joy_left_x_max, joy_left_x_scaled_min, joy_left_x_scaled_max);
  300 +}
  301 +unsigned char ClassicController::joy_left_y_scaled()
  302 +{
  303 + return map(constrain(joy_left_y(), joy_left_y_min, joy_left_y_max), joy_left_y_min, joy_left_y_max, joy_left_y_scaled_min, joy_left_y_scaled_max);
  304 +}
  305 +
  306 +void ClassicController::joy_right_set_min_max(unsigned char x_min, unsigned char x_max, unsigned char y_min, unsigned char y_max)
  307 +{
  308 + joy_right_x_min = x_min;
  309 + joy_right_x_max = x_max;
  310 + joy_right_y_min = y_min;
  311 + joy_right_y_max = y_max;
  312 +}
  313 +void ClassicController::joy_right_set_scaled_min_max(unsigned char x_scaled_min, unsigned char x_scaled_max, unsigned char y_scaled_min, unsigned char y_scaled_max)
  314 +{
  315 + joy_right_x_scaled_min = x_scaled_min;
  316 + joy_right_x_scaled_max = x_scaled_max;
  317 + joy_right_y_scaled_min = y_scaled_min;
  318 + joy_right_y_scaled_max = y_scaled_max;
  319 +}
  320 +unsigned char ClassicController::joy_right_x_scaled()
  321 +{
  322 + return map(constrain(joy_right_x(), joy_right_x_min, joy_right_x_max), joy_right_x_min, joy_right_x_max, joy_right_x_scaled_min, joy_right_x_scaled_max);
  323 +}
  324 +unsigned char ClassicController::joy_right_y_scaled()
  325 +{
  326 + return map(constrain(joy_right_y(), joy_right_y_min, joy_right_y_max), joy_right_y_min, joy_right_y_max, joy_right_y_scaled_min, joy_right_y_scaled_max);
  327 +}
  328 +
  329 +// Internal function to decode data from controller
  330 +unsigned char ClassicController::_decode_byte (unsigned char x)
  331 +{
  332 + x = (x ^ 0x17) + 0x17;
  333 + return x;
  334 +}
  335 +
175 ClassicController/ClassicController.h
... ... @@ -0,0 +1,175 @@
  1 +/*
  2 + ClassicController.h - Library for the Nintendo Wii Classic Controller
  3 + Created by: Adam Wolf and Matthew Beckler of Wayne and Layne, LLC
  4 + http://wayneandlayne.com/projects/video-game-shield/
  5 + Last updated: October 31, 2010
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 2 of the License, or
  10 + (at your option) any later version.
  11 +
  12 + This program is distributed in the hope that it will be useful,
  13 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + GNU General Public License for more details.
  16 +
  17 + You should have received a copy of the GNU General Public License along
  18 + with this program; if not, write to the Free Software Foundation, Inc.,
  19 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20 +
  21 + Some information taken from http://www.arduino.cc/playground/Main/WiiClassicController
  22 + */
  23 +#ifndef CLASSICCONTROLLER_H
  24 +#define CLASSICCONTROLLER_H
  25 +
  26 +#include "WProgram.h"
  27 +
  28 +#define WII_I2C_ADDR 0xA4
  29 +#define WII_SELECT_P1 PORTB &= 0xEF // set PB4 = low
  30 +#define WII_SELECT_P2 PORTB |= 0x10 // set PB4 = high
  31 +#define WII_PLAYER_1 0
  32 +#define WII_PLAYER_2 1
  33 +
  34 +// These are default values:
  35 +#define CLASSICCONTROLLER_JOY_LEFT_MAX 22
  36 +#define CLASSICCONTROLLER_JOY_RIGHT_MIN 45
  37 +#define CLASSICCONTROLLER_JOY_DOWN_MAX 22
  38 +#define CLASSICCONTROLLER_JOY_UP_MIN 45
  39 +#define CLASSICCONTROLLER_JOY_CENTER_RADIUS 5
  40 +
  41 +#define CLASSICCONTROLLER_JOY_X_MIN 4
  42 +#define CLASSICCONTROLLER_JOY_X_MAX 60
  43 +#define CLASSICCONTROLLER_JOY_Y_MIN 4
  44 +#define CLASSICCONTROLLER_JOY_Y_MAX 60
  45 +
  46 +#define CLASSICCONTROLLER_JOY_X_SCALED_MIN 0
  47 +#define CLASSICCONTROLLER_JOY_X_SCALED_MAX 99
  48 +#define CLASSICCONTROLLER_JOY_Y_SCALED_MIN 0
  49 +#define CLASSICCONTROLLER_JOY_Y_SCALED_MAX 99
  50 +
  51 +
  52 +class ClassicController
  53 +{
  54 + public:
  55 + // returns 0=success, 1=could not access device
  56 + // Provide a 0 or 1 to which_controller to specify which player this is
  57 + // 0 means "Player 1", 1 means "Player 2"
  58 + unsigned char begin(unsigned char which_controller);
  59 +
  60 + // Call this function to query the Controller and update the data
  61 + void update();
  62 +
  63 + // For debugging
  64 + unsigned char* get_data();
  65 +
  66 + // Buttons
  67 + bool button_a();
  68 + bool button_b();
  69 + bool button_y();
  70 + bool button_x();
  71 +
  72 + // Top buttons
  73 + bool button_zr();
  74 + bool button_zl();
  75 + bool button_r();
  76 + bool button_l();
  77 +
  78 + // D-pad buttons
  79 + bool button_up();
  80 + bool button_left();
  81 + bool button_down();
  82 + bool button_right();
  83 +
  84 + // Middle buttons
  85 + bool button_plus_start();
  86 + bool button_home();
  87 + bool button_minus_select();
  88 +
  89 + // Left and right joysticks
  90 + unsigned char joy_left_x();
  91 + unsigned char joy_left_y();
  92 + unsigned char joy_right_x();
  93 + unsigned char joy_right_y();
  94 +
  95 + // Left and right shoulder button pressure
  96 + unsigned char shoulder_left();
  97 + unsigned char shoulder_right();
  98 +
  99 + // Higher-level functions
  100 + // 1. Up/down/left/right/center boolean joystick functions - Can set a different threshold or use the default threshold values.
  101 + // For joy_xxxx_center(), you can set the center_radius to give us a deadband between u/d/l/r and center.
  102 + void joy_left_set_threshold(unsigned char left_max, unsigned char right_min, unsigned char down_max, unsigned char up_min, unsigned char center_radius);
  103 + bool joy_left_up();
  104 + bool joy_left_left();
  105 + bool joy_left_down();
  106 + bool joy_left_right();
  107 + bool joy_left_center();
  108 +
  109 + void joy_right_set_threshold(unsigned char left_max, unsigned char right_min, unsigned char down_max, unsigned char up_min, unsigned char center_radius);
  110 + bool joy_right_up();
  111 + bool joy_right_left();
  112 + bool joy_right_down();
  113 + bool joy_right_right();
  114 + bool joy_right_center();
  115 +
  116 + // 2. Scaled joystick functions - Can set a different min/max for x and y (like from a calibration function).
  117 + // The scaled() functions return a value bewteen 0 and 99, guaranteed never to be outside of that range.
  118 + // The range defaults to 0-99, but can be updated independently for x and y with the set_scaled_min_max function.
  119 + // Note that you can have a max value smaller than the min value, and it will do the Right Thing and invert the values.
  120 + void joy_left_set_min_max(unsigned char x_min, unsigned char x_max, unsigned char y_min, unsigned char y_max);
  121 + void joy_left_set_scaled_min_max(unsigned char x_scaled_min, unsigned char x_scaled_max, unsigned char y_scaled_min, unsigned char y_scaled_max);
  122 + unsigned char joy_left_x_scaled();
  123 + unsigned char joy_left_y_scaled();
  124 +
  125 + void joy_right_set_min_max(unsigned char x_min, unsigned char x_max, unsigned char y_min, unsigned char y_max);
  126 + void joy_right_set_scaled_min_max(unsigned char x_scaled_min, unsigned char x_scaled_max, unsigned char y_scaled_min, unsigned char y_scaled_max);
  127 + unsigned char joy_right_x_scaled();
  128 + unsigned char joy_right_y_scaled();
  129 +
  130 + private:
  131 + // This stores the raw data from the controller, properly translated
  132 + unsigned char data[6];
  133 +
  134 + // Stores a 0 = player 1, 1 = player 2
  135 + // Used to auto-switch between controllers so the user doesn't have to worry about it
  136 + unsigned char this_controller;
  137 +
  138 + // used for u/d/l/r joystick bool functions
  139 + unsigned char joy_left_left_max;
  140 + unsigned char joy_left_right_min;
  141 + unsigned char joy_left_down_max;
  142 + unsigned char joy_left_up_min;
  143 + unsigned char joy_left_center_radius;
  144 + // these are used for the joy_x/y_scaled() functions
  145 + unsigned char joy_left_x_min;
  146 + unsigned char joy_left_x_max;
  147 + unsigned char joy_left_y_min;
  148 + unsigned char joy_left_y_max;
  149 + // output ranges for scaled values
  150 + unsigned char joy_left_x_scaled_min;
  151 + unsigned char joy_left_x_scaled_max;
  152 + unsigned char joy_left_y_scaled_min;
  153 + unsigned char joy_left_y_scaled_max;
  154 +
  155 + // used for u/d/l/r joystick bool functions
  156 + unsigned char joy_right_left_max;
  157 + unsigned char joy_right_right_min;
  158 + unsigned char joy_right_down_max;
  159 + unsigned char joy_right_up_min;
  160 + unsigned char joy_right_center_radius;
  161 + // these are used for the joy_x/y_scaled() functions
  162 + unsigned char joy_right_x_min;
  163 + unsigned char joy_right_x_max;
  164 + unsigned char joy_right_y_min;
  165 + unsigned char joy_right_y_max;
  166 + // output ranges for scaled values
  167 + unsigned char joy_right_x_scaled_min;
  168 + unsigned char joy_right_x_scaled_max;
  169 + unsigned char joy_right_y_scaled_min;
  170 + unsigned char joy_right_y_scaled_max;
  171 +
  172 + unsigned char _decode_byte(unsigned char);
  173 +};
  174 +
  175 +#endif
9 ClassicController/README
... ... @@ -0,0 +1,9 @@
  1 +This is an arduino library for using the Wii Classic Controller.
  2 +
  3 +It uses Peter Fleury's excellent i2c library instead of Wire.h,
  4 +slightly modified to include a timeout feature on initialization.
  5 +
  6 +Adam Wolf and Matthew Beckler
  7 +Wayne and Layne, LLC
  8 +http://wayneandlayne.com/projects/video-game-shield/
  9 +
174 ClassicController/examples/classic_controller_demo/classic_controller_demo.pde
... ... @@ -0,0 +1,174 @@
  1 +/*
  2 + Arduino sketch to demonstrate interfacing with a Nintendo Wii Classic Controller.
  3 + Created by Adam Wolf and Matthew Beckler
  4 + Wayne and Layne, LLC - http://wayneandlayne.com/projects/video-game-shield/
  5 + Last updated: October 31, 2010
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 2 of the License, or
  10 + (at your option) any later version.
  11 +
  12 + This program is distributed in the hope that it will be useful,
  13 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + GNU General Public License for more details.
  16 +
  17 + You should have received a copy of the GNU General Public License along
  18 + with this program; if not, write to the Free Software Foundation, Inc.,
  19 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20 +
  21 + Some useful information provided by http://www.arduino.cc/playground/Main/WiiClassicController
  22 +
  23 +*/
  24 +
  25 +#include <ClassicController.h>
  26 +
  27 +ClassicController cc;
  28 +
  29 +void setup()
  30 +{
  31 + Serial.begin(9600);
  32 + cc.begin(WII_PLAYER_1);
  33 + cc.joy_left_set_scaled_min_max(0, 99, 0, 99);
  34 + cc.joy_right_set_scaled_min_max(0, 99, 0, 99);
  35 +}
  36 +
  37 +// The built-in arduino print functions don't have padding options.
  38 +// IE: 5 is printed in binary as "101", not "00000101", which I wanted
  39 +// to use here, to debug button locations and joystick values.
  40 +// This function prints a byte as a full 8 bits in binary.
  41 +void fixed_width_print_bin(byte value)
  42 +{
  43 + for (char i = 7; i >= 0; i--)
  44 + {
  45 + if (value & (1 << i))
  46 + Serial.print("1");
  47 + else
  48 + Serial.print("0");
  49 + }
  50 +}
  51 +
  52 +void loop()
  53 +{
  54 + cc.update();
  55 +
  56 + /*
  57 + // raw binary printing
  58 + byte* data = cc.get_data();
  59 + for (byte i = 0; i < 6; i++)
  60 + {
  61 + fixed_width_print_bin(data[i]);
  62 + Serial.print(" ");
  63 + }
  64 + Serial.println("");
  65 + */
  66 +
  67 + // using accessor functions
  68 +
  69 + Serial.print("Buttons: ");
  70 +
  71 + // Buttons
  72 + if (cc.button_a())
  73 + Serial.print("A ");
  74 + if (cc.button_b())
  75 + Serial.print("B ");
  76 + if (cc.button_x())
  77 + Serial.print("X ");
  78 + if (cc.button_y())
  79 + Serial.print("Y ");
  80 +
  81 + // Top buttons
  82 + if (cc.button_zr())
  83 + Serial.print("ZR ");
  84 + if (cc.button_zl())
  85 + Serial.print("ZL ");
  86 + if (cc.button_r())
  87 + Serial.print("R ");
  88 + if (cc.button_l())
  89 + Serial.print("L ");
  90 +
  91 + // D-pad buttons
  92 + if (cc.button_up())
  93 + Serial.print("UP ");
  94 + if (cc.button_down())
  95 + Serial.print("DOWN ");
  96 + if (cc.button_left())
  97 + Serial.print("LEFT ");
  98 + if (cc.button_right())
  99 + Serial.print("RIGHT ");
  100 +
  101 + // Middle buttons
  102 + if (cc.button_plus_start())
  103 + Serial.print("START ");
  104 + if (cc.button_home())
  105 + Serial.print("HOME ");
  106 + if (cc.button_minus_select())
  107 + Serial.print("SELECT ");
  108 +
  109 + Serial.println("");
  110 +
  111 + // Left and Right joysticks
  112 + Serial.print(" Left: ");
  113 + Serial.print(cc.joy_left_x(), DEC);
  114 + Serial.print(", ");
  115 + Serial.print(cc.joy_left_y(), DEC);
  116 + Serial.println("");
  117 +
  118 + Serial.print(" Right: ");
  119 + Serial.print(cc.joy_right_x(), DEC);
  120 + Serial.print(", ");
  121 + Serial.print(cc.joy_right_y(), DEC);
  122 + Serial.println("");
  123 +
  124 + // Left and right shoulder button pressure
  125 + Serial.print(" Left shoulder: ");
  126 + Serial.println(cc.shoulder_left(), DEC);
  127 + Serial.print(" Right shoulder: ");
  128 + Serial.println(cc.shoulder_right(), DEC);
  129 +
  130 + Serial.print(" Left joystick boolean values: ");
  131 + if (cc.joy_left_left())
  132 + Serial.print("left ");
  133 + if (cc.joy_left_right())
  134 + Serial.print("right ");
  135 + if (cc.joy_left_up())
  136 + Serial.print("up ");
  137 + if (cc.joy_left_down())
  138 + Serial.print("down ");
  139 + if (cc.joy_left_center())
  140 + Serial.print("center ");
  141 + Serial.println("");
  142 +
  143 + Serial.print(" Right joystick boolean values: ");
  144 + if (cc.joy_right_left())
  145 + Serial.print("left ");
  146 + if (cc.joy_right_right())
  147 + Serial.print("right ");
  148 + if (cc.joy_right_up())
  149 + Serial.print("up ");
  150 + if (cc.joy_right_down())
  151 + Serial.print("down ");
  152 + if (cc.joy_right_center())
  153 + Serial.print("center ");
  154 + Serial.println("");
  155 +
  156 + Serial.print(" Left joystick scaled to 0-99: (");
  157 + Serial.print(cc.joy_left_x_scaled(), DEC);
  158 + Serial.print(", ");
  159 + Serial.print(cc.joy_left_y_scaled(), DEC);
  160 + Serial.println(")");
  161 +
  162 + Serial.print(" Right joystick scaled to 0-99: (");
  163 + Serial.print(cc.joy_right_x_scaled(), DEC);
  164 + Serial.print(", ");
  165 + Serial.print(cc.joy_right_y_scaled(), DEC);
  166 + Serial.println(")");
  167 +
  168 + Serial.println("");
  169 +
  170 +
  171 + delay(1000);
  172 +}
  173 +
  174 +
44 ClassicController/keywords.txt
... ... @@ -0,0 +1,44 @@
  1 +ClassicController KEYWORD1
  2 +begin KEYWORD2
  3 +update KEYWORD2
  4 +button_a KEYWORD2
  5 +button_b KEYWORD2
  6 +button_x KEYWORD2
  7 +button_y KEYWORD2
  8 +button_zr KEYWORD2
  9 +button_zl KEYWORD2
  10 +button_r KEYWORD2
  11 +button_l KEYWORD2
  12 +button_up KEYWORD2
  13 +button_down KEYWORD2
  14 +button_left KEYWORD2
  15 +button_right KEYWORD2
  16 +button_plus_start KEYWORD2
  17 +button_home KEYWORD2
  18 +button_minus_select KEYWORD2
  19 +joy_left_x KEYWORD2
  20 +joy_left_y KEYWORD2
  21 +joy_right_x KEYWORD2
  22 +joy_right_y KEYWORD2
  23 +shoulder_left KEYWORD2
  24 +shoulder_right KEYWORD2
  25 +joy_left_set_threshold KEYWORD2
  26 +joy_left_up KEYWORD2
  27 +joy_left_left KEYWORD2
  28 +joy_left_down KEYWORD2
  29 +joy_left_right KEYWORD2
  30 +joy_left_center KEYWORD2
  31 +joy_right_set_threshold KEYWORD2
  32 +joy_right_up KEYWORD2
  33 +joy_right_left KEYWORD2
  34 +joy_right_down KEYWORD2
  35 +joy_right_right KEYWORD2
  36 +joy_right_center KEYWORD2
  37 +joy_left_set_min_max KEYWORD2
  38 +joy_left_set_scaled_min_max KEYWORD2
  39 +joy_left_x_scaled KEYWORD2
  40 +joy_left_y_scaled KEYWORD2
  41 +joy_right_set_min_max KEYWORD2
  42 +joy_right_set_scaled_min_max KEYWORD2
  43 +joy_right_x_scaled KEYWORD2
  44 +joy_right_y_scaled KEYWORD2
9 Nunchuck/README
... ... @@ -1,6 +1,9 @@
1   -This is an arduino library for using the Nunchuck.
  1 +This is an arduino library for using the Wii Nunchuck.
2 2
3   -It uses Peter Fleury's excellent i2c library instead of Wire.h.
  3 +It uses Peter Fleury's excellent i2c library instead of Wire.h,
  4 +slightly modified to include a timeout feature on initialization.
4 5
5   -Adam Wolf
  6 +Adam Wolf and Matthew Beckler
6 7 Wayne and Layne, LLC
  8 +http://wayneandlayne.com/projects/video-game-shield/
  9 +
25 Nunchuck/examples/nunchuck_demo/nunchuck_demo.pde
... ... @@ -1,5 +1,24 @@
1   -// Nunchuck library demo
2   -// TODO standard header
  1 +/*
  2 + Arduino sketch to demonstrate interfacing with a Nintendo Wii Nunchuck.
  3 + Created by Adam Wolf and Matthew Beckler
  4 + Wayne and Layne, LLC - http://wayneandlayne.com/projects/video-game-shield/
  5 + Last updated: October 31, 2010
  6 +
  7 + This program is free software; you can redistribute it and/or modify
  8 + it under the terms of the GNU General Public License as published by
  9 + the Free Software Foundation; either version 2 of the License, or
  10 + (at your option) any later version.
  11 +
  12 + This program is distributed in the hope that it will be useful,
  13 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + GNU General Public License for more details.
  16 +
  17 + You should have received a copy of the GNU General Public License along
  18 + with this program; if not, write to the Free Software Foundation, Inc.,
  19 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20 +
  21 +*/
3 22
4 23 #include <nunchuck.h>
5 24
@@ -39,7 +58,7 @@ void loop()
39 58 Serial.print("z: ");
40 59 if (nunchuck.button_z())
41 60 {
42   - Serial.println("pushed");
  61 + Serial.println("pushed");
43 62 }
44 63 else
45 64 {
27 Nunchuck/nunchuck.cpp
@@ -17,13 +17,14 @@
17 17 with this program; if not, write to the Free Software Foundation, Inc.,
18 18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 19
  20 +http://www.arduino.cc/playground/Main/WiiClassicController
  21 +
20 22 */
21 23
22 24 #include "WProgram.h" // needed for the arduino functions map() and constrain()
23 25 #include "nunchuck.h"
24 26
25 27 #include <i2cmaster.h>
26   -#include <twimaster.c>
27 28
28 29 // returns 0=success, 1=could not access device
29 30 // Provide a 0 or 1 to which_nunchuck to specify which player this is
@@ -55,15 +56,15 @@ unsigned char Nunchuck::begin(unsigned char which_nunchuck)
55 56 else
56 57 NUNCHUCK_SELECT_P1;
57 58
58   - i2c_init(); // this is non-blocking, it just sets up the baud rate generator and internal pullups
59   - if (i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_WRITE, 10) == 1)
  59 + i2cmaster::i2c_init(); // this is non-blocking, it just sets up the baud rate generator and internal pullups
  60 + if (i2cmaster::i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_WRITE, 10) == 1)
60 61 {
61 62 // could not access device
62 63 return 1;
63 64 }
64   - i2c_write(0x40);
65   - i2c_write(0x00);
66   - i2c_stop();
  65 + i2cmaster::i2c_write(0x40);
  66 + i2cmaster::i2c_write(0x00);
  67 + i2cmaster::i2c_stop();
67 68
68 69 return 0;
69 70 }
@@ -75,19 +76,19 @@ void Nunchuck::update()
75 76 else
76 77 NUNCHUCK_SELECT_P1;
77 78
78   - i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_WRITE, 0xFFFF);
79   - i2c_write(0x00);
80   - i2c_stop();
  79 + i2cmaster::i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_WRITE, 0xFFFF);
  80 + i2cmaster::i2c_write(0x00);
  81 + i2cmaster::i2c_stop();
81 82
82 83 delayMicroseconds(1000); // TODO is this needed?
83 84
84   - i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_READ, 0xFFFF);
  85 + i2cmaster::i2c_start_wait(NUNCHUCK_I2C_ADDR + I2C_READ, 0xFFFF);
85 86 for (unsigned char i = 0; i < 5; i++)
86 87 {
87   - nunchuck_buf[i] = decode_byte(i2c_readAck());
  88 + nunchuck_buf[i] = decode_byte(i2cmaster::i2c_readAck());
88 89 }
89   - nunchuck_buf[5] = decode_byte(i2c_readNak());
90   - i2c_stop();
  90 + nunchuck_buf[5] = decode_byte(i2cmaster::i2c_readNak());
  91 + i2cmaster::i2c_stop();
91 92 }
92 93
93 94 bool Nunchuck::button_z()
18 Nunchuck/nunchuck.h
@@ -21,7 +21,7 @@
21 21 #ifndef Nunchuck_h
22 22 #define Nunchuck_h
23 23
24   -#include "WProgram.h" // TODO is this needed?
  24 +#include "WProgram.h"
25 25
26 26 #define NUNCHUCK_I2C_ADDR 0xA4
27 27
@@ -37,15 +37,15 @@
37 37 #define NUNCHUCK_JOY_Y_MIN 28
38 38 #define NUNCHUCK_JOY_Y_MAX 226
39 39
40   -#define NUNCHUCK_JOY_X_SCALED_MIN 0
41   -#define NUNCHUCK_JOY_X_SCALED_MAX 100
42   -#define NUNCHUCK_JOY_Y_SCALED_MIN 0
43   -#define NUNCHUCK_JOY_Y_SCALED_MAX 100
  40 +#define NUNCHUCK_JOY_X_SCALED_MIN 0
  41 +#define NUNCHUCK_JOY_X_SCALED_MAX 100
  42 +#define NUNCHUCK_JOY_Y_SCALED_MIN 0
  43 +#define NUNCHUCK_JOY_Y_SCALED_MAX 100
44 44
45   -#define NUNCHUCK_SELECT_P1 PORTB &= 0xEF // set PB4 = low
46   -#define NUNCHUCK_SELECT_P2 PORTB |= 0x10 // set PB4 = high
47   -#define NUNCHUCK_PLAYER_1 0
48   -#define NUNCHUCK_PLAYER_2 1
  45 +#define NUNCHUCK_SELECT_P1 PORTB &= 0xEF // set PB4 = low
  46 +#define NUNCHUCK_SELECT_P2 PORTB |= 0x10 // set PB4 = high
  47 +#define NUNCHUCK_PLAYER_1 0
  48 +#define NUNCHUCK_PLAYER_2 1
49 49
50 50 class Nunchuck
51 51 {
2  README
... ... @@ -1,6 +1,6 @@
1 1 Video Game Shield
2 2 by Wayne and Layne, LLC
3   -http://wayneandlayne.com/project/video_game_shield
  3 +http://wayneandlayne.com/project/video-game-shield/
4 4 ==================================================
5 5
6 6 This includes libraries and examples for the Video Game Shield. The Video Game Shield is an expansion board for the Arduino microcontroller board. It provides circuitry to enable analog black and white TV output as well as use two Wii Nunchucks.
877 TVout/TVout.cpp
... ... @@ -0,0 +1,877 @@
  1 +/*
  2 + Copyright (c) 2010 Myles Metzer
  3 +
  4 + Permission is hereby granted, free of charge, to any person
  5 + obtaining a copy of this software and associated documentation
  6 + files (the "Software"), to deal in the Software without
  7 + restriction, including without limitation the rights to use,
  8 + copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 + copies of the Software, and to permit persons to whom the
  10 + Software is furnished to do so, subject to the following
  11 + conditions:
  12 +
  13 + The above copyright notice and this permission notice shall be
  14 + included in all copies or substantial portions of the Software.
  15 +
  16 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17 + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18 + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19 + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20 + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21 + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22 + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23 + OTHER DEALINGS IN THE SOFTWARE.
  24 +*/
  25 +
  26 +/* A note about how Color is defined for this version of TVout
  27 + *
  28 + * Where ever choosing a color is mentioned the following are true:
  29 + * BLACK =0
  30 + * WHITE =1
  31 + * INVERT =2
  32 + * All others will be ignored.
  33 +*/
  34 +
  35 +#include "TVout.h"
  36 +
  37 +
  38 +/* Call this to start video output with the default resolution.
  39 + *
  40 + * Arguments:
  41 + * mode:
  42 + * The video standard to follow:
  43 + * PAL =1 =_PAL
  44 + * NTSC =0 =_NTSC
  45 + *
  46 + * Returns:
  47 + * 0 if no error.
  48 + * 4 if there is not enough memory.
  49 + */
  50 +char TVout::begin(uint8_t mode) {
  51 +
  52 + return begin(mode,128,96);
  53 +} // end of begin
  54 +
  55 +
  56 +/* call this to start video output with a specified resolution.
  57 + *
  58 + * Arguments:
  59 + * mode:
  60 + * The video standard to follow:
  61 + * PAL =1 =_PAL
  62 + * NTSC =0 =_NTSC
  63 + * x:
  64 + * Horizonal resolution must be divisable by 8.
  65 + * y:
  66 + * Vertical resolution.
  67 + *
  68 + * Returns:
  69 + * 0 if no error.
  70 + * 1 if x is not divisable by 8.
  71 + * 2 if y is to large (NTSC only cannot fill PAL vertical resolution by 8bit limit)
  72 + * 4 if there is not enough memory for the frame buffer.
  73 + */
  74 +char TVout::begin(uint8_t mode, uint8_t x, uint8_t y) {
  75 +
  76 + // check if x is divisable by 8
  77 + if ( !(x & 0xF8))
  78 + return 1;
  79 + x = x/8;
  80 +
  81 + screen = (unsigned char*)malloc(x * y * sizeof(unsigned char));
  82 + if (screen == NULL)
  83 + return 4;
  84 +
  85 + cursor_x = 0;
  86 + cursor_y = 0;
  87 +
  88 + render_setup(mode,x,y,screen);
  89 + clear_screen();
  90 + return 0;
  91 +} // end of begin
  92 +
  93 +
  94 +/* Stop video render and free the used memory.
  95 + */
  96 + void TVout::end() {
  97 + TIMSK1 = 0;
  98 + free(screen);
  99 +}
  100 +
  101 +
  102 +/* Fill the screen with some color.
  103 + *
  104 + * Arguments:
  105 + * color:
  106 + * The color to fill the screen with.
  107 + * (see color note at the top of this file)
  108 +*/
  109 +void TVout::fill(uint8_t color) {
  110 + switch(color) {
  111 + case BLACK:
  112 + cursor_x = 0;
  113 + cursor_y = 0;
  114 + for (int i = 0; i < (display.hres)*display.vres; i++)
  115 + display.screen[i] = 0;
  116 + break;
  117 + case WHITE:
  118 + cursor_x = 0;
  119 + cursor_y = 0;
  120 + for (int i = 0; i < (display.hres)*display.vres; i++)
  121 + display.screen[i] = 0xFF;
  122 + break;
  123 + case INVERT:
  124 + for (int i = 0; i < display.hres*display.vres; i++)
  125 + display.screen[i] = ~display.screen[i];
  126 + break;
  127 + }
  128 +} // end of fill
  129 +
  130 +
  131 +/* Gets the Horizontal resolution of the screen
  132 + *
  133 + * Returns:
  134 + * The horizonal resolution.
  135 +*/
  136 +unsigned char TVout::hres() {
  137 + return display.hres*8;
  138 +} // end of hres
  139 +
  140 +
  141 +/* Gets the Vertical resolution of the screen
  142 + *
  143 + * Returns:
  144 + * The vertical resolution
  145 +*/
  146 +unsigned char TVout::vres() {
  147 + return display.vres;
  148 +} // end of vres
  149 +
  150 +
  151 +/* Return the number of characters that will fit on a line
  152 + *
  153 + * Returns:
  154 + * The number of characters that will fit on a text line starting from x=0.
  155 + * Will return -1 for dynamic width fonts as this cannot be determined.
  156 +*/
  157 +char TVout::char_line() {
  158 + return ((display.hres*8)/pgm_read_byte(font));
  159 +} // end of char_line
  160 +
  161 +
  162 +/* delay for x ms
  163 + * The resolution is 16ms for NTSC and 20ms for PAL
  164 + *
  165 + * Arguments:
  166 + * x:
  167 + * The number of ms this function should consume.
  168 +*/
  169 +void TVout::delay(unsigned int x) {
  170 + unsigned long time = millis() + x;
  171 + while(millis() < time);
  172