diff --git a/LICENSE b/LICENSE deleted file mode 100644 index cb6996c..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2009 - 2011 Ryan McGrath - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/build.py b/build.py deleted file mode 100644 index 7356323..0000000 --- a/build.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/python - -""" - Build-script that brings together all the JS files for wii.js and - takes care of minifying it down to a decent size. - - Before you even ask, no, we're not using uglify.js or Closure. Both - of them are simply too aggressive for their own good; while normally this - is an excellent feature to have, the JS engine that the Opera version on the Wii - uses has a really odd set of quirks when you start trying to get smart with code, - and YUI is the only minifier that doesn't appear to totally destroy it all through - obfuscation. We'll forego a few bytes to have the thing working. ;P - - Uglify also requires Node.js. While I *love* Node, I'll wait until it's more readily - available on Windows - there are a large amount of Windows-based programmers that I'm - not keen on keeping out of development. -""" - -import os -from subprocess import call - -currdir = os.getcwd() - -# The names of our JS files (minus the .js) that we want to build into the -# final distribution. -DEPENDENCIES = [ - 'wii', - 'util', - 'console', - 'remote', -] - -# What we're going to end up injecting as our core build, into core.js. -inject_build = '' - -def minify_code(filename, final_filename): - """ - Dips out to Java/YUI compressor and runs the minifier on the specified file, dumping the - output into the specified final_filename. - """ - #cmd = 'java -jar %s/utilities/yuicompressor-2.4.2.jar %s -o %s' % (currdir, filename, final_filename) - call(['java', '-jar', '%s/utilities/yuicompressor-2.4.2.jar' % currdir, filename, '-o', final_filename]) - -# Run through each dependency, read it into "inject build", then do a simple split on the -# contents of core.js and wrap it all up. -for dependency in DEPENDENCIES: - f = open('%s/js/src/%s.js' % (currdir, dependency), 'r') - inject_build += f.read() - f.close() - -# Open core.js, split it on our build spot, wrap junks. -f = open('%s/js/src/core.js' % currdir, 'r') -core = f.read() -f.close() -core = core.split('/*{{inject_build}}*/') - -# Write out a non-minified build. -f = open('%s/js/wii.js' % currdir, 'w') -f.write(core[0]) -f.write(inject_build) -f.write(core[1]) -f.close() - -# Write out a minified build. -minify_code('%s/js/wii.js' % currdir, '%s/js/wii.min.js' % currdir) diff --git a/css/arta.min.css b/css/arta.min.css deleted file mode 100644 index ac3965e..0000000 --- a/css/arta.min.css +++ /dev/null @@ -1 +0,0 @@ -pre code{display:block;padding:.5em;background:#222}pre .header,pre .profile .header *,pre .ini .title{color:#fff}pre .comment,pre .javadoc,pre .preprocessor,pre .shebang,pre .profile .summary,pre .diff,pre .pi,pre .doctype,pre .xml .tag,pre .template_comment,pre .css .rules,pre .tex .special{color:#444}pre .string,pre .symbol,pre .diff .change,pre .regexp,pre .xml .attribute,pre .xml .value,pre .smalltalk .char,pre .ini .value{color:#fc3}pre .number,pre .addition{color:#0c6}pre .built_in,pre .literal,pre .vhdl .type,pre .go .constant,pre .go .typename,pre .ini .keyword,pre .lua .title,pre .perl .variable,pre .php .variable,pre .mel .variable,pre .django .variable,pre .css .funtion,pre .smalltalk .method,pre .hexcolor,pre .important,pre .flow,pre .inheritance,pre .parser3 .variable{color:#32aaee}pre .keyword,pre .xml .tag .title,pre .css .tag,pre .css .class,pre .css .id,pre .css .pseudo,pre .css .attr_selector,pre .lisp .title,pre .winutils,pre .tex .command{color:#64a}pre .class .title,pre .ruby .constant,pre .vala .constant,pre .parent,pre .deletion,pre .template_tag,pre .css .keyword,pre .javascript .title,pre .objectivec .class .id,pre .smalltalk .class,pre .lisp .keyword,pre .apache .tag,pre .nginx .variable,pre .envvar,pre .bash .variable,pre .go .built_in,pre .vbscript .built_in,pre .lua .built_in,pre .rsl .built_in,pre .tail,pre .avrasm .label,pre .parser3 .title,pre .tex .formula,pre .tex .formula *{color:#b16}pre .yardoctag,pre .phpdoc,pre .profile .header,pre .ini .title,pre .apache .tag,pre .parser3 .title{font-weight:bold}pre .xml .javascript,pre .xml .css,pre .xml .cdata{opacity:.6}pre code,pre .javascript,pre .css,pre .xml,pre .subst,pre .diff .chunk,pre .css .value,pre .css .attribute,pre .lisp .string,pre .lisp .number,pre .tail .params,pre .container,pre .haskell *,pre .erlang *,pre .erlang_repl *{color:#aaa} \ No newline at end of file diff --git a/css/demo.css b/css/demo.css deleted file mode 100644 index 0f1d072..0000000 --- a/css/demo.css +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Wii Demo CSS - * - * Uses a basic CSS reset, and then some very rudimentary styles to make stuff easy - * on the eyes with the Wii console. - */ - -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, font, img, kbd, q, s, samp, -small, strike, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { -margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } -:focus { outline: 0; } -body { line-height: 1; } -ol, ul { list-style: none; } -table { border-collapse: separate; border-spacing: 0; } -caption, th, td { text-align: left; font-weight: normal; } -blockquote:before, blockquote:after, q:before, q:after { content: ""; } -blockquote, q { quotes: "" ""; } - -html { - color: #333; - font: normal 22px/26px helvetica, arial, sans-serif; - padding: 0px; - background: #fff; - overflow: hidden !important; -} - -body { overflow: hidden !important; padding: 20px; } - -h1 { background-color: #42a2cc; color: #f9f9f9; font-size: 44px; padding: 10px; } - -a, a:visited { - background-color: #42a2cc; - color: #f9f9f9; - padding: 3px 5px; - text-decoration: none; - display: inline-block; -} - -a:hover { background-color: #147ba8; } - -p { - padding: 10px; - margin-bottom: 10px; -} - -/* "Players". ;) */ -.player { position: absolute; top: 400px; width: 26px; height: 26px; text-align: center; border: 2px solid #010101; padding: 10px; } -.player span { background-color: #f9f9f9; padding: 5px 5px 4px; font-weight: bold; } -#player_1 { background-color: #ef1419; color: #ef1419; left: 500px; } -#player_2 { background-color: #13c32c; color: #13c32c; left: 580px; } -#player_3 { background-color: #e6d01a; color: #e6d01a; left: 660px; } -#player_4 { background-color: #af0bb1; color: #af0bb1; left: 740px; } diff --git a/css/presentation.css b/css/presentation.css deleted file mode 100644 index 0639090..0000000 --- a/css/presentation.css +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Basic CSS for server sent events demo. - */ - -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, font, img, kbd, q, s, samp, -small, strike, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { -margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } -:focus { outline: 0; } -body { line-height: 1; } -ol, ul { list-style: none; } -table { border-collapse: separate; border-spacing: 0; } -caption, th, td { text-align: left; font-weight: normal; } -blockquote:before, blockquote:after, q:before, q:after { content: ""; } -blockquote, q { quotes: "" ""; } - -html { - color: #333; - font: normal 22px/26px helvetica, arial, sans-serif; - padding: 0px; - background: #fff; - overflow: hidden !important; -} - -body { - overflow: hidden !important; - padding: 0px; - margin: 0px; -} - -h1 { - background-color: #01acca; - padding: 20px 0; - text-indent: 20px; - color: #fff; - font-weight: bold; - font-size: 1.8em; -} - -h2 { font-size: 1.5em;background-color: #e9e9e9; border-bottom: 1px solid #c9c9c9; margin: 0; padding: 15px; } - -a, a:visited { color: #01acca; font-weight: bold; text-decoration: none; } - -ul { margin: 10px 0 0 45px; list-style-type: disc; } - -li { - font-size: 1.3em; - line-height: 1.3em; - padding: 10px 0; - color: #555; -} - -.slide { - display: none; - border: 1px solid #c9c9c9; - background-color: #f9f9f9; - margin: 30px auto; - padding: 0; -} - -pre { - background: #333; - color: #f9f9f9; - font-size: 18px; - line-height: 22px; - font-family: inconsolata, monospace; - width: 92%; - border-radius: 4px; - padding: 10px; -} diff --git a/images/checker.png b/images/checker.png new file mode 100644 index 0000000..ab14540 Binary files /dev/null and b/images/checker.png differ diff --git a/index.html b/index.html index 1d5759d..ec86ada 100644 --- a/index.html +++ b/index.html @@ -1,108 +1,287 @@ - + -
- -- This is a demo page meant to show how easy it is to interact with the Nintendo Wii remotes using Javascript. It's - powered by wii-js, a Javascript library that abstracts the differences - and pain points associated with using the Wii remotes. -
- -- This demo is really simple, and works best with all Wii remotes (Wiimotes). Hold a Wiimote horizontal (sideways), and use - the directional pad to move a box floating in the bottom right corner around. Wiimote #1 is red, #2 is green, #3 is yellow, #4 is purple. - Have fun! -
+ + + +A sane, documented, (hopefully) performant event-based library for Wiimote webpage interaction.
+ + +The Nintendo Wii is an entertainment system with an utterly massive install base, and when +you couple it with the fact that it's got a web browser (mostly) built in, there's a lot of +potential for third party development. Sadly, few have opted to do any sort of development for +it. While it doesn't help that Nintendo pretty much dropped the ball on this opportunity, the +experience of browsing the web on the Wii isn't actually that compelling to begin with.
- wiimote.when('pressed_right', function() { - p1.css({'left': p1.position().left + 50}); - }); +That said, I think this can serve one other purpose: it's an ideal environment to teach children +how to program! I created this library to sanitize Wii interaction with webpages in the browser, +as it's notoriously crippled. It aims to offer a solid, documented, performant API that's easy to +understand and pick up. With this library, you can have up to 4 Wii-motes interacting with your +webpage at once, a dynamic not found in other web browsing mediums.
- wiimote.when('pressed_left', function() { - p1.css({'left': p1.position().left - 50}); - }); +You can find a built source file and a minified source file for production use in the /js/ directory. +To play with a live example, load up the demo (_index.html_) on your own server, or feel free to use mine:
- wiimote.when('pressed_up', function() { - p1.css({'top': p1.position().top - 50}); - }); - - wiimote2.when('pressed_down', function() { - p2.css({'top': p2.position().top + 50}); - }); - - wiimote2.when('pressed_right', function() { - p2.css({'left': p2.position().left + 50}); - }); +wii-js Demo: http://venodesigns.net/wii/
- wiimote2.when('pressed_left', function() { - p2.css({'left': p2.position().left - 50}); - }); +Working with the Wii's browser can be odd - it has moderately good support for CSS, so you're never really +as bad off as you'd be with a version of Internet Explorer - that said, if you're looking for a good read +on what's supported, check out this article on Opera Wii supported technologies.
- wiimote2.when('pressed_up', function() { - p2.css({'top': p2.position().top - 50}); - }); +Questions, comments, criticism and praise can be directed to me at the following outlets:
- wiimote3.when('pressed_down', function() { - p3.css({'top': p3.position().top + 50}); - }); - - wiimote3.when('pressed_right', function() { - p3.css({'left': p3.position().left + 50}); - }); +var wiimote = new Wii.Remote(1, {horizontal: true}),
+ wiimote2 = new Wii.Remote(2, {horizontal: true});
- wiimote3.when('pressed_up', function() {
- p3.css({'top': p3.position().top - 50});
- });
+wiimote.when('pressed_a', function() {
+ alert('Wiimote #1 pressed the A Button!');
+});
- wiimote4.when('pressed_down', function() {
- p4.css({'top': p4.position().top + 50});
- });
-
- wiimote4.when('pressed_right', function() {
- p4.css({'left': p4.position().left + 50});
- });
+wiimote2.when('pressed_a', function() {
+ alert('Wiimote #2 pressed the A Button!');
+});
- wiimote4.when('pressed_left', function() {
- p4.css({'left': p4.position().left - 50});
- });
+Wii.listen();
+The largest issue with making interactive pages that work with the Wii has been that the API has +been nothing short of a black hole. When you actually begin to dig in and figure out what's going on, +it gets even uglier to see - the primary wiimote, for instance, has a totally different set of signals +than the other three.
+ +wii-js abstracts away most of these differences and/or problems, and works on a very simple event-dispatch +system. What this means is that you create an instance of a Wii Remote, subscribe to events, and provide a +function to get called when that event has occurred. The following syntax should explain this:
+ +wiimote.when('event_name_here', function() { /* My callback function */ });
+When instantiating a Wii Remote instance, you can choose to have the library interpret directional pad controls +in horizontal or vertical mode. You can change this at any point, if you want, by simply swapping the property.
+ +var wiimote = new Wii.Remote(1, {horizontal: true}); // Horizontal controls
+var wiimote = new Wii.Remote(1, {horizontal: false}); // Vertical controls
+
+wiimote.opts.horizontal = true; // Change to horizontal scheme.
+The final important piece is to start the Wii-event loop; this manages the event dispatcher internally. To do this, simply...
+ +Wii.listen();
+You can listen for the following events on all controllers:
+ +You can listen for the following events on extra controllers, but not the primary controller.
+ +You can also get the following properties from any Wii Remote instance; they will return "undefined" if the remote +isn't able to see the TV/sensor bar, so be sure to check this!
+ +One semi-useful trick to point out about this library is that each of your callback functions get passed two +arguments by default - a reference to the Wiimote you're working with, and the raw Wiimote status object that the +Wii reports back to the library. You get this in a normalized fashion, instead of having to deal with the odd polling +issues present in the browser.
+ +var wiimote = new Wii.Remote(1, {horizontal: false});
+
+wiimote.when('pressed_a', function(wii_remote, wii_remote_status) {
+ /* Alert an internal confidence level provided by the Wii. */
+ alert(wii_remote_status.dpdValidity);
+});
+Debugging Javascript on the Wii is also nothing short of incredibly annoying, so I've made some efforts to patch this +up and make life a bit easier. My typical debugging strategy with any Wii-related code would always start with +the following. The first thing to do is set the Wii listener to run in debug mode, like so:
+ +Wii.listen({debug: true});
+With this set, you can log errors with any of the following functions. error can be a string or a complex object.
If the typical Wii debugging flow isn't enough for you, go aggressive with this - just be aware that you can crash +the Wii's browser if you're using try/catch all over the place, as it's not cheap in Javascript.
+ +try {
+ // Whatever function to execute
+} catch(e) { Wii.util.debug(e); }
+The Nintendo Wii treats the primary controller differently than the other ones, and doesn't report any action +from the Nunchuk, nor does it report when someone has pressed the "B" button on the primary controller (as it's used +for scrolling a page).
+ +The Wii Browser also doesn't report data for Gamecube controllers, the Classic controller, or any other accessories.
+ +It's a work in progress to see what can be done about these, but it's impossible to guarantee anything will come out +of it unless Nintendo and/or Opera can come out with something new.
+ +Primary Wiimote is a bit more responsive than the extra 3
+This library works by polling the status of the three extra Wii-remotes in 100ms intervals and dispatching events
+based on this. Anything lower than 100ms causes the Wii to run into memory limitations, and the single-threaded
+nature of the browser doesn't really help this issue.
The primary Wii-remote uses an odd combination of DOM-esque callbacks; due to this, it reports more frequently than +the other Wii-remotes. It's not a showstopper by any means, but for small games it would in theory give a weighted advantage. +I'll probably end up throttling this through the library by means of a flag, e.g "game_mode": true in the initial options.
+ +If you'd like to help with this library, you're more than welcome to. Simply fork it on GitHub, work away, then +issue me a pull request. I generally respond within 24 hours.
+ +The build system here is pretty simple - edits and changes go into the /js/src/ files, and you can run
+ +python build.py
+
+
+from the main directory to build a new version. The minifier here is YUI; Closure/UglifyJS are more aggressive, and +for some reason throw ridiculous issues in the Wii's browser that I've been unable to track down (and I don't have +more time to throw at it).
+ +In short, the builds require Python/Java, but once you've got them all installed you should only need the command above.
+ +I sadly did not find out about wii.js until after I released this library; +with respect to the original author, his work only covers the primary Wii Remote and not the extra ones, nor has it +been updated in years. While his approach appears to be the same as mine (or mine the same as his), neither one +influenced the other, and they're totally separate works.
+ +With the exception of wii.js, I do not know of any other (remaining) Wii interaction Javascript libraries. It's for +these reasons (and my desire for a simpler API) that I built this. ;)
+ +wii-js is released under an MIT license. Just provide credit where need be if you choose to use this, it's taken quite +a bit of my time to decipher the utterly random pieces and intricacies of this Javascript engine. ;)
+