So now I have my OUYA Dev kit all unboxed and hooked up to the TV and everything. The screens and welcome video look nice, but to load anything on it I needed to get it hooked up to the computer and detected as a valid Android device.
I like to do my development in Eclipse on Windows. I know, I'm crazy. I like my Mac and all, but when I write software (except for iOS of course) I've always been in a Microsoft environment. Maybe it's because my first introduction to programming was BASIC in DOS. Maybe? But from BASIC to Turbo Pascal to C to Java, I've always used a DOS or Windows PC. I'm now on Windows 7 64-bit and of course the OUYA wasn't detected as a valid device when I plugged it in.
The Windows section of the setup information for OUYA devs is a little sparse right now (ok, it's empty) but the forums did provide me with a solution, which I will now share. Hopefully they'll provide some kind of driver with the OUYA when it is released to the general public in a few months, but if not this trick will probably still work.
First, find the Android device driver file provided by Google in your Android SDK. Mine was
C:\Users\User Name\AppData\Local\Android\android-sdk\extras\google\android_winusb.inf
and yours is probably somewhere similar. Open that file up in Nodepad and add these two lines in the [Google.NTx86] section:
%SingleAdbInterface% = USB_Install, USB\VID_0955&PID_7100&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_0955&PID_7100&REV_0232&MI_01
Then you go to your Device Manager and find the unknown device. It is probably calling itself "Cardhu" or something. I don't know what that's about, but just open that up and click the "Update Driver" button. Choose "Browse my computer for driver software" and then "Let me pick from a list of device drivers on my computer". On the next screen, click on the "Have Disk" button and then browse for the .INF file you edited earlier. Then when asked to pick a model, select "Android ADB Interface". You'll probably get warnings about the driver not being signed. Tell the Windows nanny to take a hike and install the driver anyway.
That's what worked for me.
Thursday, January 10, 2013
Tuesday, January 1, 2013
Unboxing my OUYA Dev Kit
I received my OUYA development kit yesterday! They really shipped them to us when they said they would. These early dev models are special - they have clear casing and say "OUYA DEVS" on them. Here's what was in the box.
Here's a picture of one of the controllers beside the console. They say that the controller design is not final yet, so if you get one in the spring they might look a little different.
They even supplied Duracell batteries for the controllers! That was nice, since I don't really have enough batteries in my house right now. And when I was writing this, my wireless mouse needed new batteries.
You put one battery in each side of the controller. I thought that the panels came off a little too easily, and they've already warned us that shaking the controller too hard can pop the batteries out. Hope they address those issues before the final production.
Here's a close-up of the back of the console. Power is on the top. Below it is a mini-USB for connecting it to your PC and an Ethernet port. The bottom two ports are the HDMI output and a USB input. I used that one to connect a mouse to navigate the settings screens before I paired the controllers. I actually had trouble getting the controllers paired with the console, and here's why. To put the controller in pairing mode, you hold in the power button for 5 seconds. To shut down the controller, you hold in the button for 7 seconds. I guess I'm not good at counting in my head, so when I would keep the button down just a little too long it would shut down in the middle of pairing. I would like to see a different button used to pair the devices.
Here's a picture of one of the controllers beside the console. They say that the controller design is not final yet, so if you get one in the spring they might look a little different.
![]() |
| OUYA Console and Controller |
They even supplied Duracell batteries for the controllers! That was nice, since I don't really have enough batteries in my house right now. And when I was writing this, my wireless mouse needed new batteries.
You put one battery in each side of the controller. I thought that the panels came off a little too easily, and they've already warned us that shaking the controller too hard can pop the batteries out. Hope they address those issues before the final production.
Here's a close-up of a controller. The buttons are labeled O, U, Y, and A. Both sticks are buttons if you push them straight down as well. There's two triggers and two bumpers along the top. My initial impression is that the triggers might be a little hard for me to use but I like the bumper locations.
![]() |
| OUYA Controller |
Wednesday, July 6, 2011
Your Polygons are Hitting Each Other
While working on HTML5 games, I sometimes need something in JavaScript that I'm not able to find. On one such occasion I found myself in need of a JavaScript polygon object that would support collision detection with other polygons. This algorithm, using the Separating Axis Theorem, is well-known and had many implementations in other languages. It wasn't too difficult to convert it to JavaScript. While I was at it, I added methods to support determining if the polygon contains a given point (to detect if I was clicking on it) and rotating the polygon.
As you can see by viewing the source of the test page, it is fairly easy to use. It is designed to combine with the HTML5 canvas element.
To create a polygon centered at a given point and using center-relative coordinates for the vertices, you do something like this:
var poly = new Polygon( { x: 50, y: 50 }, "#00FF00");If you want to use all absolute coordinates for the vertices, you can do that too:
poly.addPoint( { x: -20, y: -20 } );
poly.addPoint( { x: -20, y: 20 } );
poly.addPoint( { x: 20, y: 20 } );
var poly = new Polygon( { x: 50, y: 50 }, "#00FF00");To rotate, just call the rotate method with the number of radians you want to rotate. Remember, to convert degrees to radians, multiply by Pi/180.
poly.addAbsolutePoint( { x: 130, y: 130 } );
poly.addAbsolutePoint( { x: 130, y: 170 } );
poly.addAbsolutePoint( { x: 170, y: 170 } );
poly.rotate(0.78539); // 45 degreesSo now you have no excuse for not making a fun HTML5 canvas game. I'd like to see a game about cheese-making. I think that would be awesome.
Saturday, April 16, 2011
Building by the Byte - the HTML5 File API
One of the major features needed in JavaScript to make it truly useful as an application language is file processing. I'm talking about handling the contents of a file totally in your web browser. No server needed. Even non-text format files. Now with HTML5 we have this capability in the File API! I've been thinking about the awesome new possibilities opened up by this development, and put together an example of what it can be used for.
First, let's talk about the browser support. The latest Chrome, Safari, and Firefox browsers support the new JavaScript File API. Internet Explorer? Nope. Get a real browser.
The first thing to understand is the FileReader object. It's a new built-in object, sort of like the XMLHttpRequest object. Like the familiar XHR, FileReader is designed to work asynchronously. That means you'll need to specify your own onload function to the object, which will be called when the browser is done with the file. Think about it - it could take a while to process a file and you don't necessarily need your app tied up waiting for it. Look at this simple example...
var reader = new FileReader();reader.onload = function(event) {// file is loaded, contents are in event.target.result// do something with it!}reader.readAsBinaryString(file);
Now you're probably asking a few questions at this point. Where did you get the file object? How does JavaScript handle binary data? What if there's an error? How do they get the peanut butter inside the peanut butter cups? I can answer all but that last one.
First, there are a few ways to get a file object. My favorite is to grab one simply by dragging it into the browser window. This is accomplished via the dataTransfer property of the event object. For example, let's say you have the following div in your page...
<div id="drophere" style="text-align: center; width: 200px; height: 100px;">drop a file here</div>
And then you had some JavaScript like this...
document.getElementById('drophere').ondrop = function (evt) {evt.preventDefault();var file = evt.dataTransfer.files[0];// now you've got a file object, which is the file you droppedreturn false; // don't let the browser navigate away}
Now just drag a file into your browser window and drop it on your div. Awesome! You've got a file. Now just combine this function with the previous one and you're all set to process anything you can drag in. Well, almost. There's still that binary data issue. JavaScript doesn't really have a data structure designed for binary data.
This is where you break out the FileReader and pass in that file object. Add the code from the first example into the second example....
function handleDrop(evt) {evt.preventDefault();var file = evt.dataTransfer.files[0];var reader = new FileReader();reader.onload = function(event) {// file is loaded, contents are in event.target.result// do something with it!}reader.readAsBinaryString(file);return false; // don't let the browser navigate away}
So when you get the event.target.result object (in the reader's onload function), what will it be? It's actually going to be a String where each character code is between 0 and 255. To read the "bytes" of the file, just loop through all the characters calling charCodeAt on each one. I made an object to help with all the functions you might want to do with the "byte array"...
function DataReader(a) {
this.bytes = a;
this.index = 0;
this.byteRead = 0;
this.bitIndex = 0;
this.endian = "big";
}
DataReader.prototype.readByte = function() {
if (this.eof()) return;
var ret = this.bytes.charCodeAt(this.index);
this.index++;
return ret;
}
DataReader.prototype.readBytes = function(howMany) {
if (this.eof()) return;
var ret = new Array();
for (var i = 0; i < howMany; i++) {
ret.push(this.readByte());
}
return ret;
}
DataReader.prototype.readInteger = function(numBytes) {
if (this.eof()) return;
var howMany = 4; // default to a 4-byte integer
if (numBytes) {
howMany = numBytes;
}
var ret = 0;
if (this.endian == "little") {
var origIndex = this.index;
for (var n = this.index + howMany - 1; n >= origIndex; n--) {
ret = ((ret << 8) | this.bytes.charCodeAt(n));
this.index++;
}
} else {
for (var n = 0; n < howMany; n++) {
ret = ((ret << 8) | this.bytes.charCodeAt(this.index));
this.index++;
}
}
return ret;
}
DataReader.prototype.readString = function(len) {
if (!len || this.eof()) return;
var ret = this.bytes.substring(this.index, this.index + len);
this.index += len;
return ret;
}
DataReader.prototype.readNullTerminatedString = function() {
if (this.eof()) return;
var slen = 0;
var n = this.index;
var finished = false;
while (!finished && n <= this.bytes.length) {
var c = this.bytes.charCodeAt(n);
if (c == 0) {
finished = true;
}
slen++;
n++;
}
var ret = this.bytes.substring(this.index, this.index + (slen - 1));
this.index += slen;
return ret;
}
DataReader.prototype.skip = function(num) {
if (this.eof()) return;
this.index += num;
}
DataReader.prototype.eof = function() {
return (this.index >= this.bytes.length - 1);
}
I should mention that there are other options for processing the file. If you used readAsText instead of readAsBinaryString, you'd just get a normal string containing the contents of the file. That's only really useful if you know the file will only contain text data. A third option is readAsDataURL, which returns a data: URL instead of a string. You can use this to directly set the src attribute of an img tag with the dropped file. Again, this will have limited usefulness. Getting the binary string is the most powerful.
This is a good time to talk about the onerror function. If you tried the above example in Chrome using a local HTML file, it won't work. You'll get an error. You'll only know that if you specify an onerror function as well as an onload. Don't expect a whole lot of details in the error, however.
reader.onerror = function (event) {console.log(this.error.code);}
You'll see a "4" in the console. That's helpful... It actually means that Chrome, by default, does not allow local files (your test HTML file) access other local files (the file you drop in). Firefox does. It's not a real big deal, you can either test using a local server instead of just loading the file or add the "--allow-file-access-from-files" flag to Chrome when you start it. Security thing.
Okay, okay, okay...now what can you build with this? Well, some really amazing things. I put together this nifty example that will read PNG files and display them in the browser not as images, but as a bunch of DIVs (one for each pixel). To accomplish this, I just needed two things. One, the PNG specification which can be found here. And two, a way to inflate compressed data blocks inside the files. For that part, I used my pure JavaScript Inflater that I talked about in my last post.
You can try it yourself here: http://www.amphibian.com/blogstuff/fileapi.html
If you don't have your own PNG file handy, use this one: http://www.amphibian.com/blogstuff/small_dr_frog.png
Make sure you check out the page source to see how it all works. It turns out that PNG files are fairly easy to work with once you have the data inflated.
I know my example is not particularly practical, but I hope it can at least inspire you to make something of your own that uses these splendid new HTML5 features. Use your imagination and let me know what you come up with!
Saturday, January 1, 2011
Inflate in JavaScript
Here's a little something I've been working with for the last few weeks...the Inflate algorithm implemented in JavaScript.
Just what is Inflate? Well, it's the opposite of Deflate. Obviously. In addition, it's also the algorithm used by gzip, WinZip, zlib, etc. to uncompress data. You can read all about it here or read the full RFC. It's been around a long time and has been implemented in lots of different languages, but I really wanted a pure JavaScript version. I'm that crazy.
I needed this because I've been working with the new HTML5 File API. With it, you can process file data in the client browser before uploading it to the server. This is great, until you try to work with a type of file (PNG, for example) that uses the Deflate algorithm to compress its data. I basically converted the simplest possible implementation of the process, Mark Adler's puff.c, to JavaScript and it works pretty well.
I'll have more to say on the HTML5 File API later, but now I release the JavaScript Inflate to the world! Typically, the algorithm works by processing streams of bytes. JavaScript, however, does not have such a data structure. Instead we just use arrays of numbers between 0 and 255 as input and output.
And a word of caution, I wouldn't try running this on a 3-years-out-of-date web browser or some old version of Netscape Navigator you've got running somewhere. It works great in the latest version of Chrome.
UPDATE! Here's a link to a page that you can use to see this thing in action. It uses a little HTML5 File API, which I'll discuss in a later post. I didn't explain much how to use the inflater in my original post so I hope this helps. It is really simple. Once you have your array of "bytes" representing deflated data, just pass it to the puff function along with an empty array you want to get filled up with the inflated "bytes". It will look like this:
var deflated = new Array();// fill deflated with "bytes"var inflated = new Array();puff(inflated, deflated);
Your inflated array will contain the inflated data. It's that easy.
Saturday, November 6, 2010
Break the Request-Response Cycle! WebSockets are Coming!
Since the dawn of time, or at least since 1994, web developers have been forced to work within the confines of the request-response cycle. I've seen good developers be totally confused by the strange disconnected nature of the client and server. For over a decade now, we've been looking for ways to overcome this limitation to deliver web applications that are more like "regular" applications. Around the turn of the century, AJAX started to appear. Now the client could send and receive data from the server without having to interrupt the user with a page load. Great, but we still lacked a way for the server to initiate communication with the client. Comet, sometimes called Reverse-AJAX, seemed to be the answer in 2006. But long-polling HTTP requests are not perfect by any means, and the search continued for a better way. Could WebSockets be the ultimate solution to this problem? Let's give them a try and see how it works.
That looks really simple, right? All you need to do is add a mapping for this servlet in your web.xml and you'll be able to connect via WebSockets to that URL. So how does this work? Well, if a request comes into the servlet with the right upgrade request headers, the request will be handed off to the doWebSocketConnect method instead of the regular doGet or doPost methods. Then it's up to you to return an instance of a class that implements the WebSocket interface. In the WebSocketServlet base class, Jetty will take care of holding on to that instance and making sure it gets it's data from the client. But remember, if you want to be able to send data asynchronously to those clients you need to keep track of that instance yourself somewhere. That's why you'll see the SocketStorage calls in onConnect and onDisconnect. SocketStorage is just a singleton I made that has a set of all the open WebSockets.
WebSockets (read the official spec here) are HTML5's new method of connecting the server with the client, via an "upgraded" HTTP connection. Basically, the client makes an HTTP request to the server and requests an upgrade to WebSockets. If the server agrees, the socket stays open and both the client and server can send information back and forth any time they want. In a compliant web browser a WebSocket API is available in JavaScript that makes this possible, much like the XMLHttpRequest API does for AJAX. So if you have Chrome, Safari, or Firefox 4, you're all set on the client side. But what about the server?
You'll need a web server that supports WebSockets in order to run an application that makes use of them. I wanted to find a way to use WebSockets with Tomcat, but had no luck. There is a project underway to add WebSockets support to Tomcat, but it is done via an add-on of what is essentially another server. I wanted something a little cleaner, so I went with Jetty 7.2. If you're going to serve a Java application with WebSockets I think Jetty is the way to go. Using Java's NIO, it has supported a highly efficient version of the Bayeux protocol (CometD) for a while now. WebSockets support is the logical next step, and it's nicely integrated. A WebSocketServlet class is available for you to extend which makes life easy. Here's a really simple one I made to test with.
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;
public class WebSocketTestServlet extends WebSocketServlet {
protected WebSocket doWebSocketConnect(HttpServletRequest request,
String protocol) {
return new TestWebSocket();
}
}
And here's the code for the TestWebSocket class:
import java.io.IOException;
import org.eclipse.jetty.websocket.WebSocket;
public class TestWebSocket implements WebSocket {
private Outbound ob;
public void onConnect(Outbound outbound) {
this.ob = outbound;
SocketStorage.getInstance().addSocket(this);
}
public void onDisconnect() {
SocketStorage.getInstance().removeSocket(this);
}
public void onFragment(boolean arg0, byte arg1, byte[] arg2, int arg3,
int arg4) {
// ignore fragments for now
}
public void onMessage(byte arg0, String arg1) {
System.out.println("--- received string \"" + arg1 + "\"");
try {
ob.sendMessage("thanks for the " + arg1);
} catch (IOException e) {
e.printStackTrace();
}
}
public void onMessage(byte arg0, byte[] arg1, int arg2, int arg3) {
// ignore byte arrays for now
}
}
That looks really simple, right? All you need to do is add a mapping for this servlet in your web.xml and you'll be able to connect via WebSockets to that URL. So how does this work? Well, if a request comes into the servlet with the right upgrade request headers, the request will be handed off to the doWebSocketConnect method instead of the regular doGet or doPost methods. Then it's up to you to return an instance of a class that implements the WebSocket interface. In the WebSocketServlet base class, Jetty will take care of holding on to that instance and making sure it gets it's data from the client. But remember, if you want to be able to send data asynchronously to those clients you need to keep track of that instance yourself somewhere. That's why you'll see the SocketStorage calls in onConnect and onDisconnect. SocketStorage is just a singleton I made that has a set of all the open WebSockets.
It should be obvious what most of the methods in TestWebSocket do. The Outbound instance that is passed in to the onConnect method is what you'll use to send data outbound to the client, so you need to hold on to it. The onMessage method is invoked whenver the client sends some data. In my example, I basically just echo back to the client whatever it sends me. If you were to add another method to TestWebSocket, you could easily expose the ability to send data to the client unrelated to what the client is sending to the server. Just call sendMessage on the Outbound instance and the data will find its way.
What about the client-side code? It's just as simple! Look at this JavaScript for the client:
var ws;
function connect() {
ws = new WebSocket("ws://yourwebsite.com/path/to/websocket/servlet");
ws.onopen = function() {
console.log("connection openned");
}
ws.onmessage = function(m) {
console.log(m.data);
}
ws.onclose = function() {
console.log("connection closed");
}
}
function sendMessage(msg) {
ws.send(msg);
}
Note the new protocol, "ws://", in the URL given to the WebSocket constructor. If you want secure WebSockets, "wss://" is also available. By default, the WebSocket ports are 80 and 443 (non-secure and secure, respectively) the same as HTTP.
So obviously my example here doesn't do much of anything. It was just a little test I put together to see how WebSockets work in real life. But now that we have this capability, what will we do with it? The common examples people always give are chat applications, stock alerts, things like that. But I'm thinking that there's a really unique idea out there just waiting to be built using new HTML5 technologies like this. I, for one, intend to use it to make some multi-player frog games.
2011 should be the year of the WebSocket. With Safari and Chrome already supporting them and Firefox 4 due out the beginning of the year, they'll be available in a huge percentage of clients. It looks like IE9 won't support them, but IE's market share will hopefully continue to decline. What I'd really like to see is some kind of Java standard approach for the server side. Jetty's implementation seems pretty good, so hopefully sometime next year Tomcat adds support for WebSockets in a similar fashion. I'd be happy to work on adding that if anyone asked me to...
Friday, August 13, 2010
Bring Your Web Apps Alive on the iPhone with Sound!
But now, with the HTML5 audio capabilities present in Safari on the iPhone with the latest iOS 4.0 update there is new hope! Yes, your iPhone can now play sounds inline with the web page. I'm going to talk now about how to best take advantage of this new capability while still supporting other browsers with not as much HTML5 support.
I've been using a great JavaScript audio library called SoundManager 2 for years to make the frogs on my website ribbit on command. Up until recently, it accomplished the miraculous feat of adding audio capabilities to JavaScript using small Flash files. While this was great for regular web
browsers of the past (nearly every computer that can browse the web has at least Flash 8 support), with the advent of the mobile browser my website became quiet for many of my visitors. That all changed in the last few months when SoundManager updated to include support for the HTML5 Audio capabilities and the iPhone OS updated to 4.0.There are a couple of good reasons for using SoundManager 2 to bring sound to your website. First, it has an extremely easy to use API. Second, it supports so many different browser configurations (now including mobile Safari!) in a totally transparent manner. You can be playing sounds from your web application in just a few lines of code. Let's see how simple it can be.
Step 1: Download the latest version here.
Step 2: Unzip and copy the following files to a directory in your web application (I use /soundmanager2 off the root for this).
From the script directory: soundmanager2-jsmin.js, soundmanager2-nodebug-jsmin.js, and soundmanager2.jsStep 3: Include the js file in your web page.
From the swf directory: soundmanager2.swf and soundmanager2_flash9.swf
<script src="/soundmanager2/soundmanager2.js" type="text/javascript"></script>Step 4: Set up the SoundManager configuration. The most important item in the configuration is the location of the SWF files, but you also have to turn on HTML5 Audio support if you want it. Here's the configuration I use:
<script type="text/javascript">Step 5: Initialize the sound objects. You can't do this until SoundManager has completely initialized itself, so it provides an onload property that you just set to an appropriate function. Here's an example.
soundManager.debugMode = false;
soundManager.url = '/soundmanager2/';
soundManager.useHTML5Audio = true;
</script>
<script type="text/javascript">Step 6: Play the sound! When you want to play the sound, you just call the play() function on the variable you initialized (frogSound in the example above). You might want to put a try/catch around the play call just in case something goes wrong, but in most cases it will work and you'll hear your sound!
var frogSound;
soundManager.onload = function() {
frogSound = soundManager.createSound({
id: 'frogSound',
url: '/sounds/frog_1.mp3'
});
}
</script>
frogSound.play();Give it a try for yourself and see what kinds of HTML5/JavaScript games you can make that play with sound on your iPhone. Be sure to read the documentation for SoundManager2, because the new HTML5 features and limitations are changing as more browsers add and change support for HTML5.
Subscribe to:
Posts (Atom)





