Spiel beendbar gemacht.
[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 + 1][MENU_BUFLEN];
52 char const *menu_index[levelcount + 1];
53 char const *fnames[levelcount + 1];
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 strcpy(menu_buf[i], "exit");
68 menu_index[i] = menu_buf[i];
69 size_t choice = badge_menu(menu_index, i + 1, first_visible, *selected);
70
71 if(choice == levelcount) {
72 return 1; // exit
73 }
74
75 *selected = choice;
76 strcpy(buf, fnames[*selected]);
77 return 0;
78 }
79
80 static uint8_t jumpnrun_pick_level(char *buf, size_t *first_visible, size_t *selected, uint8_t progress) {
81 FIL fd;
82
83 if(FR_OK != f_open(&fd, "levels.lst", FA_OPEN_EXISTING | FA_READ)) {
84 return JUMPNRUN_ERROR;
85 }
86
87 uint8_t err = jumpnrun_pick_level_from_fd(buf, first_visible, selected, progress, &fd);
88
89 f_close(&fd);
90
91 return err;
92 }
93
94 void jumpnrun_play(void) {
95 char buf[LEVELFILE_MAX + 1];
96 size_t first_visible = 0;
97 size_t selected = 0;
98 uint8_t progress = jumpnrun_load_progress();
99
100 while(0 == jumpnrun_pick_level(buf, &first_visible, &selected, progress)) {
101 if(JUMPNRUN_WON == jumpnrun_play_level(buf) && selected == progress) {
102 selected = ++progress;
103 jumpnrun_save_progress(progress);
104 }
105 }
106 }
This page took 0.048109 seconds and 5 git commands to generate.