Library for communicating with a Gameduino shield. Provides colour VGA display, hardware sprites with collision detection and stero sound. See http://excamera.com/sphinx/gameduino/ for more details.

Dependents:   GameduinoTest SimpleGameduinoTest RobotRic

Note that to use this library you must also import the CommonTypes library because this library uses it.

To get an mbed talking to a Gameduino shield all you really have to do is connect the Gameduino to the SPI bus. I did it using an LPC11U24 mbed and wired it to the Gameduino as follows:

  • mbed pin...................Gameduino pin
  • 5 (MOSI)...................11 (MOSI)
  • 6 (MISO)...................12 (MISO)
  • 7 (SCK)....................13 (SCK)
  • 8..........................9 (SEL)
  • 40 (VOUT)..................5V and 3.3V
  • 1 (GND)....................GND

mbed pins 5, 6 and 7 make up the SPI datalink. mbed pin 8 should be configured as a digital output and is driven low to communicate with the Gameduino.

Probably best to run the whole lot off a regulated 5V supply rather than relying on the 5V supply from the USB cable. I have had problems with the mbed's 3.3V VOUT supply. If the USB voltage is very low (nearer 4V than 5V) then the mbed's 3.3V regulator won't work properly and can't provide much current. I struggled to draw 10 mA for an LED. These problems go away if you power everything off an external 5V supply. It also means you can unplug the mbed from your computer of course.

Mounting the Gameduino is a bit awkward. I put it on some stripboard using 3 SIL sockets designed for an Arduino. Then I mounted the mbed alongside using two 20 pin SIL sockets. Unfortunately Arduino shields like the Gameduino don't fit nicely on a 0.1 inch grid (like the mbed does) so some connections have to be made using flying wires.

Here are some screenshots:

/media/uploads/RichardE/_scaled_img_0055_compressed.jpg

/media/uploads/RichardE/_scaled_img_0057_compressed.jpg

The code for generating this last display is found here:

Import programGameduinoTest

More complicated test program that generates text, coloured sprites and sound.

Here's the games console:

/media/uploads/RichardE/_scaled_img_0058_compressed.jpg

and the insides. Don't worry about the cables and the 8 pin chips. You don't need them if all you want is a display. They are an RS485 chip and a serial EEPROM.

/media/uploads/RichardE/_scaled_img_0059_compressed.jpg

Gameduino.h

Committer:
RichardE
Date:
2013-06-05
Revision:
5:d614b857b940
Parent:
4:f6a33c5f0f7f

File content as of revision 5:d614b857b940:

/*
 * SOURCE FILE : Gameduino.h
 *
 * Definition of class Gameduino.
 * Each instance of this class allows communication with
 * a Gameduino shield over an SPI communications link.
 *
 */

#ifndef GameduinoDefined

  #define GameduinoDefined

  #include "mbed.h"     // mbed library
  #include "Types.h"    // integer types
  
  // These #defines allow you to use data arrays from an Arduino background that make
  // use of program memory.
  #define PROGMEM const
  #define prog_uchar UInt8
  
/** Gameduino class to support SPI communications with the Gameduino game adapter
 *
 * Example:
 * @code
 * #include "mbed.h"
 * #include "Gameduino.h"
 * 
 * int main() {
 *     // Make a digital output for use with Gameduino.
 *     DigitalOut cs( p8 );
 *     // Initialise an SPI link for communications with Gameduino.
 *     // Use pin 5 for MOSI.
 *     // Use pin 6 for MISO.
 *     // Use pin 7 for SCK.
 *     SPI spi( p5, p6, p7 );
 *     // 8MHz clock should be OK.
 *     spi.frequency( 8000000 );
 *     // Set SPI format to use.
 *     // Use 8 bits per SPI frame.
 *     // Use SPI mode 0.
 *     spi.format( 8, 0 );
 *     // Make a Gameduino and pass SPI link and digital output for chip select.
 *     Gameduino gd( &spi, &cs );
 *     // Reset the Gameduino.
 *     gd.begin();
 *     // Lets have a default ASCII character set.
 *     gd.ascii();
 *     // Write something to character memory.
 *     gd.__wstart( Gameduino::RAM_PIC );
 *     for( UInt8 c = 'A'; c <= 'Z'; ++c ) {
 *         gd.__tr8( c );
 *     }
 *     gd.__end();
 *     // Test copy method.
 *     UInt8 copyData[] = "HELLO";
 *     gd.copy( Gameduino::RAM_PIC + 64, copyData, 5 );
 *     // Test putstr method.
 *     gd.putstr( 3, 10, "Ambidextrous!" );
 *     // Finished with Gameduino.
 *     gd.end();
 * }
 * @endcode
 */
  class Gameduino {

  public :

    // Registers on Gameduino.
    enum Reg {
        RAM_PIC         = 0x0000,    // Screen Picture, 64 x 64 = 4096 bytes
        RAM_CHR         = 0x1000,    // Screen Characters, 256 x 16 = 4096 bytes
        RAM_PAL         = 0x2000,    // Screen Character Palette, 256 x 8 = 2048 bytes
        IDENT           = 0x2800,
        REV             = 0x2801,
        FRAME           = 0x2802,
        VBLANK          = 0x2803,
        SCROLL_X        = 0x2804,
        SCROLL_Y        = 0x2806,
        JK_MODE         = 0x2808,
        J1_RESET        = 0x2809,
        SPR_DISABLE     = 0x280a,
        SPR_PAGE        = 0x280b,
        IOMODE          = 0x280c,
        BG_COLOR        = 0x280e,
        SAMPLE_L        = 0x2810,
        SAMPLE_R        = 0x2812,
        MODULATOR       = 0x2814,
        VIDEO_MODE      = 0x2815,
        SCREENSHOT_Y    = 0x281e,
        PALETTE16A      = 0x2840,   // 16-color palette RAM A, 32 bytes
        PALETTE16B      = 0x2860,   // 16-color palette RAM B, 32 bytes
        PALETTE4A       = 0x2880,   // 4-color palette RAM A, 8 bytes
        PALETTE4B       = 0x2888,   // 4-color palette RAM A, 8 bytes
        COMM            = 0x2890,   // Communication buffer
        COLLISION       = 0x2900,   // Collision detection RAM, 256 bytes
        VOICES          = 0x2a00,   // Voice controls
        J1_CODE         = 0x2b00,   // J1 coprocessor microcode RAM
        SCREENSHOT      = 0x2c00,   // screenshot line RAM
        RAM_SPR         = 0x3000,   // Sprite Control, 512 x 4 = 2048 bytes
        RAM_SPRPAL      = 0x3800,   // Sprite Palettes, 4 x 256 = 2048 bytes
        RAM_SPRIMG      = 0x4000,   // Sprite Image, 64 x 256 = 16384 bytes
    };

    // Modes of operation.
    enum Mode {
        MODE_800x600_72  = 0,
        MODE_800x600_60  = 1,
    };

    // Sprite rotations.
    enum Rotation {
        None = 0,
        SwapXY = 1,
        FlipX = 2,
        FlipXSwapXY = 3,
        FlipY = 4,
        FlipYSwapXY = 5,
        FlipYFlipX = 6,
        FlipYFlipXSwapXY = 7,
    };
    
    // Sound waveforms used with voice method.
    enum WaveForm {
        SineWave,
        WhiteNoise,
    };
    
    // Other constants.
    enum {
        TRANSPARENT     = ( 1 << 15 ),
    };
    
    // Structure used with plots method.
    struct sprplot {
        Int8 x, y;              // offsets from origin
        UInt8 image, palette;   // sprite image number and palette information
    };
    
    /** Constructor.
     * @param spi Pointer to SPI datalink to use for comms.
     * @param cs Pointer to digital output used Gameduino as chip select. 
     */
    Gameduino( SPI *spi, DigitalOut *cs );

    /** Destructor.
     */
    virtual ~Gameduino();
    
    /** Initialise connection to adapter and reset things.
     */
    void begin( void );
    
    /** Close down connection.
     */
    void end( void ) {
        // Can't think of anything to do.
    }
    
    /** Clear the screen (character memory).
     * @param code Character to use to clear screen.
     */
    void ClearScreen( UInt8 code ) {
        fill( RAM_PIC, code, 64 * 64 );
    }
    
    /** Set default ASCII character set and palette.
     */
    void ascii( void );
    
    /** Start an SPI transaction.
     *
     * @param address Address to read or write to. Bit 15 must be set for a write.
     */
    void __start( UInt16 address );
    
    /** Start an SPI write transaction.
     *
     * @param address Address to write to.
     */
    void __wstart( UInt16 address );
    
    /** Start a sprite transaction.
     * Use this before calling xhide, xsprite or TransferSprite.
     * @param sprnum Sprite number to start at.
     */
    void __wstartspr( UInt8 sprnum );
    
    /** Transfer byte via SPI.
     * Use only after a call to __start or __wstart.
     * @param data Data to send.
     */
    UInt8 __tr8( UInt8 data );
    
    /** Transfer 16 bit word via SPI.
     * Use only after a call to __start or __wstart.
     * @param data Data to send.
     */
    UInt8 __tr16( UInt16 data );

    /** End an SPI transaction.
     */
    void __end( void );
    
    /** Read a byte.
     * @param address Address in Gameduino memory to read from.
     * @param returns Byte at that address.    
     */
    UInt8 rd( UInt16 address );
    
    /** Read a 16 bit word.
     * @param address Address in Gameduino memory to read from.
     * @param returns Word at that address.    
     */
    UInt16 rd16( UInt16 address );
    
    /** Write a byte.
     * @param address Address to write to.
     * @param data Data to write.
     */
    void wr( UInt16 address, UInt8 data );
    
    /** Write a 16 bit word.
     * @param address Address to write to.
     * @param data Data to write.
     */
    void wr16( UInt16 address, UInt16 data );

    /** Fill area of Gameduino memory.
     * @param address Address to write to.
     * @param data Data to write to entire area.
     * @param count Number of bytes to write.
     */
    void fill( UInt16 address, UInt8 data, UInt16 count );
    
    /** Copy data into Gameduino memory.
     * @param address Address to write to.
     * @param src Pointer to data to copy from.
     * @param count Number of bytes to write.
     */
    void copy( UInt16 address, const UInt8 *src, UInt16 count );
    
    /** Hide a sprite.
     * Use only after specifying address to write to.
     * Basically just writes 400 twice to SPI.
     */
    void xhide( void );

    /** Send sprite information to Gameduino.
     * Use only after specifying address to write to.
     * @param x X coordinate.
     * @param y Y coordinate.
     * @param image Sprite image number.
     * @param palette Palette selection information (use 0 for 256 colour palette).
     * @param rot Rotation and flip setting.
     * @param jk JK collision information.
     */
    void TransferSprite( Int16 x, Int16 y, UInt8 image, UInt8 palette, Rotation rot=None, UInt8 jk=0 );

    /** Draw a sprite at an offset from an origin taking into account rotation.
     * Use only after specifying address to write to.
     * @param ox Origin X coordinate.
     * @param oy Origin Y coordinate.
     * @param x X offset from origin.
     * @param y Y offset from origin.
     * @param image Sprite image number.
     * @param palette Palette selection information (use 0 for 256 colour palette).
     * @param rot Rotation and flip setting.
     * @param jk JK collision information.
     */
    void xsprite( Int16 ox, Int16 oy, Int8 x, Int8 y, UInt8 image, UInt8 palette, Rotation rot=None, UInt8 jk=0 );
    
    /** Construct RGB value.
     * @param r Red level.
     * @param g Green level.
     * @param b Blue level.
     * @param returns RGB value.
     */
    static UInt16 RGB( UInt8 r, UInt8 g, UInt8 b );

    /** Set palette entry.
     * @param Pallete entry.
     * @param rgb RGB value to store.
     */
    void setpal( UInt16 pal, UInt16 rgb );

    /** Write single character at given coordinates.
     * @param x X coordinate.
     * @param y Y coordinate.
     * @param c Character to write.
     */
    void putchar( UInt8 x, UInt8 y, char c );

    /** Write text at given coordinates.
     * @param x X coordinate.
     * @param y Y coordinate.
     * @param s pointer to zero terminated text.
     */
    void putstr( UInt8 x, UInt8 y, const char *s );

    /** Position a sprite.
     * @param spr Sprite number.
     * @param x X coordinate.
     * @param y Y coordinate.
     * @param image Sprite image number.
     * @param palette Palette selection information (use 0 for 256 colour palette).
     * @param rot Rotation and flip setting.
     * @param jk JK collision information.
     */
    void sprite( UInt8 spr, Int16 x, Int16 y, UInt8 image, UInt8 palette, Rotation rot=None, UInt8 jk=0 );

    /** Draw 4 sprites as a 2 by 2 block.
     * @param spr Sprite number for first sprite.
     * @param x X coordinate for centre of group.
     * @param y Y coordinate for centre of group.
     * @param image Sprite image number for first image.
     * @param palette Palette selection information (use 0 for 256 colour palette).
     * @param rot Rotation and flip setting.
     * @param jk JK collision information.
     */
    void sprite2x2( UInt8 spr, Int16 x, Int16 y, UInt8 image, UInt8 palette, Rotation rot=None, UInt8 jk=0 );

    /** Plot a number of sprites relative to an origin.
     * @param x X coordinate of origin.
     * @param y Y coordinate of origin.
     * @param psp Pointer to an array of sprplot structures.
     * @param count Number of structures in the psp array.
     * @param rot Rotation and flip setting.
     * @param jk JK collision information.
     */
    void plots( Int16 ox, Int16 oy, const sprplot *psp, UInt8 count, Rotation rot=None, UInt8 jk=0 );
    
    /** Wait for vertical blanking.
     */
    void waitvblank( void );

    /** Make a noise.
     * @param v Voice number.
     * @param wave Waveform type.
     * @param freq Frequency in quarter Hz (so 100 Hz is 400).
     * @param lamp Amplitude for left channel.
     * @param ramp Amplitude for right channel.
     */
    void voice( UInt8 v, WaveForm wave, UInt16 freq, UInt8 lamp, UInt8 ramp );
    
    /** Hide all sprites.
     */                   
    void HideAllSprites( void );
    
    // Current sprite. Used by xsprite and xhide etc.
    UInt8 spr;
    
  private :
  
    // Pointer to SPI datalink.
    SPI *spi;
    
    // Pointer to chip select digital output.
    DigitalOut *cs;  

  };

#endif

/* END of Gameduino.h */