Browse Source

add settings and move with score to config in sram

Thomas B 1 month ago
parent
commit
60e6885189
8 changed files with 193 additions and 125 deletions
  1. 77
    0
      src/config.ba0.c
  2. 52
    0
      src/config.h
  3. 3
    2
      src/game.c
  4. 31
    22
      src/main.c
  5. 1
    11
      src/main.h
  6. 2
    1
      src/maps.c
  7. 25
    88
      src/score.c
  8. 2
    1
      src/score.h

+ 77
- 0
src/config.ba0.c View File

@@ -0,0 +1,77 @@
1
+/*
2
+ * config.ba0.c
3
+ * Duality
4
+ *
5
+ * Copyright (C) 2025 Thomas Buck <thomas@xythobuz.de>
6
+ *
7
+ * This program is free software: you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation, either version 3 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * See <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+#include <stddef.h>
21
+#undef NULL
22
+
23
+#include "banks.h"
24
+#include "score.h"
25
+#include "config.h"
26
+
27
+struct config_mem {
28
+    struct config config;
29
+    struct scores scores[SCORE_NUM * 2];
30
+
31
+    uint32_t crc; // needs to be last
32
+};
33
+
34
+static struct config_mem mem;
35
+
36
+BANKREF(config)
37
+
38
+static uint32_t calc_crc(void) {
39
+    const uint8_t *d = (const uint8_t *)mem;
40
+
41
+    uint32_t c = 0xFFFFFFFF;
42
+    for (size_t i = 0; i < offsetof(struct config_mem, crc); i++) {
43
+
44
+        // adapted from "Hacker's Delight"
45
+        c ^= d[i];
46
+        for (size_t j = 0; j < 8; j++) {
47
+            uint32_t mask = -(c & 1);
48
+            c = (c >> 1) ^ (0xEDB88320 & mask);
49
+        }
50
+    }
51
+
52
+    return ~c;
53
+}
54
+
55
+void conf_init(void) BANKED {
56
+    ENABLE_RAM;
57
+    SWITCH_RAM(0);
58
+
59
+    if (calc_crc() != mem.crc) {
60
+        mem.config.debug_flags = 0;
61
+        mem.config.sfx_vol = 0x0F;
62
+        mem.config.music_vol = 0x07;
63
+        score_reset();
64
+    }
65
+}
66
+
67
+void conf_write_crc(void) BANKED {
68
+    mem.crc = calc_crc();
69
+}
70
+
71
+struct scores *conf_scores(void) BANKED {
72
+    return mem.scores;
73
+}
74
+
75
+struct config *conf_get(void) BANKED {
76
+    return &mem.config;
77
+}

+ 52
- 0
src/config.h View File

@@ -0,0 +1,52 @@
1
+/*
2
+ * config.h
3
+ * Duality
4
+ *
5
+ * Copyright (C) 2025 Thomas Buck <thomas@xythobuz.de>
6
+ *
7
+ * This program is free software: you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation, either version 3 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * See <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+#ifndef __CONFIG_H__
21
+#define __CONFIG_H__
22
+
23
+#include <gbdk/platform.h>
24
+#include <gbdk/emu_debug.h>
25
+#include <stdint.h>
26
+
27
+#include "score.h"
28
+
29
+enum debug_flag {
30
+    DBG_NONE = 0,
31
+
32
+    DBG_MENU = (1 << 0),
33
+    DBG_MARKER = (1 << 1),
34
+    DBG_GOD_MODE = (1 << 2),
35
+    DBG_CLEAR_SCORE = (1 << 3),
36
+    DBG_ZERO_SCORE = (1 << 4),
37
+};
38
+
39
+struct config {
40
+    enum debug_flag debug_flags;
41
+    uint8_t sfx_vol;
42
+    uint8_t music_vol;
43
+};
44
+
45
+void conf_init(void) BANKED;
46
+void conf_write_crc(void) BANKED;
47
+struct scores *conf_scores(void) BANKED;
48
+struct config *conf_get(void) BANKED;
49
+
50
+BANKREF_EXTERN(config)
51
+
52
+#endif // __CONFIG_H__

+ 3
- 2
src/game.c View File

@@ -22,6 +22,7 @@
22 22
 #include <rand.h>
23 23
 #include <stdint.h>
24 24
 
25
+#include "config.h"
25 26
 #include "maps.h"
26 27
 #include "obj.h"
27 28
 #include "sprites.h"
@@ -349,7 +350,7 @@ int32_t game(void) NONBANKED {
349 350
 
350 351
         uint8_t hiwater = SPR_NUM_START;
351 352
 
352
-        if (debug_flags & DBG_MARKER) {
353
+        if (conf_get()->debug_flags & DBG_MARKER) {
353 354
             spr_draw(SPR_DEBUG, FLIP_NONE, 0, 0, 0, &hiwater);
354 355
             spr_draw(SPR_DEBUG_LARGE, FLIP_NONE, 0, 0, 0, &hiwater);
355 356
         }
@@ -363,7 +364,7 @@ int32_t game(void) NONBANKED {
363 364
 
364 365
         int16_t damage = obj_do(&spd_x, &spd_y, &score, &hiwater, 0);
365 366
         if (damage > 0) {
366
-            if (debug_flags & DBG_GOD_MODE) {
367
+            if (conf_get()->debug_flags & DBG_GOD_MODE) {
367 368
                 damage = 0;
368 369
             }
369 370
 

+ 31
- 22
src/main.c View File

@@ -24,6 +24,7 @@
24 24
 #include <rand.h>
25 25
 
26 26
 #include "banks.h"
27
+#include "config.h"
27 28
 #include "maps.h"
28 29
 #include "obj.h"
29 30
 #include "sprites.h"
@@ -37,12 +38,6 @@
37 38
 #include "sample.h"
38 39
 #include "main.h"
39 40
 
40
-#ifdef DEBUG
41
-enum debug_flag debug_flags = DBG_MENU | DBG_MARKER;
42
-#else
43
-enum debug_flag debug_flags = 0;
44
-#endif
45
-
46 41
 uint8_t debug_menu_index = 0;
47 42
 uint8_t debug_special_value = 0;
48 43
 
@@ -54,6 +49,7 @@ const struct debug_entry debug_entries[DEBUG_ENTRY_COUNT] = {
54 49
     { .name = "music",    .flag = DBG_NONE,        .max = 3 }, // 2
55 50
     { .name = "sfx-test", .flag = DBG_NONE,        .max = 3 }, // 3
56 51
     { .name = "cl score", .flag = DBG_CLEAR_SCORE, .max = 1 }, // 4
52
+    { .name = "0 scores", .flag = DBG_ZERO_SCORE,  .max = 1 }, // 5
57 53
 };
58 54
 
59 55
 static void highscore(uint8_t is_black) NONBANKED {
@@ -105,7 +101,7 @@ static void about_screen(void) NONBANKED {
105 101
 static void splash_win(void) NONBANKED {
106 102
     HIDE_WIN;
107 103
 
108
-    if (debug_flags & DBG_MENU) {
104
+    if (conf_get()->debug_flags & DBG_MENU) {
109 105
         win_debug();
110 106
         move_win(MINWNDPOSX, MINWNDPOSY);
111 107
     } else {
@@ -213,37 +209,45 @@ static void splash(void) NONBANKED {
213 209
     DISPLAY_ON;
214 210
     enable_interrupts();
215 211
 
216
-    if (!(debug_flags & DBG_MENU)) {
212
+    if (!(conf_get()->debug_flags & DBG_MENU)) {
217 213
         snd_menu_music();
218 214
     }
219 215
 
220 216
     while (1) {
221 217
         key_read();
222 218
 
223
-        if (key_pressed(J_LEFT) && (!(debug_flags & DBG_MENU))) {
219
+        if (key_pressed(J_LEFT) && (!(conf_get()->debug_flags & DBG_MENU))) {
224 220
             highscore(1);
225 221
             splash_win();
226
-        } else if (key_pressed(J_RIGHT) && (!(debug_flags & DBG_MENU))) {
222
+        } else if (key_pressed(J_RIGHT) && (!(conf_get()->debug_flags & DBG_MENU))) {
227 223
             highscore(0);
228 224
             splash_win();
229 225
         } else if (key_pressed(J_SELECT)) {
230 226
             about_screen();
231 227
             splash_win();
232 228
         } else if (key_pressed(J_START)) {
233
-            if ((key_debug() == 0) && (!(debug_flags & DBG_MENU))) {
234
-                debug_flags |= DBG_MENU;
229
+            if ((key_debug() == 0) && (!(conf_get()->debug_flags & DBG_MENU))) {
230
+                conf_get()->debug_flags |= DBG_MENU;
235 231
                 snd_music_off();
236 232
                 snd_note_off();
233
+                conf_write_crc();
237 234
                 splash_win();
238 235
             } else {
239 236
                 break;
240 237
             }
241 238
         } else {
242
-            if (debug_flags & DBG_MENU) {
239
+            if (conf_get()->debug_flags & DBG_MENU) {
243 240
                 // do it here so you quickly see the flag going to 1 and back to 0
244
-                if (debug_flags & DBG_CLEAR_SCORE) {
241
+                if (conf_get()->debug_flags & DBG_CLEAR_SCORE) {
245 242
                     score_reset();
246
-                    debug_flags &= ~DBG_CLEAR_SCORE;
243
+                    conf_get()->debug_flags &= ~DBG_CLEAR_SCORE;
244
+                    conf_write_crc();
245
+                    splash_win();
246
+                }
247
+                if (conf_get()->debug_flags & DBG_ZERO_SCORE) {
248
+                    score_zero();
249
+                    conf_get()->debug_flags &= ~DBG_ZERO_SCORE;
250
+                    conf_write_crc();
247 251
                     splash_win();
248 252
                 }
249 253
 
@@ -272,7 +276,8 @@ static void splash(void) NONBANKED {
272 276
                 } else if (key_pressed(J_LEFT)) {
273 277
                     START_ROM_BANK(BANK(main));
274 278
                         if (debug_entries[debug_menu_index].flag != DBG_NONE) {
275
-                            debug_flags ^= debug_entries[debug_menu_index].flag;
279
+                            conf_get()->debug_flags ^= debug_entries[debug_menu_index].flag;
280
+                            conf_write_crc();
276 281
                         } else {
277 282
                             if (debug_special_value > 0) {
278 283
                                 debug_special_value--;
@@ -286,7 +291,8 @@ static void splash(void) NONBANKED {
286 291
                 } else if (key_pressed(J_RIGHT)) {
287 292
                     START_ROM_BANK(BANK(main));
288 293
                         if (debug_entries[debug_menu_index].flag != DBG_NONE) {
289
-                            debug_flags ^= debug_entries[debug_menu_index].flag;
294
+                            conf_get()->debug_flags ^= debug_entries[debug_menu_index].flag;
295
+                            conf_write_crc();
290 296
                         } else {
291 297
                             if (debug_special_value < debug_entries[debug_menu_index].max) {
292 298
                                 debug_special_value++;
@@ -300,7 +306,8 @@ static void splash(void) NONBANKED {
300 306
                 } else if (key_pressed(J_A)) {
301 307
                     START_ROM_BANK(BANK(main));
302 308
                         if (debug_entries[debug_menu_index].flag != DBG_NONE) {
303
-                            debug_flags ^= debug_entries[debug_menu_index].flag;
309
+                            conf_get()->debug_flags ^= debug_entries[debug_menu_index].flag;
310
+                            conf_write_crc();
304 311
                         } else {
305 312
                             if (debug_special_value < debug_entries[debug_menu_index].max) {
306 313
                                 debug_special_value++;
@@ -312,8 +319,9 @@ static void splash(void) NONBANKED {
312 319
                     END_ROM_BANK();
313 320
                     splash_win();
314 321
                 } else if (key_pressed(J_B)) {
315
-                    debug_flags &= ~DBG_MENU;
322
+                    conf_get()->debug_flags &= ~DBG_MENU;
316 323
                     debug_special_value = 0;
324
+                    conf_write_crc();
317 325
                     splash_win();
318 326
                     snd_menu_music();
319 327
                 }
@@ -366,8 +374,8 @@ static void splash(void) NONBANKED {
366 374
 
367 375
         uint8_t hiwater = SPR_NUM_START;
368 376
 
369
-        if (!(debug_flags & DBG_MENU)) {
370
-            if (debug_flags & DBG_MARKER) {
377
+        if (!(conf_get()->debug_flags & DBG_MENU)) {
378
+            if (conf_get()->debug_flags & DBG_MARKER) {
371 379
                 spr_draw(SPR_DEBUG, FLIP_NONE, 0, -10, 0, &hiwater);
372 380
                 spr_draw(SPR_SHOT_LIGHT, FLIP_NONE, 0, -10, 0, &hiwater);
373 381
 
@@ -494,6 +502,7 @@ void main(void) NONBANKED {
494 502
         cpu_fast();
495 503
     }
496 504
 
505
+    conf_init();
497 506
     timer_init();
498 507
     spr_init();
499 508
     snd_init();
@@ -508,7 +517,7 @@ void main(void) NONBANKED {
508 517
     while (1) {
509 518
         int32_t score = game();
510 519
 
511
-        if ((!(debug_flags & DBG_GOD_MODE)) && (score != 0) && score_ranking(score)) {
520
+        if ((!(conf_get()->debug_flags & DBG_GOD_MODE)) && (score != 0) && score_ranking(score)) {
512 521
             uint16_t name = ask_name(score);
513 522
             struct scores s = { .name = name, .score = score };
514 523
             score_add(s);

+ 1
- 11
src/main.h View File

@@ -26,15 +26,6 @@
26 26
 #include <gbdk/platform.h>
27 27
 #include <stdint.h>
28 28
 
29
-enum debug_flag {
30
-    DBG_NONE = 0,
31
-
32
-    DBG_MENU = (1 << 0),
33
-    DBG_MARKER = (1 << 1),
34
-    DBG_GOD_MODE = (1 << 2),
35
-    DBG_CLEAR_SCORE = (1 << 3),
36
-};
37
-
38 29
 #define DEBUG_ENTRY_NAME_LEN 8
39 30
 
40 31
 struct debug_entry {
@@ -45,11 +36,10 @@ struct debug_entry {
45 36
 
46 37
 BANKREF_EXTERN(main)
47 38
 
48
-extern enum debug_flag debug_flags;
49 39
 extern uint8_t debug_menu_index;
50 40
 extern uint8_t debug_special_value;
51 41
 
52
-#define DEBUG_ENTRY_COUNT 5
42
+#define DEBUG_ENTRY_COUNT 6
53 43
 extern const struct debug_entry debug_entries[DEBUG_ENTRY_COUNT];
54 44
 
55 45
 #endif // __MAIN_H__

+ 2
- 1
src/maps.c View File

@@ -21,6 +21,7 @@
21 21
 #include <string.h>
22 22
 
23 23
 #include "banks.h"
24
+#include "config.h"
24 25
 #include "score.h"
25 26
 #include "title_map.h"
26 27
 #include "bg_map.h"
@@ -290,7 +291,7 @@ void win_debug(void) NONBANKED {
290 291
                     name_buff[n_len + 1] = '0';
291 292
                 }
292 293
             } else {
293
-                name_buff[n_len + 1] = (debug_flags & debug_entries[i].flag) ? '1' : '0';
294
+                name_buff[n_len + 1] = (conf_get()->debug_flags & debug_entries[i].flag) ? '1' : '0';
294 295
             }
295 296
             name_buff[n_len + 2] = '\0';
296 297
             n_len += 2;

src/score.ba0.c → src/score.c View File

@@ -20,11 +20,9 @@
20 20
 #include <string.h>
21 21
 
22 22
 #include "banks.h"
23
+#include "config.h"
23 24
 #include "score.h"
24 25
 
25
-static struct scores scores[SCORE_NUM * 2];
26
-static uint32_t scores_crc;
27
-
28 26
 BANKREF(score)
29 27
 
30 28
 #define NAME(a, b, c) (((uint16_t)(a - 'a') << 10) | ((uint16_t)(b - 'a') << 5) | (uint16_t)(c - 'a'))
@@ -72,42 +70,16 @@ uint16_t convert_name(char a, char b, char c) BANKED {
72 70
     return (a << 10) | (b << 5) | c;
73 71
 }
74 72
 
75
-static uint32_t calc_crc(void) {
76
-    const uint8_t *d = (const uint8_t *)scores;
77
-
78
-    uint32_t c = 0xFFFFFFFF;
79
-    for (size_t i = 0; i < sizeof(scores); i++) {
80
-        // adapted from "Hacker's Delight"
81
-        c ^= d[i];
82
-        for (size_t j = 0; j < 8; j++) {
83
-            uint32_t mask = -(c & 1);
84
-            c = (c >> 1) ^ (0xEDB88320 & mask);
85
-        }
86
-    }
87
-
88
-    return ~c;
89
-}
90
-
91
-static uint8_t check_crc(void) {
92
-    return (calc_crc() == scores_crc) ? 1 : 0;
93
-}
94
-
95
-static void score_init(void) NONBANKED {
96
-    START_ROM_BANK(BANK(score));
97
-        memcpy(scores, initial_scores, sizeof(scores));
98
-    END_ROM_BANK();
99
-}
100
-
101 73
 static uint8_t score_pos(int32_t score) {
102 74
     if (score > 0) {
103 75
         for (uint8_t i = 0; i < SCORE_NUM; i++) {
104
-            if (score > scores[i].score) {
76
+            if (score > conf_scores()[i].score) {
105 77
                 return i;
106 78
             }
107 79
         }
108 80
     } else if (score < 0) {
109 81
         for (uint8_t i = (SCORE_NUM * 2) - 1; i >= 5; i--) {
110
-            if (score < scores[i].score) {
82
+            if (score < conf_scores()[i].score) {
111 83
                 return i;
112 84
             }
113 85
         }
@@ -117,87 +89,52 @@ static uint8_t score_pos(int32_t score) {
117 89
 }
118 90
 
119 91
 uint8_t score_ranking(int32_t score) BANKED {
120
-    ENABLE_RAM;
121
-    SWITCH_RAM(0);
122
-
123
-    // initialize score table when data is invalid
124
-    if (!check_crc()) {
125
-        score_init();
126
-        scores_crc = calc_crc();
127
-    }
128
-
129
-    uint8_t r = (score_pos(score) < (SCORE_NUM * 2)) ? 1 : 0;
130
-
131
-    DISABLE_RAM;
132
-    return r;
92
+    return (score_pos(score) < (SCORE_NUM * 2)) ? 1 : 0;
133 93
 }
134 94
 
135 95
 void score_add(struct scores score) BANKED {
136
-    ENABLE_RAM;
137
-    SWITCH_RAM(0);
138
-
139
-    // initialize score table when data is invalid
140
-    if (!check_crc()) {
141
-        score_init();
142
-        scores_crc = calc_crc();
143
-    }
144
-
145 96
     uint8_t new = score_pos(score.score);
146 97
     if (new < (SCORE_NUM * 2)) {
147 98
         // move old scores out of the way
148 99
         if ((score.score > 0) && (new < (SCORE_NUM - 1))) {
149
-            memmove(scores + new + 1, scores + new, sizeof(struct scores) * (SCORE_NUM - 1 - new));
100
+            memmove(conf_scores() + new + 1, conf_scores() + new, sizeof(struct scores) * (SCORE_NUM - 1 - new));
150 101
         } else if ((score.score < 0) && (new > SCORE_NUM)) {
151
-            memmove(scores + new - 1, scores + new, sizeof(struct scores) * (new - SCORE_NUM));
102
+            memmove(conf_scores() + new - 1, conf_scores() + new, sizeof(struct scores) * (new - SCORE_NUM));
152 103
         }
153 104
 
154
-        scores[new] = score;
155
-        scores_crc = calc_crc();
156
-    }
105
+        conf_scores()[new] = score;
106
+        conf_write_crc();
157 107
 
158
-    DISABLE_RAM;
108
+#ifdef DEBUG
109
+        EMU_printf("%s: add %li at %hu for %x\n",
110
+                   __func__, (int32_t)score.score,
111
+                   (uint8_t)new, (uint16_t)score.name);
112
+#endif // DEBUG
113
+    }
159 114
 }
160 115
 
161 116
 void score_highest(uint8_t off, struct scores *t) BANKED {
162
-    ENABLE_RAM;
163
-    SWITCH_RAM(0);
164
-
165
-    // initialize score table when data is invalid
166
-    if (!check_crc()) {
167
-        score_init();
168
-        scores_crc = calc_crc();
169
-    }
170
-
171 117
     if (off >= SCORE_NUM) {
172 118
         off = SCORE_NUM - 1;
173 119
     }
174
-    *t = scores[off];
175
-
176
-    DISABLE_RAM;
120
+    *t = conf_scores()[off];
177 121
 }
178 122
 
179 123
 void score_lowest(uint8_t off, struct scores *t) BANKED {
180
-    ENABLE_RAM;
181
-    SWITCH_RAM(0);
182
-
183
-    // initialize score table when data is invalid
184
-    if (!check_crc()) {
185
-        score_init();
186
-        scores_crc = calc_crc();
187
-    }
188
-
189 124
     if (off >= SCORE_NUM) {
190 125
         off = SCORE_NUM - 1;
191 126
     }
192
-    *t = scores[(SCORE_NUM * 2) - 1 - off];
127
+    *t = conf_scores()[(SCORE_NUM * 2) - 1 - off];
128
+}
193 129
 
194
-    DISABLE_RAM;
130
+void score_reset(void) NONBANKED {
131
+    START_ROM_BANK(BANK(score));
132
+        memcpy(conf_scores(), initial_scores, sizeof(struct scores) * SCORE_NUM * 2);
133
+    END_ROM_BANK();
134
+    conf_write_crc();
195 135
 }
196 136
 
197
-void score_reset(void) BANKED {
198
-    ENABLE_RAM;
199
-    SWITCH_RAM(0);
200
-    score_init();
201
-    scores_crc = calc_crc();
202
-    DISABLE_RAM;
137
+void score_zero(void) NONBANKED {
138
+    memset(conf_scores(), 0, sizeof(struct scores) * SCORE_NUM * 2);
139
+    conf_write_crc();
203 140
 }

+ 2
- 1
src/score.h View File

@@ -35,7 +35,8 @@ uint8_t score_ranking(int32_t score) BANKED;
35 35
 void score_add(struct scores score) BANKED;
36 36
 void score_highest(uint8_t off, struct scores *t) BANKED;
37 37
 void score_lowest(uint8_t off, struct scores *t) BANKED;
38
-void score_reset(void) BANKED;
38
+void score_reset(void);
39
+void score_zero(void);
39 40
 
40 41
 BANKREF_EXTERN(score)
41 42
 

Loading…
Cancel
Save