Skip to content

Instantly share code, notes, and snippets.

@AstraLuma
Last active December 20, 2015 01:39
Show Gist options
  • Save AstraLuma/6050901 to your computer and use it in GitHub Desktop.
Save AstraLuma/6050901 to your computer and use it in GitHub Desktop.
typedef, void functions, and other issues.
#define SHOW_LENGTH 350 // How long to show each color
#define WAIT_LENGTH 1000 // How long to wait for the user to tap each one
#define TIME_FOR_TURN(t) 500 // Time for each correct turn
#define WINNER_BONUS (15*1000) // Time for winning the game
/*
RXLED
PB3:6 Buttons
PD0:2 Center Input selector
TXO Radio Transmit(?)
PD4 Color Button Select
RXLED
PF4:7 LEDs
Sound Gen
*/
#define GREEN 1
#define RED 2
#define YELLOW 4
#define BLUE 8
#define BUTTONS ((~PINB >> 3) & 0b1111)
#define turn_t uint8_t
#define button_t uint8_t
#define DMASK 0b00010111
#define CLEAR_SELECTOR ( DDRD = ~DMASK|0b1000 )
#define SET_SELECTOR(m) ( CLEAR_SELECTOR, DDRD |= (m) )
#define SELECT_SKILL 0b001 //TODO: What are these values?
#define SELECT_GAME 0b010
#define SELECT_SLL 0b100
#define SELECT_COLORS 0b10000
#define SET_COLORS(c) (PORTF = (c) << 4)
#define BUTTON_START GREEN
#define BUTTON_LAST RED
#define BUTTON_LONGEST YELLOW
unsigned long shutoffTime = 0;
void setup() {
DDRB = 0;
PORTB = 0xFF;
CLEAR_SELECTOR;
PORTD = ~DMASK;
DDRF = 0xF0;
PORTF = 0;
randomSeed(analogRead(5)); // Pin isn't even broken out
}
/// Get the skill level, from 1 to 4
uint8_t readSkillLevel()
{
SET_SELECTOR(SELECT_SKILL);
switch(BUTTONS)
{
case RED:
return 1;
case YELLOW:
return 2;
case BLUE:
return 3;
case GREEN:
return 4;
default:
return 0;
}
}
/// Get the game mode, from 1 to 3
uint8_t readGame()
{
SET_SELECTOR(SELECT_GAME);
switch(BUTTONS)
{
case RED:
return 1;
case GREEN:
return 2;
case YELLOW:
return 3;
default:
return 0;
}
}
/// Get the Start/Last/Longest buttons
button_t readButtons()
{
SET_SELECTOR(SELECT_SLL);
return BUTTONS;
}
/// Get the color inputs, see bitmask
button_t readColors()
{
SET_SELECTOR(SELECT_COLORS);
return BUTTONS;
}
#define STATE_MENU 0
#define STATE_GAME 1
uint8_t game, skill;
uint8_t MainMenu(bool init)
{
uint8_t buttons = readButtons();
game = readGame();
skill = readSkillLevel();
SET_COLORS(0);
if (buttons & BUTTON_START)
return STATE_GAME;
return STATE_MENU;
}
#define MAX_TURNS 30
turn_t turn = 0; // turn counter
int colorSequence[MAX_TURNS];
void failGame(turn_t i)
{
// TODO: Do a bunch of failure-related things
setMister(false);
}
void winGame(turn_t i)
{
// TODO: Do a bunch of winning-related things
addTime(WINNER_BONUS);
}
uint8_t PlayGame(bool init)
{
static uint8_t gamestate = 0; // 0=Show sequence, 1=Read Sequence
static turn_t i = 0; // Where we are in the sequence, either displaying or reading
static unsigned long waitUntil = 0; // Idle until millis() reaches this value
if (init)
{
for (int i=0; i<MAX_TURNS; i++)
{
colorSequence[i] = 1 << random(1, 5);
}
turn = 0;
gamestate = 0;
waitUntil = 0;
}
switch (gamestate)
{
case 0: // Show sequence
{
if (waitUntil == 0)
{
SET_COLORS(colorSequence[i]);
// SND:Begin Tone
waitUntil = millis() + SHOW_LENGTH;
}
else if (millis() >= waitUntil)
{
waitUntil = 0;
SET_COLORS(0);
// SND:Stop
i++;
}
if (i >= turn)
{
i = 0;
gamestate = 1; // User input
}
}
break;
case 1: // Read input
{
button_t buttons = readColors();
if (buttons)
{
if (buttons == colorSequence[i])
{
// Success!
i++;
waitUntil = 0;
}
else
{
// Failure!
failGame(i);
return STATE_MENU;
}
}
else if (waitUntil == 0)
{
waitUntil = millis() + WAIT_LENGTH;
}
else if (millis() >= waitUntil)
{
// Failure!
failGame(i);
return STATE_MENU;
}
if (i >= turn)
{
i = 0;
turn++;
gamestate = 0; // Display the next sequence
addTime(TIME_FOR_TURN(turn));
}
if (turn >= MAX_TURNS)
{
// WINNAR!
winGame(i);
return STATE_MENU;
}
}
break;
default:
gamestate = 0;
}
return STATE_GAME;
}
void loop() {
static uint8_t state = STATE_MENU;
static bool init = true;
uint8_t oldstate = state;
if (init)
{
// SND:Kill
}
switch (state)
{
case STATE_MENU:
state = MainMenu(init);
break;
case STATE_GAME:
state = PlayGame(init);
break;
default:
state = STATE_MENU;
}
init = (state != oldstate);
if (millis() >= shutoffTime)
{
setMister(false);
}
}
bool misterOn = false;
void addTime(unsigned long t)
{
if (misterOn)
{
shutoffTime += t;
}
else
{
setMister(true);
shutoffTime = millis() + t;
}
}
void setMister(bool value)
{
// TODO: Send refreshes
if (value == misterOn)
return;
// TODO: Send update over radio
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment