ELEC2645 (2018/19) / Mbed 2 deprecated el17lw

Dependencies:   mbed

Menu/Menu.cpp

Committer:
lewisgw
Date:
2019-04-20
Revision:
21:20478f086bc2
Parent:
20:a8cad4e044ea
Child:
26:4253656c0755

File content as of revision 21:20478f086bc2:

#include "Menu.h"

// Define sprite arrays.
int menu_sprite[23][80] =   { 
  { 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,1 },
  { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
  1,1,1 },
  { 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
  0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
  1,1,0 },
  { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,
  0,0,0 },
  { 0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
  0,0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,
  0,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
  1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
  0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,
  1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
  1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,
  1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,
  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1,0,0,0,1,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,
  1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,
  0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,1,
  1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,
  1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,
  0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 },
  { 0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,
  1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0 }
};

// Define the finite state machine for three different states: running game, 
// display
// menu and display controls, {ouput,{a,b,c,d}} where a,b,c,d are inputs.
// The ouputs have been assigned to 0,1,2.  
// There are four different relevent input combinations that have been assigned 
// to: 0,1,2,3.
State _fsm[3] = { 
  {0,{0,1,0,0}},
  {1,{1,1,0,2}},
  {2,{2,1,2,0}}
};   

// Constructor and distructor.
Menu::Menu() {}

Menu::~Menu() {}

void Menu::init() { 
  _state = 1;  // Starting state is the menu.  
  _controller.init();
  _tone_flag = false;
  _tone_counter = 0;
  _chord_counter = 0;
}

void Menu::run(N5110 &lcd, Gamepad &gamepad) {
  set_input(gamepad.check_event(Gamepad::START_PRESSED), 
    gamepad.check_event(Gamepad::BACK_PRESSED),
    gamepad.check_event(Gamepad::X_PRESSED));
  // Select the current output, execute that output via the output function and 
  // update to the next state depending on the input.
  _output = _fsm[_state].output;
  output(lcd, gamepad);
  _state = _fsm[_state].next_state[_menu_input];    
}

void Menu::output(N5110 &lcd, Gamepad &gamepad) {
  // 0, 1 and 2 have been assigned to the output of each state respectivley.
  if (_output == 0) {
    run_game(lcd, gamepad);
  } else if (_output == 1) {
    display_menu(lcd, gamepad);
  } else {
    display_controls(lcd, gamepad);
  }
}

void Menu::set_input(bool start, bool back, bool x) {
  // 0, 1, 2, 3 have been assigned to each relevent input combination.
  if (!start && !back && !x) {
    _menu_input = 0;  // Nothing is pressed.
  } else if (!start && back) {
    _menu_input = 1;  // Only back is pressed.
  } else if (start && !back) {
    _menu_input = 2;  // Only start is pressed.
  } else if (x) {
    _menu_input = 3;  // Only X is pressed.
  }
} 

void Menu::run_game(N5110 &lcd, Gamepad &gamepad) {
  _controller.run_game_engine(lcd, gamepad);
}

void Menu::display_controls(N5110 &lcd, Gamepad &gamepad) {
  lcd.drawLine(0,0,84,0,FILL_BLACK);
  lcd.drawLine(0,6,84,6,FILL_BLACK);
  lcd.drawLine(0,32,84,32,FILL_BLACK);
  lcd.drawLine(0,38,84,38,FILL_BLACK);
  lcd.printString("JOYSTICK:",0,0);
  lcd.printString("-Move left",0,1);
  lcd.printString("-Move right",0,2);
  lcd.printString("-Move down",0,3);
  lcd.printString("A:",0,4);
  lcd.printString("-Jump   (back)",0,5);
  play_tone(gamepad);
}

void Menu::display_menu(N5110 &lcd, Gamepad &gamepad) {
  lcd.drawLine(0,0,84,0,FILL_BLACK);
  lcd.drawLine(0,6,84,6,FILL_BLACK);
  lcd.drawLine(0,24,84,24,FILL_BLACK);
  lcd.printString("SKATER",24,0);
  lcd.printString("START- Play!",0,1);   
  lcd.printString("X- Controls",0,2); 
  lcd.drawSprite(1,25,23,80,(int*)menu_sprite); 
  play_tone(gamepad);
}

void Menu::play_tone(Gamepad &gamepad) {
  // Plays a musical tune in 3/4 based on two chords, A and F in Aminor.
  // It switches between each chord every 12 game loops via chord counter.  
  _tone_flag = !_tone_flag;
  _tone_counter++;
  _chord_counter++;
  if (_chord_counter < 12) {
    play_chord_a(gamepad);
  } else {
    if (_chord_counter == 24) _chord_counter = 0;
    play_chord_b(gamepad);
  }  
  wait(0.14);  // Determines how fast the musical tune is played.
}

void Menu::play_chord_a(Gamepad &gamepad) {
  // For each chord, the first set of two notes is played for 5 game loops and 
  // the second set for 2 game loops via tone counter.
  // Each note is alternated every game loop via tone flag.  
  if (_tone_counter < 5) {
    if (_tone_flag) {
      gamepad.tone(220, 0.5);
    } else {
      gamepad.tone(440, 0.1);
    }
  } else {
    if (_tone_counter == 6) _tone_counter = 0;
    if (_tone_flag) {
      gamepad.tone(174.61, 0.1);
    } else {
      gamepad.tone(246.94, 0.1);
    }
  }
} 

void Menu::play_chord_b(Gamepad &gamepad) {
  if (_tone_counter < 5) {
    if (_tone_flag) {
      gamepad.tone(174.61, 0.5);
    } else {
      gamepad.tone(349.23, 0.1);
    }
  } else {
    if (_tone_counter == 6) _tone_counter = 0;
    if (_tone_flag) {
      gamepad.tone(659.25, 0.1);
    } else {
      gamepad.tone(220, 0.1);
    }
  }
}