Toorum's Quest II - ATmega328P based retro video game with 256 color graphics

Right, I made a NES controller emulator using a Wii nunchuk. The protocol was a tiny bit obscure (one latch pulse and seven clock pulses) but I got there. For timing reasons I made a tight loop where it waited for latch, and then clocked out the 8 values. Then in the 1/60th of a second I should have available I read the nunchuk ready for next time.

// NES controller emulator using Wii nunchuk
// Author: Nick Gammon
// Date:   1st December 2013

#include <Nunchuk.h>
#include <Wire.h>

const byte JOYSTICK_LOW_THESHOLD = 100;
const byte JOYSTICK_HIGH_THESHOLD = 200;

void setup ()
{
  // don't have bogus initial data
  pinMode (12, INPUT_PULLUP);
  
  // initialize nunchuk
  Nunchuk::begin ();
  // first read
  Nunchuk::read ();
  
}  // end of setup

byte reply [8]; // A, B, SELECT, START, UP, DOWN, LEFT, RIGHT

void loop ()
{
  reply [0] = Nunchuk::z_button;  // A
  reply [1] = Nunchuk::c_button;  // B
  reply [2] = 0;   // SELECT  ??
  reply [3] = Nunchuk::c_button && Nunchuk::z_button;  // START (both Z and C buttons together)
  reply [4] = Nunchuk::joy_y_axis > JOYSTICK_HIGH_THESHOLD;  // UP
  reply [5] = Nunchuk::joy_y_axis < JOYSTICK_LOW_THESHOLD;   // DOWN
  reply [6] = Nunchuk::joy_x_axis < JOYSTICK_LOW_THESHOLD;   // LEFT
  reply [7] = Nunchuk::joy_x_axis > JOYSTICK_HIGH_THESHOLD;  // RIGHT
  
  noInterrupts ();

  // wait for LATCH (pin 10) to go high
  while ((PINB & bit(2)) == 0)
    { }
    
  PORTB |= bit (4); // start off with HIGH output
  DDRB |= bit (4);  // set MISO (pin 12) to output
  
  // wait for LATCH (pin 10) to go low again
  while (PINB & bit(2))
    { }

  // After LATCH we immediately output the first bit
  
  // set MISO (pin 12) to appropriate value for the "A" button
  if (reply [0])
    PORTB &= ~bit (4);
  else
    PORTB |= bit (4);

  // do 7 more data pulses
  for (byte i = 1; i < 8; i++)
    {
    // wait for CLOCK (pin 13) to go high
    while ((PINB & bit(5)) == 0)
      { }
      
    // set MISO (pin 12) to appropriate value
    if (reply [i])
      PORTB &= ~bit (4);
    else
      PORTB |= bit (4);

    // wait for CLOCK (pin 13) to go low
    while (PINB & bit(5))
      { }
    }  // end of 8 pulses

  PORTB |= bit (4); // end off with HIGH output
  DDRB &= ~bit (4);  // set MISO (pin 12) to input
  
  interrupts ();

  // read for next time around
  Nunchuk::read ();
}  // end of loop

With the assistance of that I was able to play the game. Now I'll take a look at how the code works. :slight_smile: