The Ouya is a tiny game console which is designed for promoting indy games rather than traditional high budget productions. It’s cheap compared to standard games hardware, and all the games are free to play at least in demo form. It’s very easy to start making games with as it’s based on Android – you can just plug in a USB cable and treat it just the same as any other Android device. You also don’t need to sign anything to start building stuff – it’s just a case of adding one line to your AndroidManifest.xml to tell the Ouya that the program is a game:
and adding a 732×412 icon in “res/drawable-xhdpi/ouya_icon.png” so it shows up on the menu.
There is a lot to like about the Ouya’s philosophy, so I tried out some graphics experiments with it to get better acquainted:
This program was made using Jellyfish, part of my increasingly odd rendering stack which started out as a port of Fluxus to PS2. It’s a type of microcode written inside TinyScheme and running in a separate virtual machine that makes it possible to process a lot of geometry without garbage collection overheads. At some point I might write a compiler for this, but writing the code longhand at the moment means I can tweak the instruction set and get a better understanding of how to use it. Here is the microcode for the ribbons above, they run at 20,000 cycles per frame each (so about 1.2MHz):
;; register section 8 20000 0 ;; control (pc, cycles, stack) mdl-size prim-tristrip 1 ;; graphics (size, primtype, renderhints) 0 0 0 ;; pos 0 0 0 ;; sensor addr ;; program data section mdl-start 0 0 ;; 4 address of current vertex mdl-start 0 0 ;; 5 address of accum vertex (loop) 0 0 0 ;; 6 influence 0 0 0 ;; temp ;; code section ;; add up differences with every other vertex ldi 4 0 ;; load current vertex ldi 5 0 ;; load accum vertex sub 0 0 ;; get the difference lda 6 0 ;; load the accumulation add 0 0 ;; accumulate nrm 0 0 ;; normalise sta 6 0 ;; store accumulation add.x 5 1 ;; inc accum address ;; accumulation iteration lda 5 0 ;; load accum address ldl mdl-end 0 ;; load end address jlt 2 0 ;; exit if greater than model end (relative address) jmp 8 0 ;; return to accum-loop ;; end accum loop ;; push away from other verts lda 6 0 ;; load accum ldl -0.1 0 ;; reverse & make smaller mul 0 0 ;; attract to next vertex ldi 4 0 ;; load current ldi 4 1 ;; load next sub 0 0 ;; get the difference ldl 0.4 0 mul 0 0 ;; make smaller add 0 0 ;; add to accum result ;; do the animation ldi 4 0 ;; load current vertex add 0 0 ;; add the accumulation sti 4 0 ;; write to model data ;; reset the outer loop ldl 0 0 ;; load zero sta 6 0 ;; reset accum ldl mdl-start 0 sta 5 0 ;; reset accum address add.x 4 1 ;; inc vertex address lda 4 0 ;; load vertex address ldl mdl-end 0 ;; load end address jlt 2 0 ;; if greater than model (relative address) jmp 8 0 ;; do next vertex ;; end: reset current vertex back to start ldl mdl-start 0 sta 4 0 ;; waggle around the last point a bit lda mdl-end 0 ;; load vertex pos rnd 0 0 ;; load random vert ldl 0.5 0 mul 0 0 ;; make it smaller add 0 0 ;; add to vertex pos sta mdl-end 0 ;; write to model jmp 8 0