/** * @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 md14_main() { switch(md14_next_state) { case MD14_STATE_INTRO: lang_fileset = LANG_FILESET; mode_fileset = MODE_FILESET; play_mp3(MODE_FILESET, "WELC"); md14_next_state = MD14_STATE_LVLSEL; srand(timer_rand()); break; case MD14_STATE_LVLSEL: md14_last_dot = create_dialog("LVL3", (DOT_1 | DOT_2 | DOT_3)); if (md14_last_dot == NO_DOTS) break; switch (md14_last_dot) { case '1': play_mp3(LANGUAGE, "EASY"); strings_to_wordlist(easy, ARRAYLEN(easy), &md14_dict); break; case '2': play_mp3(LANGUAGE, "MED"); strings_to_wordlist(medium, ARRAYLEN(medium), &md14_dict); break; case '3': play_mp3(LANGUAGE, "HARD"); strings_to_wordlist(hard, ARRAYLEN(hard), &md14_dict); break; } print_words_in_list(&md14_dict); play_mp3(MODE_FILESET, "INST"); md14_next_state = MD14_STATE_GENQUES; break; case MD14_STATE_GENQUES: md14_reset(); get_next_word_in_wordlist(&md14_dict, &md14_chosen_word); log_msg("[MD14] Next word: %s\n\r", md14_chosen_word->name); md14_next_state = MD14_STATE_PROMPT; break; case MD14_STATE_PROMPT: play_mp3(LANGUAGE, "SPEL"); speak_word(md14_chosen_word); md14_next_state = MD14_STATE_INPUT; break; case MD14_STATE_INPUT: md14_cell = get_cell(); if (md14_cell == NO_DOTS) { break; } md14_cell_pattern = GET_CELL_PATTERN(md14_cell); md14_cell_control = GET_CELL_CONTROL(md14_cell); switch (md14_cell_control) { case WITH_ENTER: md14_user_cell.pattern = md14_cell_pattern; md14_next_state = MD14_STATE_CHECK; log_msg("[MD14] Checking answer\n\r"); break; case WITH_LEFT: md14_next_state = MD14_STATE_REPROMPT; break; case WITH_RIGHT: md14_next_state = MD14_STATE_GENQUES; break; case WITH_CANCEL: break; } break; case MD14_STATE_CHECK: md14_speak_inputted_cell(); get_next_cell_in_word(md14_chosen_word, &md14_curr_cell); log_msg("Target cell: %x, inputted cell: %x.\n\r", md14_curr_cell.pattern, md14_user_cell.pattern); if (cell_equals(&md14_curr_cell, &md14_user_cell)) { if (md14_chosen_word->curr_letter == md14_chosen_word->num_letters - 1) { // done md14_correct_answer(); md14_next_state = MD14_STATE_GENQUES; } else {// correct but not done play_mp3(LANGUAGE, "GOOD"); play_mp3(LANGUAGE, "NLET"); md14_curr_mistakes = 0; md14_next_state = MD14_STATE_INPUT; } } else { md14_incorrect_answer(); md14_next_state = MD14_STATE_REPROMPT; } break; case MD14_STATE_REPROMPT: if (md14_curr_mistakes >= MAX_INCORRECT_GUESS) { play_mp3(LANGUAGE, "PRSS"); char* letter_name = get_eng_letter_name_by_cell(&md14_curr_cell); play_mp3(LANGUAGE, letter_name); if (md14_curr_mistakes >= MAX_INCORRECT_GUESS + 1) play_pattern(md14_curr_cell.pattern); } else { play_mp3(LANGUAGE, "SPEL"); speak_word(md14_chosen_word); if (md14_chosen_word->curr_glyph > -1) {// not at beginning of word play_mp3(MODE_FILESET, "SPLS"); speak_letters_so_far(md14_chosen_word); play_mp3(LANGUAGE, "NLET"); } } md14_next_state = MD14_STATE_INPUT; break; default: 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; } }
/** * @brief Step through the main stages in the code. * @return Void */ void md14_main() { switch(md14_next_state) { case MD14_STATE_INTRO: PRINTF("In intro state\n\r"); play_mp3(MODE_FILESET, "WELC"); lang_fileset = "ENG_"; mode_fileset = "MD14"; md14_next_state = MD14_STATE_LVLSEL; srand(timer_rand()); break; case MD14_STATE_LVLSEL: md14_last_dot = create_dialog("LVLS", (DOT_1 | DOT_2)); switch (md14_last_dot) { case NO_DOTS: break; case '1': play_mp3(LANGUAGE, "EASY"); strings_to_wordlist(easy, ARRAYLEN(easy), &md14_dict); print_words_in_list(&md14_dict); play_mp3(MODE_FILESET, "INST"); md14_next_state = MD14_STATE_GENQUES; break; case '2': play_mp3(LANGUAGE, "HARD"); strings_to_wordlist(medium, ARRAYLEN(medium), &md14_dict); print_words_in_list(&md14_dict); play_mp3(MODE_FILESET, "INST"); md14_next_state = MD14_STATE_GENQUES; break; // todo: add case 3; figure out too-long words default: play_mp3(LANGUAGE, "INVP"); PRINTF("Invalid entry."); break; } break; case MD14_STATE_GENQUES: PRINTF("In genques state\n\r"); md14_curr_mistakes = 0; get_next_word_in_wordlist(&md14_dict, &md14_chosen_word); sprintf(dbgstr, "[MD14] Next word: %s\n\r", md14_chosen_word->name); PRINTF(dbgstr); md14_next_state = MD14_STATE_PROMPT; break; case MD14_STATE_PROMPT: PRINTF("In prompt state\n\r"); play_mp3(LANGUAGE, "SPEL"); speak_word(md14_chosen_word); md14_next_state = MD14_STATE_INPUT; break; case MD14_STATE_INPUT: md14_cell = get_cell(); if (md14_cell == NO_DOTS) { break; } md14_cell_pattern = GET_CELL_PATTERN(md14_cell); md14_cell_control = GET_CELL_CONTROL(md14_cell); switch (md14_cell_control) { case WITH_ENTER: md14_user_cell.pattern = md14_cell_pattern; md14_next_state = MD14_STATE_CHECK; PRINTF("[MD14] Checking answer\n\r"); break; case WITH_LEFT: md14_next_state = MD14_STATE_REPROMPT; break; case WITH_RIGHT: stats(); md14_next_state = MD14_STATE_GENQUES; break; case WITH_CANCEL: break; } break; case MD14_STATE_CHECK: get_next_cell_in_word(md14_chosen_word, &md14_curr_cell); sprintf(dbgstr, "In check state. Current cell: %x, user cell: %x.\n\r", md14_curr_cell.pattern, md14_user_cell.pattern); PRINTF(dbgstr); if (cell_equals(&md14_curr_cell, &md14_user_cell)) { md14_curr_mistakes = 0; if (md14_chosen_word->curr_letter == md14_chosen_word->num_letters - 1) { // done correct_answer(); md14_next_state = MD14_STATE_GENQUES; } else {// correct but not done play_mp3(LANGUAGE, "GOOD"); play_mp3(LANGUAGE, "NLET"); md14_next_state = MD14_STATE_INPUT; } } else {// incorrect letter incorrect_answer(); // @todo mark invalid letters invalid md14_next_state = MD14_STATE_REPROMPT; } break; case MD14_STATE_REPROMPT: PRINTF("In reprompt state\n\r"); if (md14_curr_mistakes >= MAX_INCORRECT_GUESS) { play_mp3(LANGUAGE, "PRSS"); play_pattern(md14_curr_cell.pattern); } else { play_mp3(LANGUAGE, "SPEL"); speak_word(md14_chosen_word); if (md14_chosen_word->curr_glyph > -1) {// not at beginning of word play_mp3(MODE_FILESET, "SPLS"); speak_letters_so_far(md14_chosen_word); } } md14_next_state = MD14_STATE_INPUT; 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; } }