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