Browse Source

start work on mirroring background on scroll (still disabled)

Thomas B 1 month ago
parent
commit
9e6b2ee09a
9 changed files with 188 additions and 29 deletions
  1. 4
    2
      src/config.h
  2. 7
    11
      src/game.c
  3. 7
    8
      src/main.c
  4. 1
    1
      src/main.h
  5. 130
    3
      src/maps.c
  6. 4
    0
      src/maps.h
  7. 1
    2
      src/sound.c
  8. 29
    0
      src/util.h
  9. 5
    2
      src/window.c

+ 4
- 2
src/config.h View File

@@ -32,8 +32,10 @@ enum debug_flag {
32 32
     DBG_MENU = (1 << 0),
33 33
     DBG_MARKER = (1 << 1),
34 34
     DBG_GOD_MODE = (1 << 2),
35
-    DBG_CLEAR_SCORE = (1 << 3),
36
-    DBG_ZERO_SCORE = (1 << 4),
35
+    DBG_NO_OBJ = (1 << 3),
36
+
37
+    DBG_CLEAR_SCORE = (1 << 6),
38
+    DBG_ZERO_SCORE = (1 << 7),
37 39
 };
38 40
 
39 41
 struct config {

+ 7
- 11
src/game.c View File

@@ -45,9 +45,6 @@
45 45
 #define SPEED_MAX_ACC_DIAG 16
46 46
 #define SPEED_MAX_IDLE 16
47 47
 
48
-#define POS_SCALE_BG 6
49
-#define POS_MASK_BG 0x3FFF
50
-
51 48
 #define POWER_MAX 0x1FF
52 49
 #define POWER_SHIFT 1
53 50
 
@@ -151,8 +148,6 @@ int32_t game(void) NONBANKED {
151 148
     SHOW_SPRITES;
152 149
     SPRITES_8x8;
153 150
 
154
-    int16_t pos_x = 0;
155
-    int16_t pos_y = 0;
156 151
     int16_t spd_x = 0;
157 152
     int16_t spd_y = 0;
158 153
     enum SPRITE_ROT rot = 0;
@@ -162,7 +157,10 @@ int32_t game(void) NONBANKED {
162 157
     int32_t score = 0;
163 158
 
164 159
     obj_init();
165
-    obj_spawn();
160
+
161
+    if (!(conf_get()->debug_flags & DBG_NO_OBJ)) {
162
+        obj_spawn();
163
+    }
166 164
 
167 165
     win_init(0);
168 166
     uint8_t x_off = win_game_draw(score);
@@ -338,12 +336,9 @@ int32_t game(void) NONBANKED {
338 336
             snd_music(SND_GAME);
339 337
         }
340 338
 
341
-        pos_x = (pos_x + spd_x) & POS_MASK_BG;
342
-        pos_y = (pos_y + spd_y) & POS_MASK_BG;
343
-        move_bkg(pos_x >> POS_SCALE_BG, pos_y >> POS_SCALE_BG);
339
+        map_move(spd_x, spd_y);
344 340
 
345 341
         uint8_t hiwater = SPR_NUM_START;
346
-
347 342
         status(health >> HEALTH_SHIFT, power >> POWER_SHIFT, &hiwater);
348 343
 
349 344
         if (conf_get()->debug_flags & DBG_MARKER) {
@@ -353,7 +348,8 @@ int32_t game(void) NONBANKED {
353 348
 
354 349
         spr_ship(rot, acc & (ACC_X | ACC_Y), &hiwater);
355 350
 
356
-        int16_t damage = obj_do(&spd_x, &spd_y, &score, &hiwater, 0);
351
+        int16_t damage = obj_do(&spd_x, &spd_y, &score, &hiwater,
352
+                                (conf_get()->debug_flags & DBG_NO_OBJ) ? 1 : 0);
357 353
         if (damage > 0) {
358 354
             if (conf_get()->debug_flags & DBG_GOD_MODE) {
359 355
                 damage = 0;

+ 7
- 8
src/main.c View File

@@ -53,10 +53,11 @@ const struct conf_entry conf_entries[CONF_ENTRY_COUNT] = {
53 53
 const struct debug_entry debug_entries[DEBUG_ENTRY_COUNT] = {
54 54
     { .name = "marker",   .flag = DBG_MARKER,      .max = 1 }, // 0
55 55
     { .name = "invuln",   .flag = DBG_GOD_MODE,    .max = 1 }, // 1
56
-    { .name = "music",    .flag = DBG_NONE,        .max = SND_COUNT }, // 2
57
-    { .name = "sfx-test", .flag = DBG_NONE,        .max = SFX_COUNT }, // 3
58
-    { .name = "cl score", .flag = DBG_CLEAR_SCORE, .max = 1 }, // 4
59
-    { .name = "0 scores", .flag = DBG_ZERO_SCORE,  .max = 1 }, // 5
56
+    { .name = "no-spawn", .flag = DBG_NO_OBJ,      .max = 1 }, // 2
57
+    { .name = "music",    .flag = DBG_NONE,        .max = SND_COUNT }, // 3
58
+    { .name = "sfx-test", .flag = DBG_NONE,        .max = SFX_COUNT }, // 4
59
+    { .name = "cl score", .flag = DBG_CLEAR_SCORE, .max = 1 }, // 5
60
+    { .name = "0 scores", .flag = DBG_ZERO_SCORE,  .max = 1 }, // 6
60 61
 };
61 62
 
62 63
 static void highscore(uint8_t is_black) NONBANKED {
@@ -272,7 +273,6 @@ static void splash(void) NONBANKED {
272 273
     disable_interrupts();
273 274
     DISPLAY_OFF;
274 275
     map_title();
275
-    move_bkg(0, 0);
276 276
     SHOW_BKG;
277 277
     spr_init_pal();
278 278
     SHOW_SPRITES;
@@ -405,13 +405,13 @@ static void splash(void) NONBANKED {
405 405
                     snd_music(SND_MENU);
406 406
                 }
407 407
 
408
-                if (switch_special && (debug_menu_index == 2)) {
408
+                if (switch_special && (debug_menu_index == 3)) {
409 409
                     snd_music_off();
410 410
                     if (debug_special_value > 0) {
411 411
                         snd_music(debug_special_value - 1);
412 412
                     }
413 413
                     snd_note_off();
414
-                } else if ((switch_special || (!sample_running())) && (debug_menu_index == 3)) {
414
+                } else if ((switch_special || (!sample_running())) && (debug_menu_index == 4)) {
415 415
                     if (debug_special_value > 0) {
416 416
                         sample_play(debug_special_value - 1);
417 417
                     }
@@ -453,7 +453,6 @@ static uint16_t ask_name(int32_t score) NONBANKED {
453 453
     disable_interrupts();
454 454
     DISPLAY_OFF;
455 455
     map_title();
456
-    move_bkg(0, 0);
457 456
     SHOW_BKG;
458 457
     spr_init_pal();
459 458
     SHOW_SPRITES;

+ 1
- 1
src/main.h View File

@@ -48,7 +48,7 @@ extern const struct conf_entry conf_entries[CONF_ENTRY_COUNT];
48 48
 extern uint8_t debug_menu_index;
49 49
 extern uint8_t debug_special_value;
50 50
 
51
-#define DEBUG_ENTRY_COUNT 6
51
+#define DEBUG_ENTRY_COUNT 7
52 52
 extern const struct debug_entry debug_entries[DEBUG_ENTRY_COUNT];
53 53
 
54 54
 #endif // __MAIN_H__

+ 130
- 3
src/maps.c View File

@@ -20,31 +20,75 @@
20 20
 #include "banks.h"
21 21
 #include "title_map.h"
22 22
 #include "bg_map.h"
23
+#include "util.h"
23 24
 #include "maps.h"
24 25
 
26
+#define POS_SCALE_BG 6
27
+
28
+// define this to disable mirrored map scaling support
29
+#define WRAP_BG // TODO
30
+
31
+#define bg_map_mapWidth (bg_map_WIDTH / bg_map_TILE_W)
32
+#define bg_map_mapHeight (bg_map_HEIGHT / bg_map_TILE_H)
33
+
34
+#define camera_max_x ((bg_map_mapWidth - DEVICE_SCREEN_WIDTH) * 8)
35
+#define camera_max_y ((bg_map_mapHeight - DEVICE_SCREEN_HEIGHT) * 8)
36
+
37
+#define set_bkg_sub_attr(x, y, w, h, attr, map_w) \
38
+    if (attr)                                     \
39
+        set_bkg_submap_attributes(x, y, w, h, attr, map_w)
40
+
41
+#define set_bkg_sub(x, y, w, h, map, attr, map_w) \
42
+    set_bkg_submap(x, y, w, h, map, map_w);       \
43
+    set_bkg_sub_attr(x, y, w, h, attr, map_w)
44
+
45
+// current unscaled ship position
46
+static uint16_t abs_x, abs_y;
47
+
48
+// current and old positions of the camera in pixels
49
+static uint16_t camera_x, camera_y, old_camera_x, old_camera_y;
50
+
51
+// current and old position of the map in tiles
52
+static uint8_t map_pos_x, map_pos_y, old_map_pos_x, old_map_pos_y;
53
+
25 54
 void map_title(void) NONBANKED {
26 55
     START_ROM_BANK(BANK(title_map));
56
+
27 57
         set_bkg_palette(OAMF_CGB_PAL0, title_map_PALETTE_COUNT, title_map_palettes);
28 58
         set_bkg_data(0, title_map_TILE_COUNT, title_map_tiles);
59
+
29 60
         if (title_map_MAP_ATTRIBUTES != NULL) {
30 61
             set_bkg_attributes(0, 0,
31
-                               title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
62
+                               title_map_WIDTH / title_map_TILE_W,
63
+                               title_map_HEIGHT / title_map_TILE_H,
32 64
                                title_map_MAP_ATTRIBUTES);
33 65
         } else {
34 66
             VBK_REG = VBK_ATTRIBUTES;
35 67
             fill_bkg_rect(0, 0,
36
-                          title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
68
+                          title_map_WIDTH / title_map_TILE_W,
69
+                          title_map_HEIGHT / title_map_TILE_H,
37 70
                           0x00);
38 71
             VBK_REG = VBK_TILES;
39 72
         }
40
-        set_bkg_tiles(0, 0, title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H, title_map_map);
73
+
74
+        set_bkg_tiles(0, 0,
75
+                      title_map_WIDTH / title_map_TILE_W,
76
+                      title_map_HEIGHT / title_map_TILE_H,
77
+                      title_map_map);
78
+
41 79
     END_ROM_BANK();
80
+
81
+    move_bkg(0, 0);
42 82
 }
43 83
 
44 84
 void map_game(void) NONBANKED {
45 85
     START_ROM_BANK(BANK(bg_map));
86
+
46 87
         set_bkg_palette(OAMF_CGB_PAL0, bg_map_PALETTE_COUNT, bg_map_palettes);
47 88
         set_bkg_data(0, bg_map_TILE_COUNT, bg_map_tiles);
89
+
90
+#ifdef WRAP_BG
91
+
48 92
         if (bg_map_MAP_ATTRIBUTES != NULL) {
49 93
             set_bkg_attributes(0, 0,
50 94
                                bg_map_WIDTH / bg_map_TILE_W, bg_map_HEIGHT / bg_map_TILE_H,
@@ -57,5 +101,88 @@ void map_game(void) NONBANKED {
57 101
             VBK_REG = VBK_TILES;
58 102
         }
59 103
         set_bkg_tiles(0, 0, bg_map_WIDTH / bg_map_TILE_W, bg_map_HEIGHT / bg_map_TILE_H, bg_map_map);
104
+
105
+#else // WRAP_BG
106
+
107
+        abs_x = 0;
108
+        abs_y = 0;
109
+
110
+        // Initial camera position in pixels set here.
111
+        camera_x = 0;
112
+        camera_y = 0;
113
+
114
+        // Enforce map limits on initial camera position
115
+        if (camera_x > camera_max_x) camera_x = camera_max_x;
116
+        if (camera_y > camera_max_y) camera_y = camera_max_y;
117
+        old_camera_x = camera_x; old_camera_y = camera_y;
118
+
119
+        map_pos_x = camera_x >> 3;
120
+        map_pos_y = camera_y >> 3;
121
+        old_map_pos_x = old_map_pos_y = 255;
122
+
123
+        move_bkg(camera_x, camera_y);
124
+
125
+        // Draw the initial map view for the whole screen
126
+        set_bkg_sub(map_pos_x, map_pos_y,
127
+                    MIN(DEVICE_SCREEN_WIDTH + 1u, bg_map_mapWidth - map_pos_x),
128
+                    MIN(DEVICE_SCREEN_HEIGHT + 1u, bg_map_mapHeight - map_pos_y),
129
+                    bg_map_map, bg_map_MAP_ATTRIBUTES, bg_map_mapWidth);
130
+
131
+#endif // WRAP_BG
132
+
60 133
     END_ROM_BANK();
61 134
 }
135
+
136
+void map_move(int16_t delta_x, int16_t delta_y) NONBANKED {
137
+    abs_x += delta_x;
138
+    abs_y += delta_y;
139
+
140
+    camera_x = abs_x >> POS_SCALE_BG;
141
+    camera_y = abs_y >> POS_SCALE_BG;
142
+
143
+    // update hardware scroll position
144
+    move_bkg(camera_x, camera_y);
145
+
146
+#ifndef WRAP_BG
147
+
148
+    map_pos_y = (uint8_t)(camera_y >> 3u);
149
+    map_pos_x = (uint8_t)(camera_x >> 3u);
150
+
151
+    START_ROM_BANK(BANK(bg_map));
152
+
153
+        // up or down
154
+        if (map_pos_y != old_map_pos_y) {
155
+            if (camera_y < old_camera_y) {
156
+                set_bkg_sub(map_pos_x, map_pos_y,
157
+                            MIN(DEVICE_SCREEN_WIDTH + 1, bg_map_mapWidth-map_pos_x), 1,
158
+                            bg_map_map, bg_map_MAP_ATTRIBUTES, bg_map_mapWidth);
159
+            } else if ((bg_map_mapHeight - DEVICE_SCREEN_HEIGHT) > map_pos_y) {
160
+                set_bkg_sub(map_pos_x, map_pos_y + DEVICE_SCREEN_HEIGHT,
161
+                            MIN(DEVICE_SCREEN_WIDTH + 1, bg_map_mapWidth-map_pos_x), 1,
162
+                            bg_map_map, bg_map_MAP_ATTRIBUTES, bg_map_mapWidth);
163
+            }
164
+            old_map_pos_y = map_pos_y;
165
+        }
166
+
167
+        // left or right
168
+        if (map_pos_x != old_map_pos_x) {
169
+            if (camera_x < old_camera_x) {
170
+                set_bkg_sub(map_pos_x, map_pos_y,
171
+                            1, MIN(DEVICE_SCREEN_HEIGHT + 1, bg_map_mapHeight - map_pos_y),
172
+                            bg_map_map, bg_map_MAP_ATTRIBUTES, bg_map_mapWidth);
173
+            } else if ((bg_map_mapWidth - DEVICE_SCREEN_WIDTH) > map_pos_x) {
174
+                set_bkg_sub(map_pos_x + DEVICE_SCREEN_WIDTH, map_pos_y,
175
+                            1, MIN(DEVICE_SCREEN_HEIGHT + 1, bg_map_mapHeight - map_pos_y),
176
+                            bg_map_map, bg_map_MAP_ATTRIBUTES, bg_map_mapWidth);
177
+            }
178
+            old_map_pos_x = map_pos_x;
179
+        }
180
+
181
+    END_ROM_BANK();
182
+
183
+    // set old camera position to current camera position
184
+    old_camera_x = camera_x;
185
+    old_camera_y = camera_y;
186
+
187
+#endif // ! WRAP_BG
188
+}

+ 4
- 0
src/maps.h View File

@@ -20,7 +20,11 @@
20 20
 #ifndef __MAPS_H__
21 21
 #define __MAPS_H__
22 22
 
23
+#include <stdint.h>
24
+
23 25
 void map_title(void);
26
+
24 27
 void map_game(void);
28
+void map_move(int16_t delta_x, int16_t delta_y);
25 29
 
26 30
 #endif // __MAPS_H__

+ 1
- 2
src/sound.c View File

@@ -27,6 +27,7 @@
27 27
 #include "banks.h"
28 28
 #include "config.h"
29 29
 #include "timer.h"
30
+#include "util.h"
30 31
 #include "sound_menu.h"
31 32
 #include "sound_game.h"
32 33
 #include "sound_over.h"
@@ -61,8 +62,6 @@ static const struct snds snds[SND_COUNT] = {
61 62
 };
62 63
 
63 64
 #define CALL_FREQ_HZ 256
64
-#define MIN(x, y) ((x < y) ? x : y)
65
-#define MAX(x, y) ((x > y) ? x : y)
66 65
 
67 66
 static void play_note(enum notes note) NONBANKED {
68 67
     if (note < SILENCE) {

+ 29
- 0
src/util.h View File

@@ -0,0 +1,29 @@
1
+/*
2
+ * util.h
3
+ * Duality
4
+ *
5
+ * Copyright (C) 2025 Thomas Buck <thomas@xythobuz.de>
6
+ *
7
+ * Based on examples from gbdk-2020:
8
+ * https://github.com/gbdk-2020/gbdk-2020/blob/develop/gbdk-lib/examples/gb/rand/rand.c
9
+ *
10
+ * This program is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
+ * GNU General Public License for more details.
19
+ *
20
+ * See <http://www.gnu.org/licenses/>.
21
+ */
22
+
23
+#ifndef __UTIL_H__
24
+#define __UTIL_H__
25
+
26
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
27
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
28
+
29
+#endif // __UTIL_H__

+ 5
- 2
src/window.c View File

@@ -19,6 +19,7 @@
19 19
 
20 20
 #include <gbdk/platform.h>
21 21
 #include <string.h>
22
+#include <assert.h>
22 23
 
23 24
 #include "banks.h"
24 25
 #include "config.h"
@@ -278,11 +279,12 @@ void win_debug(void) BANKED {
278 279
                   title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
279 280
 
280 281
     // TODO paging when more options added
282
+    static_assert(DEBUG_ENTRY_COUNT <= 8, "too many debug menu entries");
281 283
     uint8_t off = (10 - DEBUG_ENTRY_COUNT) / 2;
282 284
 
283 285
     str_center("Debug Menu", 0, 0);
284 286
 
285
-    for (uint8_t i = 0; (i < DEBUG_ENTRY_COUNT) && (i < 7); i++) {
287
+    for (uint8_t i = 0; (i < DEBUG_ENTRY_COUNT) && (i < 8); i++) {
286 288
         char name_buff[ENTRY_NAME_LEN + 2 + 1] = {0};
287 289
         uint8_t n_len = get_debug(name_buff, i);
288 290
         str(name_buff, (LINE_WIDTH - n_len) * 2, (i * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
@@ -312,11 +314,12 @@ void win_conf(void) BANKED {
312 314
                   title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
313 315
 
314 316
     // TODO paging when more options added
317
+    static_assert(CONF_ENTRY_COUNT <= 8, "too many conf menu entries");
315 318
     uint8_t off = (10 - CONF_ENTRY_COUNT) / 2;
316 319
 
317 320
     str_center("Conf Menu", 0, 0);
318 321
 
319
-    for (uint8_t i = 0; (i < CONF_ENTRY_COUNT) && (i < 7); i++) {
322
+    for (uint8_t i = 0; (i < CONF_ENTRY_COUNT) && (i < 8); i++) {
320 323
         char name_buff[ENTRY_NAME_LEN + 2 + 1] = {0};
321 324
         uint8_t n_len = get_conf(name_buff, i);
322 325
         str(name_buff, (LINE_WIDTH - n_len) * 2, (i * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);

Loading…
Cancel
Save