/** * @brief Creates a dialog with prompt and specified allowed user inputs * @param char* prompt - Pointer to filename for prompt to play - prefixed with * mode fileset * @param char control_mask - Controls to allow on dialog re: io.h for masks * @return char - Button corresponding to user input */ char create_dialog(char* prompt, char control_mask) { // Gets initialised on first call after a successful return or first run if (io_dialog_initialised == false) { log_msg("[IO] Creating dialog: %s\n\r", prompt); io_dialog_init(control_mask); } char last_dot = get_dot(); switch (last_dot) { // Returns NO_DOTS but also plays prompt when fresh call or after a certain // number of incorrect tries case NO_DOTS: if (io_dialog_incorrect_tries == -1) { play_mp3(mode_fileset, prompt); io_dialog_incorrect_tries++; } return NO_DOTS; break; // Returns dot if enabled, o/w registers error case '1': case '2': case '3': case '4': case '5': case '6': if (io_dialog_dots_enabled[CHARTOINT(last_dot) - 1] == true) { log_msg("[IO] Returning dot %c\n\r", last_dot); io_dialog_reset(); return last_dot; } else { io_dialog_error(); return NO_DOTS; } break; // Returns control button if enabled, o/w registers error case ENTER: case CANCEL: if (io_dialog_enter_cancel_enabled == true) { io_dialog_reset(); return last_dot; } else { io_dialog_error(); return NO_DOTS; } break; // Returns control button if enabled, o/w registers error case LEFT: case RIGHT: if (io_dialog_left_right_enabled == true) { io_dot = last_dot; io_dialog_reset(); return last_dot; } else { io_dialog_error(); return NO_DOTS; } break; // Should not get here default: log_msg("[IO] Invalid dot: %x\n\r", last_dot); quit_mode(); return NO_DOTS; break; } }
/** * @brief Gets current cell * @param void * @return char - Cell pattern with 2 MSB as controls for ENTER, LEFT, RIGHT * terminated cell entry, WITH_CANCEL for CANCEL and NO_DOTS when nothing to * return (wait) */ char get_cell(void) { char last_dot = get_dot(); char ret_val = NO_DOTS; switch(last_dot) { case NO_DOTS: return NO_DOTS; break; // If one of the dots, then add to cell state case '1': case '2': case '3': case '4': case '5': case '6': io_cell_state = add_dot(io_cell_state, last_dot); return NO_DOTS; break; // If a control is pressed, return cell state with control preserved in // 2 MSB of char case ENTER: case LEFT: case RIGHT: case CANCEL: ret_val = io_cell_state; io_cell_state = NO_DOTS; switch (last_dot) { case ENTER: io_user_cancel = false; io_user_abort = false; log_msg("[IO] Cell pattern: %x\n\r", ret_val | WITH_ENTER); return ret_val | WITH_ENTER; break; case LEFT: io_user_cancel = false; io_user_abort = false; return ret_val | WITH_LEFT; break; case RIGHT: io_user_cancel = false; io_user_abort = false; return ret_val | WITH_RIGHT; break; case CANCEL: if (ret_val == 0x00) { if (io_user_cancel == true) { io_user_abort = true; io_user_cancel = false; } else { io_user_cancel = true; io_user_abort = false; } } return ret_val | WITH_CANCEL; break; // Should not execute this code default: log_msg("[IO] Invalid dot: %x\n\r", last_dot); quit_mode(); return NO_DOTS; break; } break; // Should not execute this code default: log_msg("[IO] Invalid dot: %x\n\r", last_dot); quit_mode(); return NO_DOTS; break; } }
/** * @brief Gets a line of raw cells from the user * @param void * @return bool - true if io_line is ready for further processing, false * otherwise */ bool get_line(void) { if (io_line_ready == false) { io_line_reset(); } if (io_user_abort) { return false; } char last_cell = get_cell(); char pattern = GET_CELL_PATTERN(last_cell); char control = GET_CELL_CONTROL(last_cell); // If last cell was empty, there's nothing to do so return false and wait if (last_cell == NO_DOTS) { return false; } // Otherwise, if cell was recorded, save it to io_line if (pattern) { io_line[io_line_cell_index] = pattern; } switch (control) { // ENTER - Advance cell, add EOT and return true case WITH_ENTER: io_line_next_cell(); io_line[io_line_cell_index] = END_OF_TEXT; io_line_ready = false; return true; break; /* RIGHT is used to switch to previous cell because Braille is entered this way */ // RIGHT - Select prev cell case WITH_RIGHT: play_mp3(lang_fileset, MP3_PREV_CELL); io_line_prev_cell(); if (!pattern) { play_pattern(io_line[io_line_cell_index]); } return false; break; /* LEFT is used to switch to next cell because Braille is entered this way */ // LEFT - Select next cell case WITH_LEFT: play_mp3(lang_fileset, MP3_NEXT_CELL); io_line_next_cell(); if (!pattern) { play_pattern(io_line[io_line_cell_index]); } return false; break; // CANCEL - Clear current cell case WITH_CANCEL: io_line_clear_cell(); return false; break; // Should not execute this code default: log_msg("[IO] Invalid control: %x\n\r", control); quit_mode(); return false; break; } }
/** * @brief Step through the main stages in the code. * @return Void */ void mode_14_main() { switch(current_state) { case INITIAL: play_welcome(); current_state = CHOOSE_LEVEL; break; case CHOOSE_LEVEL: last_dot = create_dialog(MP3_CHOOSE_LEVELS_3, (DOT_1 | DOT_2 | DOT_3 | CANCEL)); switch (last_dot) { case '1': play_direction(MP3_EASY_MODE); strings_to_wordlist(easy, ARRAYLEN(easy), &mode_14_dict); current_state = GENERATE_QUESTION; break; case '2': play_direction(MP3_MEDIUM_MODE); strings_to_wordlist(medium, ARRAYLEN(medium), &mode_14_dict); current_state = GENERATE_QUESTION; break; case '3': play_direction(MP3_HARD_MODE); strings_to_wordlist(hard, ARRAYLEN(hard), &mode_14_dict); current_state = GENERATE_QUESTION; break; case CANCEL: log_msg("Quitting to main menu."); quit_mode(); break; default: break; } break; case GENERATE_QUESTION: print_words_in_list(&mode_14_dict); play_direction(MP3_INSTRUCTIONS_WORD); curr_mistakes = 0; get_next_word_in_wordlist(&mode_14_dict, &mode_14_chosen_word); log_msg("[mode_14] Next word: %s", mode_14_chosen_word->name); current_state = PROMPT; break; case PROMPT: play_direction(MP3_SPELL_WORD); speak_word(mode_14_chosen_word); current_state = GET_INPUT; break; case GET_INPUT: cell = get_cell(); if (cell == NO_DOTS) break; cell_pattern = GET_CELL_PATTERN(cell); cell_control = GET_CELL_CONTROL(cell); switch (cell_control) { case WITH_ENTER: current_state = CHECK_ANSWER; break; case WITH_LEFT: current_state = REPROMPT; break; case WITH_RIGHT: current_state = GENERATE_QUESTION; break; case WITH_CANCEL: break; } break; case CHECK_ANSWER: mode_14_curr_cell = get_next_cell_in_word(mode_14_chosen_word); log_msg("Target cell: %x, inputted cell: %x.", mode_14_curr_cell, cell_pattern); if (cell_pattern == mode_14_curr_cell) { if (mode_14_chosen_word->curr_letter == mode_14_chosen_word->num_letters - 1) { // done mode_14_correct_answer(); current_state = GENERATE_QUESTION; } else { // correct but not done play_feedback(MP3_GOOD); play_direction(MP3_NEXT_LETTER); curr_mistakes = 0; current_state = GET_INPUT; } } else { mode_14_incorrect_answer(); current_state = REPROMPT; } break; case REPROMPT: if (curr_mistakes >= max_mistakes) { play_direction(MP3_PLEASE_PRESS); char* letter_name = get_eng_letter_name_by_cell(mode_14_curr_cell); play_lang_audio(letter_name); if (curr_mistakes >= max_mistakes + 1) play_cell(mode_14_curr_cell); } else { play_direction(MP3_SPELL_WORD); speak_word(mode_14_chosen_word); if (mode_14_chosen_word->curr_glyph > -1) { // not at beginning of word play_feedback(MP3_SPELLING_SO_FAR); speak_letters_so_far(mode_14_chosen_word); play_direction(MP3_NEXT_LETTER); } } current_state = GET_INPUT; break; default: log_msg("Invalid state_t %d", current_state); quit_mode(); break; } }
/** * @brief Step through the main stages in the code. * @return Void */ void sound_game_main(script_t* SCRIPT_ADDRESS, char* LANG_FILESET, char* MODE_FILESET) { switch(next_state) { case STATE_MENU: if (io_user_abort == true) { PRINTF("[MD3] Quitting to main menu\n\r"); quit_mode(); io_init(); } cell = get_cell(); if (cell == NO_DOTS) { break; } cell_pattern = GET_CELL_PATTERN(cell); cell_control = GET_CELL_CONTROL(cell); switch (cell_control) { /*If user input is A, enter SUBMODE_PLAY; if input is B, enter SUBMODE_LEARN; else go back to menu*/ case WITH_ENTER: user_glyph = search_script(this_script, cell_pattern); if (cell_pattern == ENG_A) { play_glyph(user_glyph); submode = SUBMODE_PLAY; next_state = STATE_GENQUES; } else if (cell_pattern == ENG_B) { play_glyph(user_glyph); submode = SUBMODE_LEARN; next_state = STATE_GENQUES; } else { play_mp3(lang_fileset, MP3_INVALID_PATTERN); next_state = STATE_MENU; } break; case WITH_LEFT:case WITH_RIGHT:case WITH_CANCEL: break; } break; case STATE_GENQUES: length_entered_word = 0; current_word_index = 0; sound_source = sound_source_list[choose_sound_source()]; user_glyph = NULL; curr_glyph = NULL; user_word = free_word(user_word); curr_word = free_word(curr_word); next_state = STATE_PROMPT; break; case STATE_PROMPT: switch(submode) { case SUBMODE_PLAY: play_mp3(MODE_FILESET, "PLSA"); play_sound(MODE_FILESET, sound_source, false); break; case SUBMODE_LEARN: play_mp3(MODE_FILESET, "PLSB"); play_sound(MODE_FILESET, sound_source, true); break; default: break; } next_state = STATE_INPUT; break; case STATE_INPUT: if (io_user_abort == true) { PRINTF("[MD3] User aborted input\n\r"); next_state = STATE_REPROMPT; io_init(); } cell = get_cell(); if (cell == NO_DOTS) { break; } cell_pattern = GET_CELL_PATTERN(cell); cell_control = GET_CELL_CONTROL(cell); switch (cell_control) { case WITH_ENTER: user_glyph = search_script(this_script, cell_pattern); next_state = STATE_CHECK; PRINTF("[MD3] Checking answer\n\r"); break; case WITH_LEFT: next_state = STATE_PROMPT; break; case WITH_RIGHT: next_state = STATE_REPROMPT; break; case WITH_CANCEL: break; } break; case STATE_CHECK: curr_glyph = search_script(this_script, get_bits_from_letter(sound_source[length_entered_word])); if (glyph_equals(curr_glyph, user_glyph)) { play_glyph(curr_glyph); incorrect_tries = 0; length_entered_word++; user_word = add_glyph_to_word(user_word, user_glyph); if(length_entered_word != strlen(sound_source)) { play_mp3(lang_fileset, "GOOD"); next_state = STATE_INPUT; } else { play_mp3(lang_fileset, "GOOD"); play_mp3(lang_fileset, "NCWK"); switch (submode){ case SUBMODE_LEARN: play_sound(MODE_FILESET, sound_source, true); play_mp3(MODE_FILESET, "SAYS"); play_sound(MODE_FILESET, sound_source, false); break; case SUBMODE_PLAY: play_word(user_word); play_sound(MODE_FILESET, sound_source, true); } next_state = STATE_GENQUES; } } else { play_glyph(user_glyph); incorrect_tries++; PRINTF("[MD3] User answered incorrectly\n\r"); play_mp3(lang_fileset, "NO"); play_mp3(lang_fileset, MP3_TRY_AGAIN); play_word(user_word); if (incorrect_tries == MAX_INCORRECT_TRIES_1) { play_mp3(MODE_FILESET, "PLWR"); play_sound(MODE_FILESET, sound_source, true); curr_word = word_to_glyph_word(this_script, sound_source); play_word(curr_word); } else if (incorrect_tries >= 6) { play_glyph(curr_glyph); play_mp3(MODE_FILESET, "PRSS"); play_dot_sequence(curr_glyph); } next_state = STATE_INPUT; } break; case STATE_REPROMPT: switch(create_dialog("SKIP", ENTER_CANCEL | LEFT_RIGHT)) { case NO_DOTS: break; case CANCEL: PRINTF("[MD3] Reissuing prompt"); next_state = STATE_PROMPT; scrolled = false; break; case ENTER: PRINTF("[MD3] Skipping sound_source"); if (scrolled) next_state = STATE_PROMPT; else next_state = STATE_GENQUES; scrolled = false; break; case RIGHT: case LEFT: PRINTF("[MD3] Next sound_source"); length_entered_word = 0; current_word_index = 0; sound_source = sound_source_list[choose_sound_source()]; user_word = NULL; switch(submode) { case SUBMODE_PLAY: play_sound(MODE_FILESET, sound_source, false); break; case SUBMODE_LEARN: play_sound(MODE_FILESET, sound_source, true); break; default: break; } scrolled = true; break; default: break; } break; default: break; } }
void md12_main(void) { switch (next_state) { case STATE_MENU: switch(create_dialog(MP3_MENU, DOT_1 | DOT_2 | ENTER_CANCEL)) { case NO_DOTS: break; case '1': PRINTF("[MD12] Submode: Learn\n\r"); play_mp3(MODE_FILESET, MP3_INSTRUCTIONS); submode = SUBMODE_LEARN; next_state = STATE_GENQUES; break; case '2': PRINTF("[MD12] Submode: Play\n\r"); play_mp3(MODE_FILESET, MP3_INSTRUCTIONS); submode = SUBMODE_PLAY; next_state = STATE_GENQUES; break; case CANCEL: PRINTF("[MD12] Quitting to main menu\n\r"); quit_mode(); break; case ENTER: PRINTF("[MD12] Re-issuing main menu prompt\n\r"); next_state = STATE_MENU; break; default: break; } break; case STATE_GENQUES: switch (submode) { case SUBMODE_LEARN: curr_glyph = get_next_glyph(SCRIPT_ADDRESS); if (curr_glyph == NULL) { reset_script_indices(SCRIPT_ADDRESS); next_state = STATE_GENQUES; break; } break; case SUBMODE_PLAY: curr_glyph = get_random_glyph(SCRIPT_ADDRESS); break; default: break; } sprintf(dbgstr, "[MD12] Next glyph: %s\n\r", curr_glyph->sound); PRINTF(dbgstr); play_mp3(LANG_FILESET, MP3_NEXT_LETTER); next_state = STATE_PROMPT; break; case STATE_PROMPT: switch(submode) { case SUBMODE_LEARN: play_glyph(curr_glyph); play_mp3(MODE_FILESET, MP3_FOR_X_PRESS_DOTS); play_dot_sequence(curr_glyph); break; case SUBMODE_PLAY: play_silence(500); play_glyph(curr_glyph); break; default: break; } next_state = STATE_INPUT; break; case STATE_INPUT: if (io_user_abort == true) { PRINTF("[MD12] User aborted input\n\r"); next_state = STATE_REPROMPT; io_init(); } if (get_character(&user_glyph) == true) { PRINTF("[MD12] Valid character received\n\r"); next_state = STATE_CHECK; io_init(); } break; case STATE_CHECK: if (glyph_equals(curr_glyph, user_glyph)) { incorrect_tries = 0; PRINTF("[MD12] User answered correctly\n\r"); play_mp3(LANG_FILESET, MP3_CORRECT); play_mp3(SYS_FILESET, MP3_TADA); next_state = STATE_GENQUES; } else { incorrect_tries++; PRINTF("[MD12] User answered incorrectly\n\r"); play_mp3(LANG_FILESET, MP3_INCORRECT); play_mp3(LANG_FILESET, MP3_TRY_AGAIN); next_state = STATE_PROMPT; if (incorrect_tries >= MAX_INCORRECT_TRIES) { play_glyph(curr_glyph); play_mp3(MODE_FILESET, MP3_FOR_X_PRESS_DOTS); play_dot_sequence(curr_glyph); play_mp3(LANG_FILESET, MP3_TRY_AGAIN); next_state = STATE_INPUT; } } break; case STATE_REPROMPT: switch(create_dialog(MP3_REPROMPT, DOT_1 | DOT_2 | DOT_3 | ENTER_CANCEL | LEFT_RIGHT)) { case NO_DOTS: break; case '1': PRINTF("[MD12] Skipping character\n\r"); next_state = STATE_GENQUES; break; case '2': PRINTF("[MD12] Playing pattern\n\r"); play_glyph(curr_glyph); play_mp3(MODE_FILESET, MP3_FOR_X_PRESS_DOTS); play_dot_sequence(curr_glyph); play_mp3(LANG_FILESET, MP3_TRY_AGAIN); next_state = STATE_INPUT; break; case '3': PRINTF("[MD12] Reissuing prompt\n\r"); next_state = STATE_PROMPT; break; case CANCEL: PRINTF("[MD12] Cancelling to submode menu\n\r"); md12_reset(); break; case ENTER: PRINTF("[MD12] Reissuing prompt\n\r"); next_state = STATE_PROMPT; break; case LEFT: PRINTF("[MD12] Previous letter\n\r"); switch (submode) { case SUBMODE_LEARN: curr_glyph = get_prev_glyph(SCRIPT_ADDRESS); if (curr_glyph == NULL) { curr_glyph = get_next_glyph(SCRIPT_ADDRESS); } break; case SUBMODE_PLAY: curr_glyph = get_random_glyph(SCRIPT_ADDRESS); break; default: break; } play_glyph(curr_glyph); break; case RIGHT: PRINTF("[MD12] Next letter\n\r"); switch (submode) { case SUBMODE_LEARN: curr_glyph = get_next_glyph(SCRIPT_ADDRESS); if (curr_glyph == NULL) { curr_glyph = get_prev_glyph(SCRIPT_ADDRESS); } break; case SUBMODE_PLAY: curr_glyph = get_random_glyph(SCRIPT_ADDRESS); break; default: break; } play_glyph(curr_glyph); break; default: break; } break; default: break; } }
void mode_letter_game_main() { switch (current_state) { case INITIAL: play_welcome(); play_submode_choice(); current_state = CHOOSE_LEVEL; break; case CHOOSE_LEVEL: switch(create_dialog(NULL, DOT_1 | DOT_2 | ENTER_CANCEL)) { case '1': log_msg("Submode: Learn"); play_letter_instructions(); submode = SUBMODE_LEARN; sort(this_script->letters, this_script->num_letters); current_state = GENERATE_QUESTION; break; case '2': log_msg("Submode: Play"); play_letter_instructions(); shuffle(this_script->letters, this_script->num_letters); should_shuffle = true; current_state = GENERATE_QUESTION; break; case CANCEL: log_msg("Quitting to main menu"); quit_mode(); break; case ENTER: log_msg("Re-issuing main menu prompt"); play_submode_choice(); current_state = CHOOSE_LEVEL; break; default: break; } break; case GENERATE_QUESTION: curr_glyph = get_next_letter(this_script, should_shuffle); log_msg("Next glyph: %s", curr_glyph->sound); play_next_letter_prompt(); current_state = PROMPT; break; case PROMPT: play_glyph(curr_glyph); switch(submode) { case SUBMODE_LEARN: play_dot_prompt(); play_dot_sequence(curr_glyph); break; case SUBMODE_PLAY: default: break; } current_state = GET_INPUT; break; case GET_INPUT: if (io_user_abort == true) { log_msg("User aborted input"); current_state = PROMPT; io_init(); } cell = get_cell(); if (cell == NO_DOTS) break; cell_pattern = GET_CELL_PATTERN(cell); cell_control = GET_CELL_CONTROL(cell); log_msg("Pattern %d, control %d.", cell_pattern, cell_control); switch (cell_control) { case WITH_ENTER: user_glyph = search_script(this_script, cell_pattern); current_state = CHECK_ANSWER; break; case WITH_LEFT: current_state = PROMPT; break; case WITH_RIGHT: current_state = GENERATE_QUESTION; break; case WITH_CANCEL: default: break; } break; case CHECK_ANSWER: if (glyph_equals(curr_glyph, user_glyph)) { if (curr_glyph -> next == NULL) { mistakes = 0; log_msg("User answered correctly"); play_right(); current_state = GENERATE_QUESTION; } else { curr_glyph = curr_glyph->next; play_next_cell_prompt(); if (submode == SUBMODE_LEARN) play_dot_sequence(curr_glyph); else play_glyph(curr_glyph); current_state = GET_INPUT; } } else { mistakes++; log_msg("User answered incorrectly"); play_wrong(); curr_glyph = get_root(this_script, curr_glyph); current_state = PROMPT; if (mistakes >= max_mistakes) { play_glyph(curr_glyph); play_dot_prompt(); play_dot_sequence(curr_glyph); current_state = GET_INPUT; } } break; default: log_msg("Invalid state_t %d", current_state); quit_mode(); break; } }
/* * @brief Step through the main stages in the code. * @return Void */ void mode_5_main(void) { switch(current_state) { case INITIAL: /* if (!done_rd_dict) { log_msg("Reading dictionary file..."); play_direction(MP3_PLEASE_WAIT) init_read_dict((unsigned char *)"wordsEn.txt"); while (!done_rd_dict) read_dict_file(); } */ play_welcome(); current_state = REQUEST_QUESTION; break; case REQUEST_QUESTION: if (got_input) { got_input = false; current_state = GENERATE_QUESTION; } break; case GENERATE_QUESTION: if (cell == 0) { // if return was entered twice mode_5_chosen_word[input_word_index] = '\0'; // if (bin_srch_dict((unsigned char *)mode_5_chosen_word)) { // valid word; switch to player 2 // @TODO "valid word, please hand device to player 2 and press enter when ready" // play_mode_audio(MP3_VALID_WORD_PASS_DEVICE); input_word_index = 0; play_feedback(MP3_YOUR_WORD_IS); play_string(mode_5_chosen_word, strlen(mode_5_chosen_word)); play_feedback(MP3_PASS_DEVICE_PRESS_ENTER); current_state = SWITCH_USERS; /* } else { // invalid word; clear variables and try again play_feedback(MP3_WORD_NOT_FOUND); mode_5_reset(); current_state = REQUEST_QUESTION; } */ } else if (mode_5_valid_letter(cell)) { // letter valid; word not complete log_msg("Letter %c entered.", entered_letter); char letter[2] = {entered_letter, '\0'}; play_lang_audio(letter); // reset because too many letters were input if (input_word_index == MAX_WORD_LENGTH) { log_msg("Too many letters inputted!"); play_feedback(MP3_TOO_LONG); mode_5_reset(); current_state = REQUEST_QUESTION; break; } mode_5_chosen_word[input_word_index] = entered_letter; // add letter to chosen_word input_word_index++; current_state = REQUEST_QUESTION; } else { // invalid letter play_feedback(MP3_INVALID_PATTERN); current_state = REQUEST_QUESTION; } break; case SWITCH_USERS: if (got_input) { got_input = false; current_state = PROMPT; } break; case PROMPT: log_msg("Entering ask for guess state."); play_direction(MP3_PLAYER_2); play_feedback(MP3_YOUR_WORD_IS_NOW); play_string(input_word, strlen(mode_5_chosen_word)); play_direction(MP3_GUESS_A_LETTER); current_state = GET_INPUT; break; case GET_INPUT: if (got_input) { got_input = false; current_state = PROCESS_ANSWER; } break; case PROCESS_ANSWER: log_msg("Entering checkans state."); if (cell == 0) // nothing entered: repeat word current_state = GAME_OVER; else if (mode_5_valid_letter(cell)) { // valid letter: read aloud char buff[7]; sprintf(buff, "%c", entered_letter); play_lang_audio(buff); //@todo fix this current_state = CHECK_ANSWER; } else { play_feedback(MP3_INVALID_PATTERN); mistakes++; current_state = GAME_OVER; } break; case CHECK_ANSWER: log_msg("Entering check match state."); if (mode_5_place_letter()) // letters is in word; fn places it play_feedback(MP3_YES); else { play_feedback(MP3_NO); if (!mode_5_is_past_mistake(entered_letter)) { mistake_pool[mistakes] = entered_letter; mistakes++; } else play_feedback(MP3_YOU_HAVE_MADE_THE_SAME_MISTAKE); } current_state = GAME_OVER; break; case GAME_OVER: log_msg("Entering evaluate game state."); if (!strncmp(input_word, mode_5_chosen_word, strlen(mode_5_chosen_word))) { play_feedback(MP3_YOU_HAVE_GUESSED_THE_WORD); play_tada(); current_state = INITIAL; } else if (mistakes == max_mistakes) { play_feedback(MP3_7_MISTAKES_YOU_MISSED); play_string(mode_5_chosen_word, strlen(mode_5_chosen_word)); current_state = INITIAL; } else { if (mistakes > 0) { play_feedback(MP3_YOU_HAVE); play_number(max_mistakes - mistakes); if (max_mistakes - mistakes == 1) play_feedback(MP3_MISTAKE_REMAINING); else play_feedback(MP3_MISTAKES_REMAINING); } current_state = PROMPT; } break; default: log_msg("Invalid state_t %d", current_state); quit_mode(); break; } }