X-Git-Url: http://git.rohieb.name/hackover2013-badge-firmware.git/blobdiff_plain/cde2e04c6ed7210ec4ff242adc1b640666fcabf5..e89a0502f47865e816e0ba85b86b1377bc352915:/badge/jumpnrun/starter.c diff --git a/badge/jumpnrun/starter.c b/badge/jumpnrun/starter.c index 146e85c..bb69f2e 100644 --- a/badge/jumpnrun/starter.c +++ b/badge/jumpnrun/starter.c @@ -1,38 +1,58 @@ #include "jumpnrun.h" #include "../ui/menu.h" +#include "../ui/browser.h" #include +#define CREDITS_FNAME "credits.txt" +#define POSITION_FNAME "selected.dat" +#define PROGRESS_FNAME "progress.dat" + enum { LEVELFILE_MAX = 12, LEVELDESCRIPTION_MAX = 14, MENU_BUFLEN = LEVELDESCRIPTION_MAX + 1 + LEVELFILE_MAX + 1 }; -#define PROGRESS_FNAME "progress.dat" +enum { + CHOICE_LEVEL, + CHOICE_CREDITS, + CHOICE_EXIT, + CHOICE_ERROR +}; -static uint8_t jumpnrun_load_progress(void) { - uint8_t progress = 0; +static uint8_t read_byte_from_file(char const *fname) { FIL fd; + uint8_t x = 0; - if(FR_OK == f_open(&fd, PROGRESS_FNAME, FA_OPEN_EXISTING | FA_READ)) { + if(FR_OK == f_chdir(JUMPNRUN_PATH) && + FR_OK == f_open(&fd, fname, FA_OPEN_EXISTING | FA_READ)) { UINT bytes; - f_read(&fd, &progress, sizeof(progress), &bytes); + f_read(&fd, &x, sizeof(x), &bytes); + f_close(&fd); } - return progress; + return x; } -static void jumpnrun_save_progress(uint8_t progress) { +static void save_byte_to_file(char const *fname, uint8_t x) { FIL fd; - if(FR_OK == f_open(&fd, PROGRESS_FNAME, FA_CREATE_NEW | FA_WRITE)) { + if(FR_OK == f_chdir(JUMPNRUN_PATH) && + FR_OK == f_open(&fd, fname, FA_CREATE_ALWAYS | FA_WRITE)) { UINT bytes; - f_write(&fd, &progress, sizeof(progress), &bytes); + f_write(&fd, &x, sizeof(x), &bytes); + f_close(&fd); } } -static uint8_t jumpnrun_pick_level_from_fd(char *buf, size_t *first_visible, size_t *selected, uint8_t progress, FIL *fd) { +static uint8_t jumpnrun_load_selected(void ) { return read_byte_from_file(POSITION_FNAME ); } +static void jumpnrun_save_selected(uint8_t selected) { save_byte_to_file (POSITION_FNAME, selected); } + +static uint8_t jumpnrun_load_progress(void ) { return read_byte_from_file(PROGRESS_FNAME ); } +static void jumpnrun_save_progress(uint8_t progress) { save_byte_to_file (PROGRESS_FNAME, progress); } + +static uint8_t jumpnrun_pick_level_from_fd(char *buf, uint8_t *first_visible, uint8_t *selected, uint8_t progress, FIL *fd) { unsigned levelcount = 0; { @@ -46,9 +66,11 @@ static uint8_t jumpnrun_pick_level_from_fd(char *buf, size_t *first_visible, siz return JUMPNRUN_ERROR; } - char menu_buf[levelcount][MENU_BUFLEN]; - char const *menu_index[levelcount]; - char const *fnames[levelcount]; + uint8_t menulen = levelcount + (levelcount <= progress) + 1; + + char menu_buf [menulen][MENU_BUFLEN]; + char const *menu_index[menulen]; + char const *fnames [menulen]; unsigned i; for(i = 0; i < levelcount && f_gets(menu_buf[i], MENU_BUFLEN, fd); ++i) { @@ -62,16 +84,43 @@ static uint8_t jumpnrun_pick_level_from_fd(char *buf, size_t *first_visible, siz fnames[i] = p; } - *selected = badge_menu(menu_index, i, first_visible, *selected); + uint8_t creditspos = -1; + uint8_t exitpos = i; + + if(levelcount <= progress) { + creditspos = i; + strcpy(menu_buf[creditspos], "Credits"); + menu_index[creditspos] = menu_buf[creditspos]; + + ++exitpos; + } - strcpy(buf, fnames[*selected]); - return 0; + strcpy(menu_buf[exitpos], "Zurück"); + menu_index[exitpos] = menu_buf[exitpos]; + + uint8_t choice = badge_menu(menu_index, exitpos + 1, first_visible, *selected); + + if(choice == exitpos) { + return CHOICE_EXIT; + } + + *selected = choice; + + if(choice == creditspos) { + return CHOICE_CREDITS; + } + + strncpy(buf, fnames[*selected], LEVELFILE_MAX); + buf[LEVELFILE_MAX] = '\0'; + + return CHOICE_LEVEL; } -static uint8_t jumpnrun_pick_level(char *buf, size_t *first_visible, size_t *selected, uint8_t progress) { +static uint8_t jumpnrun_pick_level(char *buf, uint8_t *first_visible, uint8_t *selected, uint8_t progress) { FIL fd; - if(FR_OK != f_open(&fd, "levels.lst", FA_OPEN_EXISTING | FA_READ)) { + if(FR_OK != f_chdir(JUMPNRUN_PATH) || + FR_OK != f_open(&fd, "levels.lst", FA_OPEN_EXISTING | FA_READ)) { return JUMPNRUN_ERROR; } @@ -83,15 +132,31 @@ static uint8_t jumpnrun_pick_level(char *buf, size_t *first_visible, size_t *sel } void jumpnrun_play(void) { - char buf[LEVELFILE_MAX + 1]; - size_t first_visible = 0; - size_t selected = 0; + char buf[LEVELFILE_MAX + 1]; + uint8_t selected = jumpnrun_load_selected(); uint8_t progress = jumpnrun_load_progress(); + uint8_t first_visible = selected; + uint8_t choice; + uint8_t oldselected = selected; + + do { + if(oldselected != selected) { + jumpnrun_save_selected((uint8_t) selected); + oldselected = selected; + } - while(0 == jumpnrun_pick_level(buf, &first_visible, &selected, progress)) { - if(JUMPNRUN_WON == jumpnrun_play_level(buf) && selected == progress) { - ++progress; - jumpnrun_save_progress(progress); + choice = jumpnrun_pick_level(buf, &first_visible, &selected, progress); + + switch(choice) { + case CHOICE_LEVEL: + if(JUMPNRUN_WON == jumpnrun_play_level(buf) && selected == progress) { + selected = ++progress; + jumpnrun_save_progress(progress); + } + break; + case CHOICE_CREDITS: + badge_browse_textfile(CREDITS_FNAME); + break; } - } + } while(choice != CHOICE_EXIT); }