2e7eebf603fef84bbbc4ddd45226cca217d75f71
[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 if(FR_OK == f_open(&fd, PROGRESS_FNAME, FA_OPEN_EXISTING | FA_READ)) {
19 UINT bytes;
20 f_read(&fd, &progress, sizeof(progress), &bytes);
21 f_close(&fd);
22 }
23
24 return progress;
25 }
26
27 static void jumpnrun_save_progress(uint8_t progress) {
28 FIL fd;
29
30 if(FR_OK == f_open(&fd, PROGRESS_FNAME, FA_CREATE_ALWAYS | FA_WRITE)) {
31 UINT bytes;
32 f_write(&fd, &progress, sizeof(progress), &bytes);
33 f_close(&fd);
34 }
35 }
36
37 static uint8_t jumpnrun_pick_level_from_fd(char *buf, size_t *first_visible, size_t *selected, uint8_t progress, FIL *fd) {
38 unsigned levelcount = 0;
39
40 {
41 char buf[MENU_BUFLEN];
42 while(f_gets(buf, MENU_BUFLEN, fd) && levelcount <= progress) {
43 ++levelcount;
44 }
45 }
46
47 if(FR_OK != f_lseek(fd, 0)) {
48 return JUMPNRUN_ERROR;
49 }
50
51 char menu_buf[levelcount][MENU_BUFLEN];
52 char const *menu_index[levelcount];
53 char const *fnames[levelcount];
54 unsigned i;
55
56 for(i = 0; i < levelcount && f_gets(menu_buf[i], MENU_BUFLEN, fd); ++i) {
57 menu_index[i] = menu_buf[i];
58 char *p;
59 for(p = menu_buf[i]; *p && *p != '|'; ++p)
60 ;
61 if(*p) {
62 *p++ = '\0';
63 }
64 fnames[i] = p;
65 }
66
67 *selected = badge_menu(menu_index, i, first_visible, *selected);
68
69 strcpy(buf, fnames[*selected]);
70 return 0;
71 }
72
73 static uint8_t jumpnrun_pick_level(char *buf, size_t *first_visible, size_t *selected, uint8_t progress) {
74 FIL fd;
75
76 if(FR_OK != f_open(&fd, "levels.lst", FA_OPEN_EXISTING | FA_READ)) {
77 return JUMPNRUN_ERROR;
78 }
79
80 uint8_t err = jumpnrun_pick_level_from_fd(buf, first_visible, selected, progress, &fd);
81
82 f_close(&fd);
83
84 return err;
85 }
86
87 void jumpnrun_play(void) {
88 char buf[LEVELFILE_MAX + 1];
89 size_t first_visible = 0;
90 size_t selected = 0;
91 uint8_t progress = jumpnrun_load_progress();
92
93 while(0 == jumpnrun_pick_level(buf, &first_visible, &selected, progress)) {
94 if(JUMPNRUN_WON == jumpnrun_play_level(buf) && selected == progress) {
95 selected = ++progress;
96 jumpnrun_save_progress(progress);
97 }
98 }
99 }
This page took 0.04814 seconds and 3 git commands to generate.