Fahrplandaten.
[hackover2013-badge-firmware.git] / badge / jumpnrun / starter.c
1 #include "jumpnrun.h"
2 #include "../ui/menu.h"
3
4 #include <drivers/fatfs/ff.h>
5
6 enum {
7 LEVELFILE_MAX = 12,
8 LEVELDESCRIPTION_MAX = 14,
9 MENU_BUFLEN = LEVELDESCRIPTION_MAX + 1 + LEVELFILE_MAX + 1
10 };
11
12 #define PROGRESS_FNAME "progress.dat"
13
14 static uint8_t jumpnrun_load_progress(void) {
15 uint8_t progress = 0;
16 FIL fd;
17
18
19 if(FR_OK == f_chdir(JUMPNRUN_PATH) &&
20 FR_OK == f_open(&fd, PROGRESS_FNAME, FA_OPEN_EXISTING | FA_READ)) {
21 UINT bytes;
22 f_read(&fd, &progress, sizeof(progress), &bytes);
23 f_close(&fd);
24 }
25
26 return progress;
27 }
28
29 static void jumpnrun_save_progress(uint8_t progress) {
30 FIL fd;
31
32 if(FR_OK == f_chdir(JUMPNRUN_PATH) &&
33 FR_OK == f_open(&fd, PROGRESS_FNAME, FA_CREATE_ALWAYS | FA_WRITE)) {
34 UINT bytes;
35 f_write(&fd, &progress, sizeof(progress), &bytes);
36 f_close(&fd);
37 }
38 }
39
40 static uint8_t jumpnrun_pick_level_from_fd(char *buf, size_t *first_visible, size_t *selected, uint8_t progress, FIL *fd) {
41 unsigned levelcount = 0;
42
43 {
44 char buf[MENU_BUFLEN];
45 while(f_gets(buf, MENU_BUFLEN, fd) && levelcount <= progress) {
46 ++levelcount;
47 }
48 }
49
50 if(FR_OK != f_lseek(fd, 0)) {
51 return JUMPNRUN_ERROR;
52 }
53
54 char menu_buf[levelcount + 1][MENU_BUFLEN];
55 char const *menu_index[levelcount + 1];
56 char const *fnames[levelcount + 1];
57 unsigned i;
58
59 for(i = 0; i < levelcount && f_gets(menu_buf[i], MENU_BUFLEN, fd); ++i) {
60 menu_index[i] = menu_buf[i];
61 char *p;
62 for(p = menu_buf[i]; *p && *p != '|'; ++p)
63 ;
64 if(*p) {
65 *p++ = '\0';
66 }
67 fnames[i] = p;
68 }
69
70 strcpy(menu_buf[i], "exit");
71 menu_index[i] = menu_buf[i];
72 size_t choice = badge_menu(menu_index, i + 1, first_visible, *selected);
73
74 if(choice == levelcount) {
75 return 1; // exit
76 }
77
78 *selected = choice;
79 strncpy(buf, fnames[*selected], LEVELFILE_MAX);
80 buf[LEVELFILE_MAX] = '\0';
81 return 0;
82 }
83
84 static uint8_t jumpnrun_pick_level(char *buf, size_t *first_visible, size_t *selected, uint8_t progress) {
85 FIL fd;
86
87 if(FR_OK != f_chdir(JUMPNRUN_PATH) ||
88 FR_OK != f_open(&fd, "levels.lst", FA_OPEN_EXISTING | FA_READ)) {
89 return JUMPNRUN_ERROR;
90 }
91
92 uint8_t err = jumpnrun_pick_level_from_fd(buf, first_visible, selected, progress, &fd);
93
94 f_close(&fd);
95
96 return err;
97 }
98
99 void jumpnrun_play(void) {
100 char buf[LEVELFILE_MAX + 1];
101 size_t first_visible = 0;
102 size_t selected = 0;
103 uint8_t progress = jumpnrun_load_progress();
104
105 while(0 == jumpnrun_pick_level(buf, &first_visible, &selected, progress)) {
106 if(JUMPNRUN_WON == jumpnrun_play_level(buf) && selected == progress) {
107 selected = ++progress;
108 jumpnrun_save_progress(progress);
109 }
110 }
111 }
This page took 0.046406 seconds and 5 git commands to generate.