Last active
December 20, 2015 01:39
-
-
Save AstraLuma/6050901 to your computer and use it in GitHub Desktop.
typedef, void functions, and other issues.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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