Browse Source

add second configurable game background map, refactor text handling functions.

Thomas B 3 weeks ago
parent
commit
b121a2f05b
22 changed files with 879 additions and 367 deletions
  1. BIN
      data/bg2_map.png
  2. 7
    0
      src/config.ba0.c
  3. 1
    0
      src/config.h
  4. 2
    2
      src/game.c
  5. 18
    5
      src/gbprinter.c
  6. 1
    1
      src/gbprinter.h
  7. 8
    10
      src/gbprinter_error.c
  8. 5
    4
      src/main.c
  9. 1
    1
      src/main.h
  10. 179
    0
      src/map_data.c
  11. 61
    0
      src/map_data.h
  12. 96
    67
      src/maps.c
  13. 20
    2
      src/maps.h
  14. 1
    1
      src/sprite_data.c
  15. 4
    4
      src/sprite_data.h
  16. 1
    1
      src/sprites.c
  17. 89
    0
      src/strings.c
  18. 60
    0
      src/strings.h
  19. 216
    0
      src/text.c
  20. 55
    0
      src/text.h
  21. 54
    268
      src/window.c
  22. 0
    1
      src/window.h

BIN
data/bg2_map.png View File


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

@@ -55,6 +55,13 @@ void conf_init(void) BANKED {
55 55
         mem.config.debug_flags = 0;
56 56
         mem.config.sfx_vol = 0x03;
57 57
         mem.config.music_vol = 0x07;
58
+
59
+        if (_cpu == CGB_TYPE) {
60
+            mem.config.game_bg = 0;
61
+        } else {
62
+            mem.config.game_bg = 1;
63
+        }
64
+
58 65
         score_reset();
59 66
     }
60 67
 }

+ 1
- 0
src/config.h View File

@@ -44,6 +44,7 @@ struct config {
44 44
     enum debug_flag debug_flags;
45 45
     uint8_t sfx_vol;
46 46
     uint8_t music_vol;
47
+    uint8_t game_bg;
47 48
 };
48 49
 
49 50
 void conf_init(void) BANKED;

+ 2
- 2
src/game.c View File

@@ -424,7 +424,8 @@ int32_t game(enum GAME_MODE mode) NONBANKED {
424 424
 
425 425
     disable_interrupts();
426 426
     DISPLAY_OFF;
427
-    map_game();
427
+    map_load(0);
428
+    map_fill(MAP_GAME_1 + conf_get()->game_bg, 1);
428 429
     SHOW_BKG;
429 430
     spr_init_pal();
430 431
     SHOW_SPRITES;
@@ -445,7 +446,6 @@ int32_t game(enum GAME_MODE mode) NONBANKED {
445 446
         }
446 447
     }
447 448
 
448
-    win_init(0);
449 449
     uint8_t x_off = win_game_draw(score);
450 450
     move_win(MINWNDPOSX + DEVICE_SCREEN_PX_WIDTH - x_off, MINWNDPOSY + DEVICE_SCREEN_PX_HEIGHT - 16);
451 451
 

+ 18
- 5
src/gbprinter.c View File

@@ -34,7 +34,7 @@ BANKREF(gbprinter)
34 34
 #define PRN_TILE_WIDTH     20 // Width of the printed image in tiles
35 35
 #define PRN_MAGIC          0x3388
36 36
 #define PRN_MAGIC_DETECT   0x81 // magic reply from printer
37
-#define PRN_DETECT_TIMEOUT 10 // 1/6th second
37
+#define PRN_DETECT_TIMEOUT 20 // 1/3rd second
38 38
 #define PRN_BUSY_TIMEOUT   (2 * 60) // 2s
39 39
 #define PRN_PRINT_TIMEOUT  (20 * 60) // 20s
40 40
 
@@ -125,21 +125,34 @@ static uint8_t printer_check_cancel(void) {
125 125
 }
126 126
 
127 127
 static enum PRN_STATUS printer_wait(uint16_t timeout, uint8_t mask, uint8_t value) {
128
-    enum PRN_STATUS error;
128
+    enum PRN_STATUS error = PRN_STATUS_OK;
129 129
 
130 130
     while (1) {
131
+#ifdef DEBUG
132
+        error = (error & 0xF000) | printer_send_command(PRN_CMD_STATUS, NULL, 0);
133
+#else
131 134
         error = printer_send_command(PRN_CMD_STATUS, NULL, 0);
135
+#endif // DEBUG
132 136
         if ((error & mask) == value) {
133 137
             break;
134 138
         }
135 139
 
140
+#ifdef DEBUG
141
+        EMU_printf("%s: 0x%04x\n",  __func__, (uint16_t)error);
142
+
143
+        uint8_t n = (error & 0xF000) >> 12;
144
+        n = (n + 1) & 0x000F;
145
+        error = (error & 0x0FFF) | (n << 12);
146
+#endif // DEBUG
147
+
136 148
         if (printer_check_cancel()) {
137 149
             printer_send_command(PRN_CMD_BREAK, NULL, 0);
138
-            return PRN_STATUS_CANCELLED;
150
+            error |= PRN_STATUS_CANCELLED;
139 151
         }
140 152
 
141
-        if (timeout-- == 0) {
142
-            return PRN_STATUS_TIMEOUT;
153
+        timeout--;
154
+        if (timeout == 0) {
155
+            error |= PRN_STATUS_TIMEOUT;
143 156
         }
144 157
 
145 158
         if (error & PRN_STATUS_MASK_ERRORS) {

+ 1
- 1
src/gbprinter.h View File

@@ -56,7 +56,7 @@ enum PRN_STATUS {
56 56
 enum PRN_STATUS gbprinter_detect(void) BANKED;
57 57
 enum PRN_STATUS gbprinter_screenshot(uint8_t win, uint8_t palette) BANKED;
58 58
 
59
-uint8_t gbprinter_error(enum PRN_STATUS status, char *buff);
59
+uint8_t gbprinter_error(enum PRN_STATUS status, char *buff) BANKED;
60 60
 
61 61
 BANKREF_EXTERN(gbprinter)
62 62
 BANKREF_EXTERN(gbprinter_error)

+ 8
- 10
src/gbprinter_error.c View File

@@ -49,23 +49,21 @@ static const char * const error_strings[ERROR_BITS] = {
49 49
     str_cancel, str_timeout, str_magic,
50 50
 };
51 51
 
52
-uint8_t gbprinter_error(enum PRN_STATUS status, char *buff) NONBANKED {
52
+uint8_t gbprinter_error(enum PRN_STATUS status, char *buff) BANKED {
53 53
     if (status == PRN_STATUS_OK) {
54 54
         sprintf(buff, "ok");
55 55
         return 2;
56 56
     }
57 57
 
58 58
     uint8_t n = 0;
59
-    START_ROM_BANK(BANK(gbprinter_error)) {
60
-        for (uint8_t i = 0; i < ERROR_BITS; i++) {
61
-            if (status & (1 << i)) {
62
-                if (n != 0) {
63
-                    buff[n++] = '\n';
64
-                }
65
-                strcpy(buff + n, error_strings[i]);
66
-                n += strlen(error_strings[i]);
59
+    for (uint8_t i = 0; i < ERROR_BITS; i++) {
60
+        if (status & (1 << i)) {
61
+            if (n != 0) {
62
+                buff[n++] = '\n';
67 63
             }
64
+            strcpy(buff + n, error_strings[i]);
65
+            n += strlen(error_strings[i]);
68 66
         }
69
-    } END_ROM_BANK
67
+    }
70 68
     return n;
71 69
 }

+ 5
- 4
src/main.c View File

@@ -53,6 +53,7 @@ BANKREF(main)
53 53
 const struct conf_entry conf_entries[CONF_ENTRY_COUNT] = {
54 54
     //{ .name = "sfx-vol",  .var = &mem.config.sfx_vol,   .max = 3 },
55 55
     { .name = "musi-vol", .var = &mem.config.music_vol, .max = 15 },
56
+    { .name = "game-map", .var = &mem.config.game_bg,   .max = 1 },
56 57
 };
57 58
 
58 59
 const struct debug_entry debug_entries[DEBUG_ENTRY_COUNT] = {
@@ -303,7 +304,8 @@ static void splash(void) NONBANKED {
303 304
 
304 305
     disable_interrupts();
305 306
     DISPLAY_OFF;
306
-    map_title();
307
+    map_load(1);
308
+    map_fill(MAP_TITLE, 1);
307 309
     SHOW_BKG;
308 310
     spr_init_pal();
309 311
     SHOW_SPRITES;
@@ -316,7 +318,6 @@ static void splash(void) NONBANKED {
316 318
     obj_add(SPR_LIGHT, 42, -42, 0, 0);
317 319
     obj_add(SPR_DARK, -42, -42, 0, 0);
318 320
 
319
-    win_init(1);
320 321
     splash_win();
321 322
 
322 323
     DISPLAY_ON;
@@ -492,7 +493,8 @@ static uint16_t ask_name(int32_t score) NONBANKED {
492 493
 
493 494
     disable_interrupts();
494 495
     DISPLAY_OFF;
495
-    map_title();
496
+    map_load(1);
497
+    map_fill(MAP_TITLE, 0);
496 498
     SHOW_BKG;
497 499
     spr_init_pal();
498 500
     SHOW_SPRITES;
@@ -500,7 +502,6 @@ static uint16_t ask_name(int32_t score) NONBANKED {
500 502
 
501 503
     hide_sprites_range(SPR_NUM_START, MAX_HARDWARE_SPRITES);
502 504
 
503
-    win_init(1);
504 505
     win_name(score);
505 506
 
506 507
     move_win(MINWNDPOSX, MINWNDPOSY);

+ 1
- 1
src/main.h View File

@@ -39,7 +39,7 @@ struct debug_entry {
39 39
 
40 40
 BANKREF_EXTERN(main)
41 41
 
42
-#define CONF_ENTRY_COUNT 1
42
+#define CONF_ENTRY_COUNT 2
43 43
 extern const struct conf_entry conf_entries[CONF_ENTRY_COUNT];
44 44
 
45 45
 extern uint8_t debug_menu_index;

+ 179
- 0
src/map_data.c View File

@@ -0,0 +1,179 @@
1
+/*
2
+ * map_data.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 <assert.h>
21
+
22
+#include "map_data.h"
23
+
24
+#include "title_map.h"
25
+#include "bg_map.h"
26
+#include "bg2_map.h"
27
+#include "numbers_fnt16.h"
28
+#include "text_fnt16.h"
29
+#include "vincent_fnt8.h"
30
+
31
+BANKREF(map_data)
32
+
33
+/*
34
+ * BCP0: Title map
35
+ * BCP1: Game map 1
36
+ * BCP2: Game map 2
37
+ * BCP3: Text Font 16
38
+ * BCP4: Text Font 16 inverted
39
+ * BCP5: Num Font 16 (same as 3)
40
+ * BCP6: Font Ascii 8
41
+ * BCP7: (unused)
42
+ *
43
+ * Explosion uses OCP0 to OCP3 at end of game.
44
+ * Pause is flipped in-place for animating the pause screen colors.
45
+ */
46
+
47
+const palette_color_t num_pal_inv[INV_PALETTE_COUNT * 4] = {
48
+    //RGB8(  0,  0,  0), RGB8(248,252,248), RGB8(  0,  0,  0), RGB8(  0,  0,  0)
49
+    RGB8(  0,  0,  0), RGB8(  0,  0,  0), RGB8(248,252,248), RGB8(  0,  0,  0)
50
+};
51
+
52
+// currently this assumption is hard-coded
53
+static_assert(bg_map_WIDTH == 256, "bg_map needs to be 256x256");
54
+static_assert(bg_map_HEIGHT == 256, "bg_map needs to be 256x256");
55
+static_assert(bg2_map_WIDTH == 256, "bg2_map needs to be 256x256");
56
+static_assert(bg2_map_HEIGHT == 256, "bg2_map needs to be 256x256");
57
+
58
+struct maps maps[MAP_COUNT] = {
59
+    { // MAP_TITLE
60
+        .width = title_map_WIDTH / title_map_TILE_W,
61
+        .height = title_map_HEIGHT / title_map_TILE_H,
62
+        .map = title_map_map,
63
+        .tiles = title_map_tiles,
64
+        .palettes = title_map_palettes,
65
+        .palette_count = title_map_PALETTE_COUNT,
66
+        .palette_index = BKGF_CGB_PAL0,
67
+        .map_count = sizeof(title_map_map),
68
+        .tile_count = title_map_TILE_COUNT,
69
+        .tile_offset = BG_TILE_NUM_START,
70
+        .tile_copy = BG_COPY_NONE,
71
+        .bank = BANK(title_map),
72
+        .load = BG_LOAD_SPLASH,
73
+    },
74
+    { // MAP_GAME_1
75
+        .width = bg_map_WIDTH / bg_map_TILE_W,
76
+        .height = bg_map_HEIGHT / bg_map_TILE_H,
77
+        .map = bg_map_map,
78
+        .tiles = bg_map_tiles,
79
+        .palettes = bg_map_palettes,
80
+        .palette_count = bg_map_PALETTE_COUNT,
81
+        .palette_index = BKGF_CGB_PAL1,
82
+        .map_count = sizeof(bg_map_map),
83
+        .tile_count = bg_map_TILE_COUNT,
84
+        .tile_offset = BG_TILE_NUM_START,
85
+        .tile_copy = BG_COPY_NONE,
86
+        .bank = BANK(bg_map),
87
+        .load = BG_LOAD_GAME,
88
+    },
89
+    { // MAP_GAME_2
90
+        .width = bg2_map_WIDTH / bg2_map_TILE_W,
91
+        .height = bg2_map_HEIGHT / bg2_map_TILE_H,
92
+        .map = bg2_map_map,
93
+        .tiles = bg2_map_tiles,
94
+        .palettes = bg2_map_palettes,
95
+        .palette_count = bg2_map_PALETTE_COUNT,
96
+        .palette_index = BKGF_CGB_PAL2,
97
+        .map_count = sizeof(bg2_map_map),
98
+        .tile_count = bg2_map_TILE_COUNT,
99
+        .tile_offset = BG_TILE_NUM_START,
100
+        .tile_copy = BG_COPY_NONE,
101
+        .bank = BANK(bg2_map),
102
+        .load = BG_LOAD_GAME,
103
+    },
104
+    { // FNT_TEXT_16
105
+        .width = text_fnt16_WIDTH / text_fnt16_TILE_W,
106
+        .height = text_fnt16_HEIGHT / text_fnt16_TILE_H,
107
+        .map = text_fnt16_map,
108
+        .tiles = text_fnt16_tiles,
109
+        .palettes = text_fnt16_palettes,
110
+        .palette_count = text_fnt16_PALETTE_COUNT,
111
+        .palette_index = BKGF_CGB_PAL3,
112
+        .map_count = sizeof(text_fnt16_map),
113
+        .tile_count = text_fnt16_TILE_COUNT,
114
+        .tile_offset = BG_TILE_NUM_START,
115
+        .tile_copy = BG_COPY_NONE,
116
+        .bank = BANK(text_fnt16),
117
+        .load = BG_LOAD_SPLASH,
118
+    },
119
+    { // FNT_TEXT_16_INV
120
+        .width = text_fnt16_WIDTH / text_fnt16_TILE_W,
121
+        .height = text_fnt16_HEIGHT / text_fnt16_TILE_H,
122
+        .map = text_fnt16_map,
123
+        .tiles = text_fnt16_tiles,
124
+        .palettes = num_pal_inv,
125
+        .palette_count = INV_PALETTE_COUNT,
126
+        .palette_index = BKGF_CGB_PAL4,
127
+        .map_count = sizeof(text_fnt16_map),
128
+        .tile_count = text_fnt16_TILE_COUNT,
129
+        .tile_offset = BG_TILE_NUM_START,
130
+        .tile_copy = FNT_TEXT_16,
131
+        .bank = BANK(text_fnt16),
132
+        .load = BG_LOAD_SPLASH,
133
+    },
134
+    { // FNT_NUM_16
135
+        .width = numbers_fnt16_WIDTH / numbers_fnt16_TILE_W,
136
+        .height = numbers_fnt16_HEIGHT / numbers_fnt16_TILE_H,
137
+        .map = numbers_fnt16_map,
138
+        .tiles = numbers_fnt16_tiles,
139
+        .palettes = numbers_fnt16_palettes,
140
+        .palette_count = numbers_fnt16_PALETTE_COUNT,
141
+        .palette_index = BKGF_CGB_PAL5,
142
+        .map_count = sizeof(numbers_fnt16_map),
143
+        .tile_count = numbers_fnt16_TILE_COUNT,
144
+        .tile_offset = BG_TILE_NUM_START,
145
+        .tile_copy = BG_COPY_NONE,
146
+        .bank = BANK(numbers_fnt16),
147
+        .load = BG_LOAD_ALL,
148
+    },
149
+    { // FNT_NUM_16_INV
150
+        .width = numbers_fnt16_WIDTH / numbers_fnt16_TILE_W,
151
+        .height = numbers_fnt16_HEIGHT / numbers_fnt16_TILE_H,
152
+        .map = numbers_fnt16_map,
153
+        .tiles = numbers_fnt16_tiles,
154
+        .palettes = NULL,
155
+        .palette_count = INV_PALETTE_COUNT,
156
+        .palette_index = BKGF_CGB_PAL4,
157
+        .map_count = sizeof(numbers_fnt16_map),
158
+        .tile_count = numbers_fnt16_TILE_COUNT,
159
+        .tile_offset = BG_TILE_NUM_START,
160
+        .tile_copy = FNT_NUM_16,
161
+        .bank = BANK(numbers_fnt16),
162
+        .load = BG_LOAD_ALL,
163
+    },
164
+    { // FNT_ASCII_8
165
+        .width = vincent_fnt8_WIDTH / vincent_fnt8_TILE_W,
166
+        .height = vincent_fnt8_HEIGHT / vincent_fnt8_TILE_H,
167
+        .map = vincent_fnt8_map,
168
+        .tiles = vincent_fnt8_tiles,
169
+        .palettes = vincent_fnt8_palettes,
170
+        .palette_count = vincent_fnt8_PALETTE_COUNT,
171
+        .palette_index = BKGF_CGB_PAL6,
172
+        .map_count = sizeof(vincent_fnt8_map),
173
+        .tile_count = vincent_fnt8_TILE_COUNT,
174
+        .tile_offset = BG_TILE_NUM_START,
175
+        .tile_copy = BG_COPY_NONE,
176
+        .bank = BANK(vincent_fnt8),
177
+        .load = BG_LOAD_SPLASH | BG_LOAD_GBC_ONLY,
178
+    },
179
+};

+ 61
- 0
src/map_data.h View File

@@ -0,0 +1,61 @@
1
+/*
2
+ * map_data.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 __MAP__DATA_H__
21
+#define __MAP__DATA_H__
22
+
23
+#include <gbdk/platform.h>
24
+#include <stdint.h>
25
+
26
+#include "maps.h"
27
+
28
+// background tiles are loaded into VRAM starting at tile number 0
29
+#define BG_TILE_NUM_START 0
30
+
31
+#define BG_COPY_NONE 0xFF
32
+
33
+#define BG_LOAD_GAME     (0 << 0)
34
+#define BG_LOAD_SPLASH   (1 << 0)
35
+#define BG_LOAD_ALL      (1 << 6)
36
+#define BG_LOAD_GBC_ONLY (1 << 7)
37
+
38
+struct maps {
39
+    uint8_t width;
40
+    uint8_t height;
41
+    const uint8_t * map;
42
+    const uint8_t * tiles;
43
+    const palette_color_t * palettes;
44
+    uint8_t palette_count;
45
+    uint8_t palette_index;
46
+    uint16_t map_count;
47
+    uint8_t tile_count;
48
+    uint8_t tile_offset;
49
+    uint8_t tile_copy;
50
+    uint8_t bank;
51
+    uint8_t load;
52
+};
53
+
54
+extern struct maps maps[MAP_COUNT];
55
+
56
+BANKREF_EXTERN(map_data)
57
+
58
+#define INV_PALETTE_COUNT 1
59
+extern const palette_color_t num_pal_inv[INV_PALETTE_COUNT * 4];
60
+
61
+#endif // __MAP__DATA_H__

+ 96
- 67
src/maps.c View File

@@ -20,23 +20,21 @@
20 20
  * See <http://www.gnu.org/licenses/>.
21 21
  */
22 22
 
23
-#include <assert.h>
24
-
25 23
 #include "banks.h"
26
-#include "title_map.h"
27
-#include "bg_map.h"
24
+#include "gb/gb.h"
28 25
 #include "util.h"
26
+#include "map_data.h"
29 27
 #include "maps.h"
30 28
 
31
-// currently this assumption is hard-coded
32
-static_assert(bg_map_WIDTH == 256, "bg_map needs to be 256x256");
33
-static_assert(bg_map_HEIGHT == 256, "bg_map needs to be 256x256");
34
-
35 29
 #define POS_SCALE_BG 6
36 30
 
31
+// current unscaled ship position
32
+static uint16_t abs_x, abs_y;
33
+
37 34
 // define this to disable mirrored map scaling support
38 35
 #define WRAP_BG // TODO
39 36
 
37
+#ifndef WRAP_BG
40 38
 #define bg_map_mapWidth (bg_map_WIDTH / bg_map_TILE_W)
41 39
 #define bg_map_mapHeight (bg_map_HEIGHT / bg_map_TILE_H)
42 40
 
@@ -48,43 +46,90 @@ static_assert(bg_map_HEIGHT == 256, "bg_map needs to be 256x256");
48 46
 #define MAP_FLIP_Y (0x40 | 0x02)
49 47
 #define MAP_FLIP_XY (MAP_FLIP_X | MAP_FLIP_Y)
50 48
 
51
-// current unscaled ship position
52
-static uint16_t abs_x, abs_y;
53
-
54 49
 // current and old positions of the camera in pixels
55 50
 static uint16_t old_camera_x, old_camera_y;
56 51
 
57 52
 // current and old position of the map in tiles
58 53
 static uint8_t old_map_pos_x, old_map_pos_y;
54
+#endif // ! WRAP_BG
55
+
56
+BANKREF(maps)
57
+
58
+static void map_load_helper(uint8_t i) NONBANKED {
59
+    START_ROM_BANK(maps[i].bank) {
60
+        if (maps[i].tile_copy == BG_COPY_NONE) {
61
+            set_bkg_data(maps[i].tile_offset, maps[i].tile_count, maps[i].tiles);
62
+        }
63
+    } END_ROM_BANK
64
+
65
+    uint8_t bank = maps[i].bank;
66
+    if (maps[i].palettes == num_pal_inv) {
67
+        bank = BANK(map_data);
68
+    }
69
+
70
+    START_ROM_BANK_2(bank) {
71
+        if (maps[i].palettes != NULL) {
72
+            set_bkg_palette(maps[i].palette_index, maps[i].palette_count, maps[i].palettes);
73
+        }
74
+    } END_ROM_BANK
75
+}
59 76
 
60
-void map_title(void) NONBANKED {
61
-    START_ROM_BANK(BANK(title_map)) {
62
-        set_bkg_palette(OAMF_CGB_PAL0, title_map_PALETTE_COUNT, title_map_palettes);
63
-        set_bkg_data(0, title_map_TILE_COUNT, title_map_tiles);
77
+void map_load(uint8_t is_splash) BANKED {
78
+    uint8_t off = BG_TILE_NUM_START;
79
+    uint8_t off_gbc = BG_TILE_NUM_START;
80
+
81
+    for (uint8_t i = 0; i < MAP_COUNT; i++) {
82
+        if (!(maps[i].load & BG_LOAD_ALL)) {
83
+            if (is_splash) {
84
+                if (!(maps[i].load & BG_LOAD_SPLASH)) {
85
+                    continue;
86
+                }
87
+            } else {
88
+                if (maps[i].load & BG_LOAD_SPLASH) {
89
+                    continue;
90
+                }
91
+            }
92
+        }
64 93
 
65
-        if (title_map_MAP_ATTRIBUTES != NULL) {
66
-            set_bkg_attributes(0, 0,
67
-                               title_map_WIDTH / title_map_TILE_W,
68
-                               title_map_HEIGHT / title_map_TILE_H,
69
-                               title_map_MAP_ATTRIBUTES);
94
+        if (_cpu != CGB_TYPE) {
95
+            if (maps[i].load & BG_LOAD_GBC_ONLY) {
96
+                continue;
97
+            }
98
+        }
99
+
100
+        if (maps[i].tile_copy == BG_COPY_NONE) {
101
+            if (maps[i].load & BG_LOAD_GBC_ONLY) {
102
+                VBK_REG = VBK_BANK_1;
103
+                maps[i].tile_offset = off_gbc;
104
+                off_gbc += maps[i].tile_count;
105
+            } else {
106
+                maps[i].tile_offset = off;
107
+                off += maps[i].tile_count;
108
+            }
70 109
         } else {
71
-            VBK_REG = VBK_ATTRIBUTES;
72
-            fill_bkg_rect(0, 0,
73
-                          title_map_WIDTH / title_map_TILE_W,
74
-                          title_map_HEIGHT / title_map_TILE_H,
75
-                          0x00);
76
-            VBK_REG = VBK_TILES;
110
+            maps[i].tile_offset = maps[maps[i].tile_copy].tile_offset;
77 111
         }
78 112
 
79
-        set_bkg_tiles(0, 0,
80
-                      title_map_WIDTH / title_map_TILE_W,
81
-                      title_map_HEIGHT / title_map_TILE_H,
82
-                      title_map_map);
113
+        map_load_helper(i);
114
+    }
115
+}
116
+
117
+void map_fill(enum MAPS map, uint8_t bkg) NONBANKED {
118
+    START_ROM_BANK(maps[map].bank) {
119
+        VBK_REG = VBK_ATTRIBUTES;
120
+        bkg ? fill_bkg_rect(0, 0, maps[map].width, maps[map].height, maps[map].palette_index)
121
+            : fill_win_rect(0, 0, maps[map].width, maps[map].height, maps[map].palette_index);
122
+
123
+        VBK_REG = VBK_TILES;
124
+        bkg ? set_bkg_based_tiles(0, 0, maps[map].width, maps[map].height, maps[map].map, maps[map].tile_offset)
125
+            : set_win_based_tiles(0, 0, maps[map].width, maps[map].height, maps[map].map, maps[map].tile_offset);
83 126
     } END_ROM_BANK
84 127
 
85
-    move_bkg(0, 0);
128
+    bkg ? move_bkg(0, 0)
129
+        : move_win(MINWNDPOSX, MINWNDPOSY);
86 130
 }
87 131
 
132
+#ifndef WRAP_BG
88 133
 static inline void set_bkg_sub_attr(uint8_t x, uint8_t y,
89 134
                                     uint8_t w, uint8_t h,
90 135
                                     const uint8_t *attr,
@@ -109,48 +154,31 @@ static inline void set_bkg_sub(uint8_t x, uint8_t y,
109 154
         set_bkg_sub_attr(x, y, w, h, attr, attr_val, map_w);
110 155
     } END_ROM_BANK
111 156
 }
157
+#endif // ! WRAP_BG
112 158
 
159
+// TODO
160
+#ifndef WRAP_BG
113 161
 void map_game(void) NONBANKED {
114 162
     START_ROM_BANK(BANK(bg_map)) {
115
-        set_bkg_palette(OAMF_CGB_PAL0, bg_map_PALETTE_COUNT, bg_map_palettes);
116
-        set_bkg_data(0, bg_map_TILE_COUNT, bg_map_tiles);
163
+        abs_x = 0;
164
+        abs_y = 0;
165
+        old_camera_x = 0;
166
+        old_camera_y = 0;
167
+        old_map_pos_x = 0;
168
+        old_map_pos_y = 0;
169
+
170
+        move_bkg(0, 0);
171
+
172
+        // Draw the initial map view for the whole screen
173
+        set_bkg_sub(0, 0,
174
+                    MIN(DEVICE_SCREEN_WIDTH + 1u, bg_map_mapWidth),
175
+                    MIN(DEVICE_SCREEN_HEIGHT + 1u, bg_map_mapHeight),
176
+                    bg_map_map, bg_map_MAP_ATTRIBUTES, MAP_FLIP_NONE, bg_map_mapWidth);
117 177
     } END_ROM_BANK
118
-
119
-#ifdef WRAP_BG
120
-
121
-        if (bg_map_MAP_ATTRIBUTES != NULL) {
122
-            set_bkg_attributes(0, 0,
123
-                               bg_map_WIDTH / bg_map_TILE_W, bg_map_HEIGHT / bg_map_TILE_H,
124
-                               bg_map_MAP_ATTRIBUTES);
125
-        } else {
126
-            VBK_REG = VBK_ATTRIBUTES;
127
-            fill_bkg_rect(0, 0,
128
-                          bg_map_WIDTH / bg_map_TILE_W, bg_map_HEIGHT / bg_map_TILE_H,
129
-                          0x00);
130
-            VBK_REG = VBK_TILES;
131
-        }
132
-        set_bkg_tiles(0, 0, bg_map_WIDTH / bg_map_TILE_W, bg_map_HEIGHT / bg_map_TILE_H, bg_map_map);
133
-
134
-#else // WRAP_BG
135
-
136
-    abs_x = 0;
137
-    abs_y = 0;
138
-    old_camera_x = 0;
139
-    old_camera_y = 0;
140
-    old_map_pos_x = 0;
141
-    old_map_pos_y = 0;
142
-
143
-    move_bkg(0, 0);
144
-
145
-    // Draw the initial map view for the whole screen
146
-    set_bkg_sub(0, 0,
147
-                MIN(DEVICE_SCREEN_WIDTH + 1u, bg_map_mapWidth),
148
-                MIN(DEVICE_SCREEN_HEIGHT + 1u, bg_map_mapHeight),
149
-                bg_map_map, bg_map_MAP_ATTRIBUTES, MAP_FLIP_NONE, bg_map_mapWidth);
150
-
151
-#endif // WRAP_BG
152 178
 }
179
+#endif // ! WRAP_BG
153 180
 
181
+#ifndef WRAP_BG
154 182
 static inline void set(uint8_t dst_x, uint8_t dst_y,
155 183
                        uint8_t src_x, uint8_t src_y,
156 184
                        uint8_t attr) {
@@ -159,6 +187,7 @@ static inline void set(uint8_t dst_x, uint8_t dst_y,
159 187
         set_bkg_attribute_xy(dst_x, dst_y, attr);
160 188
     } END_ROM_BANK
161 189
 }
190
+#endif // ! WRAP_BG
162 191
 
163 192
 void map_dbg_reset(void) NONBANKED {
164 193
 #ifndef WRAP_BG

+ 20
- 2
src/maps.h View File

@@ -20,13 +20,31 @@
20 20
 #ifndef __MAPS_H__
21 21
 #define __MAPS_H__
22 22
 
23
+#include <gbdk/platform.h>
23 24
 #include <stdint.h>
24 25
 
25
-void map_title(void);
26
+enum MAPS {
27
+    MAP_TITLE = 0,
28
+    MAP_GAME_1,
29
+    MAP_GAME_2,
26 30
 
27
-void map_game(void);
31
+    FNT_TEXT_16,
32
+    FNT_TEXT_16_INV,
33
+
34
+    FNT_NUM_16,
35
+    FNT_NUM_16_INV,
36
+
37
+    FNT_ASCII_8,
38
+
39
+    MAP_COUNT
40
+};
41
+
42
+void map_load(uint8_t is_splash) BANKED;
43
+void map_fill(enum MAPS map, uint8_t bkg);
28 44
 void map_move(int16_t delta_x, int16_t delta_y);
29 45
 
30 46
 void map_dbg_reset(void);
31 47
 
48
+BANKREF_EXTERN(maps)
49
+
32 50
 #endif // __MAPS_H__

+ 1
- 1
src/sprite_data.c View File

@@ -32,7 +32,7 @@
32 32
 #include "debug_marker.h"
33 33
 #include "debug_marker_spr32.h"
34 34
 
35
-BANKREF(power_palettes)
35
+BANKREF(sprite_data)
36 36
 
37 37
 /*
38 38
  * OCP0: Rocketship (1)

+ 4
- 4
src/sprite_data.h View File

@@ -20,8 +20,8 @@
20 20
  * See <http://www.gnu.org/licenses/>.
21 21
  */
22 22
 
23
-#ifndef __SPRITE__DATA_H
24
-#define __SPRITE__DATA_H
23
+#ifndef __SPRITE__DATA_H__
24
+#define __SPRITE__DATA_H__
25 25
 
26 26
 #include <gbdk/platform.h>
27 27
 #include <gbdk/metasprites.h>
@@ -54,7 +54,7 @@ struct sprites {
54 54
 
55 55
 extern struct sprites metasprites[SPRITE_COUNT];
56 56
 
57
-BANKREF_EXTERN(power_palettes)
57
+BANKREF_EXTERN(sprite_data)
58 58
 extern const palette_color_t power_palettes[4];
59 59
 
60
-#endif // __SPRITE__DATA_H
60
+#endif // __SPRITE__DATA_H__

+ 1
- 1
src/sprites.c View File

@@ -42,7 +42,7 @@ void spr_init_pal(void) NONBANKED {
42 42
     for (uint8_t i = 0; i < SPRITE_COUNT; i++) {
43 43
         uint8_t bank = metasprites[i].bank;
44 44
         if (metasprites[i].pa == power_palettes) {
45
-            bank = BANK(power_palettes);
45
+            bank = BANK(sprite_data);
46 46
         }
47 47
 
48 48
         START_ROM_BANK(bank) {

+ 89
- 0
src/strings.c View File

@@ -0,0 +1,89 @@
1
+/*
2
+ * strings.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 <string.h>
21
+
22
+#include "banks.h"
23
+#include "strings.h"
24
+
25
+BANKREF(strings)
26
+
27
+static const char string_top[] = "top";
28
+static const char string_score[] = "score";
29
+static const char string_black[] = "black";
30
+static const char string_white[] = "white";
31
+static const char string_enter[] = "enter";
32
+static const char string_name[] = "name";
33
+static const char string_start_ok[] = "start ok";
34
+static const char string_conf_menu[] = "Conf Menu";
35
+static const char string_debug_menu[] = "Debug Menu";
36
+static const char string_duality[] = "Duality";
37
+static const char string_xythobuz[] = "xythobuz";
38
+static const char string_git[] = "Git Commit Hash:";
39
+static const char string_build_date[] = "Build Date:";
40
+static const char string_date[] = __DATE__;
41
+static const char string_time[] = __TIME__;
42
+static const char string_mp_tx[] = "MP Tx:";
43
+static const char string_wait[] = "Wait";
44
+static const char string_visit[] = "Visit:";
45
+static const char string_url[] = "https://xythobuz.de";
46
+static const char string_printout[] = "printout";
47
+static const char string_success[] = "success";
48
+static const char string_error[] = "error";
49
+static const char string_gb_printer[] = "GB Printer";
50
+static const char string_score_printout[] = "Score Printout";
51
+static const char string_result[] = "Result:";
52
+static const char string_printf_error[] = "error: 0x%04x";
53
+
54
+static const char * const strings[COUNT_STRINGS] = {
55
+    string_top,            // STR_TOP
56
+    string_score,          // STR_SCORE
57
+    string_black,          // STR_BLACK
58
+    string_white,          // STR_WHITE
59
+    string_enter,          // STR_ENTER
60
+    string_name,           // STR_NAME
61
+    string_start_ok,       // STR_START_OK
62
+    string_conf_menu,      // STR_CONF_MENU
63
+    string_debug_menu,     // STR_DEBUG_MENU
64
+    string_duality,        // STR_DUALITY
65
+    string_xythobuz,       // STR_XYTHOBUZ
66
+    string_git,            // STR_GIT
67
+    string_build_date,     // STR_BUILD_DATE
68
+    string_date,           // STR_DATE
69
+    string_time,           // STR_TIME
70
+    string_mp_tx,          // STR_MP_TX
71
+    string_wait,           // STR_WAIT
72
+    string_visit,          // STR_VISIT
73
+    string_url,            // STR_URL
74
+    string_printout,       // STR_PRINTOUT
75
+    string_success,        // STR_SUCCESS
76
+    string_error,          // STR_ERROR
77
+    string_gb_printer,     // STR_GB_PRINTER
78
+    string_score_printout, // STR_SCORE_PRINTOUT
79
+    string_result,         // STR_RESULT
80
+    string_printf_error,   // STR_PRINTF_ERROR
81
+};
82
+
83
+#define MAX_STR_LEN 32
84
+static char str_buff[MAX_STR_LEN + 1];
85
+
86
+const char *get_string(enum STRINGS s) BANKED {
87
+    strncpy(str_buff, strings[s], MAX_STR_LEN);
88
+    return str_buff;
89
+}

+ 60
- 0
src/strings.h View File

@@ -0,0 +1,60 @@
1
+/*
2
+ * strings.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 __STRINGS_H__
21
+#define __STRINGS_H__
22
+
23
+#include <gbdk/platform.h>
24
+
25
+enum STRINGS {
26
+    STR_TOP = 0,
27
+    STR_SCORE,
28
+    STR_BLACK,
29
+    STR_WHITE,
30
+    STR_ENTER,
31
+    STR_NAME,
32
+    STR_START_OK,
33
+    STR_CONF_MENU,
34
+    STR_DEBUG_MENU,
35
+    STR_DUALITY,
36
+    STR_XYTHOBUZ,
37
+    STR_GIT,
38
+    STR_BUILD_DATE,
39
+    STR_DATE,
40
+    STR_TIME,
41
+    STR_MP_TX,
42
+    STR_WAIT,
43
+    STR_VISIT,
44
+    STR_URL,
45
+    STR_PRINTOUT,
46
+    STR_SUCCESS,
47
+    STR_ERROR,
48
+    STR_GB_PRINTER,
49
+    STR_SCORE_PRINTOUT,
50
+    STR_RESULT,
51
+    STR_PRINTF_ERROR,
52
+
53
+    COUNT_STRINGS
54
+};
55
+
56
+const char *get_string(enum STRINGS s) BANKED;
57
+
58
+BANKREF_EXTERN(strings)
59
+
60
+#endif // __STRINGS_H__

+ 216
- 0
src/text.c View File

@@ -0,0 +1,216 @@
1
+/*
2
+ * text.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 <gbdk/platform.h>
21
+#include <string.h>
22
+#include <stdio.h>
23
+
24
+#include "banks.h"
25
+#include "maps.h"
26
+#include "map_data.h"
27
+#include "text.h"
28
+
29
+// TODO inverted score color not visible on DMG
30
+// TODO 8x8 font only available on GBC
31
+
32
+#define TEXT_PALETTE_WHITE BKGF_CGB_PAL3
33
+#define TEXT_PALETTE_BLACK BKGF_CGB_PAL4
34
+
35
+#define TEXT_ATTR_WHITE    (BKGF_PRI | TEXT_PALETTE_WHITE)
36
+#define TEXT_ATTR_BLACK    (BKGF_PRI | TEXT_PALETTE_BLACK)
37
+
38
+#define ASCI_ATTR_DARK     (BKGF_PRI | BKGF_BANK1 | BKGF_CGB_PAL6) // TODO?
39
+#define ASCI_ATTR_LIGHT    (BKGF_PRI | BKGF_BANK1 | BKGF_CGB_PAL5) // TODO?
40
+
41
+BANKREF(text)
42
+
43
+static void digit(uint8_t val, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black);
44
+
45
+static void set_win_based(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
46
+                          const uint8_t *tiles, uint8_t base_tile, uint8_t tile_bank,
47
+                          const uint8_t *attributes, uint8_t attr_bank) NONBANKED {
48
+    if (attributes != NULL) {
49
+        START_ROM_BANK(attr_bank) {
50
+            VBK_REG = VBK_ATTRIBUTES;
51
+            set_win_tiles(x, y, w, h, attributes);
52
+        } END_ROM_BANK
53
+    } else {
54
+        VBK_REG = VBK_ATTRIBUTES;
55
+        fill_win_rect(x, y, w, h, 0x00);
56
+    }
57
+
58
+    START_ROM_BANK(tile_bank) {
59
+        VBK_REG = VBK_TILES;
60
+        set_win_based_tiles(x, y, w, h, tiles, base_tile);
61
+    } END_ROM_BANK
62
+}
63
+
64
+static void set_win_based_attr(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
65
+                               const uint8_t *tiles, uint8_t base_tile, uint8_t tile_bank,
66
+                               const uint8_t attr) NONBANKED {
67
+    VBK_REG = VBK_ATTRIBUTES;
68
+    fill_win_rect(x, y, w, h, attr);
69
+
70
+    START_ROM_BANK(tile_bank) {
71
+        VBK_REG = VBK_TILES;
72
+        set_win_based_tiles(x, y, w, h, tiles, base_tile);
73
+    } END_ROM_BANK
74
+}
75
+
76
+// ----------------------------------------------------------------------------
77
+// Characters 16x16 (for menus)
78
+// ----------------------------------------------------------------------------
79
+
80
+static void character(uint8_t c, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
81
+    uint8_t off = c * maps[FNT_TEXT_16].width;
82
+
83
+    set_win_based_attr(x_off + (pos * maps[FNT_TEXT_16].width), y_off,
84
+                       maps[FNT_TEXT_16].width, 1,
85
+                       maps[FNT_TEXT_16].map + off,
86
+                       maps[FNT_TEXT_16].tile_offset,
87
+                       maps[FNT_TEXT_16].bank, is_black ? TEXT_ATTR_BLACK : TEXT_ATTR_WHITE);
88
+
89
+    set_win_based_attr(x_off + (pos * maps[FNT_TEXT_16].width), y_off + 1,
90
+                       maps[FNT_TEXT_16].width, 1,
91
+                       maps[FNT_TEXT_16].map + off + (maps[FNT_TEXT_16].map_count / 2),
92
+                       maps[FNT_TEXT_16].tile_offset,
93
+                       maps[FNT_TEXT_16].bank, is_black ? TEXT_ATTR_BLACK : TEXT_ATTR_WHITE);
94
+}
95
+
96
+void str3(uint16_t name, uint8_t x_off, uint8_t y_off,
97
+          uint8_t is_black_a, uint8_t is_black_b, uint8_t is_black_c) BANKED {
98
+    character((name >> 10) & 0x1F, 0, x_off, y_off, is_black_a);
99
+    character((name >>  5) & 0x1F, 1, x_off, y_off, is_black_b);
100
+    character((name >>  0) & 0x1F, 2, x_off, y_off, is_black_c);
101
+}
102
+
103
+void str_l(const char *s, uint8_t len, uint8_t x_off, uint8_t y_off, uint8_t is_black) BANKED {
104
+    for (uint8_t n = 0; (*s) && (n < TEXT_LINE_WIDTH) && (n < len); n++) {
105
+        char c = *(s++);
106
+        if ((c >= 'A') && (c <= 'Z')) {
107
+            c = c - 'A' + 'a';
108
+        }
109
+        if ((c >= '0') && (c <= '9')) {
110
+            digit(c - '0', n, x_off, y_off, is_black);
111
+        } else if ((c >= 'a') && (c <= 'z')) {
112
+            character(c - 'a', n, x_off, y_off, is_black);
113
+        }
114
+    }
115
+}
116
+
117
+void str(const char *s, uint8_t x_off, uint8_t y_off, uint8_t is_black) BANKED {
118
+    str_l(s, 0xFF, x_off, y_off, is_black);
119
+}
120
+
121
+void str_center(const char *s, uint8_t y_off, uint8_t is_black) BANKED {
122
+    uint8_t n = strlen(s);
123
+    if (n > TEXT_LINE_WIDTH) n = TEXT_LINE_WIDTH;
124
+    str(s, TEXT_LINE_WIDTH - n, y_off, is_black);
125
+}
126
+
127
+void str_lines(const char *s, uint8_t y_off, uint8_t is_black) BANKED {
128
+    if (strlen(s) > 10) {
129
+        str(s, 0, y_off, is_black);
130
+        str_center(s + 10, y_off + 2, is_black);
131
+    } else {
132
+        str_center(s, y_off, is_black);
133
+    }
134
+}
135
+
136
+// ----------------------------------------------------------------------------
137
+// Numbers 16x16 (for scores)
138
+// ----------------------------------------------------------------------------
139
+
140
+static void digit(uint8_t val, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
141
+    uint8_t off = val * maps[FNT_NUM_16].width;
142
+
143
+    set_win_based_attr(x_off + (pos * maps[FNT_NUM_16].width), y_off,
144
+                       maps[FNT_NUM_16].width, 1,
145
+                       maps[FNT_NUM_16].map + off,
146
+                       maps[FNT_NUM_16].tile_offset,
147
+                       maps[FNT_NUM_16].bank, is_black ? TEXT_ATTR_BLACK : TEXT_ATTR_WHITE);
148
+
149
+    set_win_based_attr(x_off + (pos * maps[FNT_NUM_16].width), y_off + 1,
150
+                       maps[FNT_NUM_16].width, 1,
151
+                       maps[FNT_NUM_16].map + off + (maps[FNT_NUM_16].map_count / 2),
152
+                       maps[FNT_NUM_16].tile_offset,
153
+                       maps[FNT_NUM_16].bank, is_black ? TEXT_ATTR_BLACK : TEXT_ATTR_WHITE);
154
+}
155
+
156
+uint8_t number(int32_t score, uint8_t x_off, uint8_t y_off, uint8_t is_black) BANKED {
157
+    // TODO can not set numbers larger than int16 max?!
158
+    //score = 32767 + 1; // wtf?!
159
+
160
+    uint8_t len = 0;
161
+    uint8_t digits[MAX_DIGITS];
162
+    do {
163
+        digits[len++] = score % 10L;
164
+        score = score / 10L;
165
+        if (len >= MAX_DIGITS) {
166
+            break;
167
+        }
168
+    } while (score > 0);
169
+
170
+    // if the number was too large for our buffer don't draw anything
171
+    if (score > 0) {
172
+        return 0;
173
+    }
174
+
175
+    uint8_t off = (x_off == 0xFF) ? (TEXT_LINE_WIDTH - len)
176
+               : ((x_off == 0xFE) ? ((TEXT_LINE_WIDTH * 2) - (len * 2)) : x_off);
177
+    for (uint8_t i = 0; i < len; i++) {
178
+        digit(digits[len - i - 1], i, off, y_off, is_black);
179
+    }
180
+
181
+    return 8 * len * 2;
182
+}
183
+
184
+// ----------------------------------------------------------------------------
185
+// GBC-only ASCII 8x8 font (for detailed / debug output)
186
+// ----------------------------------------------------------------------------
187
+
188
+static void char_ascii(uint8_t c, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t light) {
189
+    set_win_based_attr(x_off + pos, y_off, 1, 1,
190
+                       maps[FNT_ASCII_8].map + c, 0,
191
+                       maps[FNT_ASCII_8].bank, light ? ASCI_ATTR_LIGHT : ASCI_ATTR_DARK);
192
+}
193
+
194
+void str_ascii_l(const char *s, uint8_t len, uint8_t x_off, uint8_t y_off, uint8_t light) BANKED {
195
+    for (uint8_t n = 0; (*s) && (n < (2 * TEXT_LINE_WIDTH)) && (n < len); n++) {
196
+        char c = *(s++);
197
+        char_ascii(c, n, x_off, y_off, light);
198
+    }
199
+}
200
+
201
+void str_ascii(const char *s, uint8_t x_off, uint8_t y_off, uint8_t light) BANKED {
202
+    str_ascii_l(s, 0xFF, x_off, y_off, light);
203
+}
204
+
205
+void str_ascii_lines(const char *s, uint8_t y_off, uint8_t light) BANKED {
206
+    const char *nl = s;
207
+    uint8_t lines = 0;
208
+    do {
209
+        // find next newline
210
+        while (*nl && (*nl != '\n')) nl++;
211
+        str_ascii_l(s, nl - s, 0, y_off + lines, light);
212
+        lines++;
213
+        if (*nl) nl++;
214
+        s = nl;
215
+    } while (*nl);
216
+}

+ 55
- 0
src/text.h View File

@@ -0,0 +1,55 @@
1
+/*
2
+ * text.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 __TEXT_H__
21
+#define __TEXT_H__
22
+
23
+#include <gbdk/platform.h>
24
+
25
+#define MAX_DIGITS 7
26
+#define TEXT_LINE_WIDTH 10
27
+
28
+// ----------------------------------------------------------------------------
29
+// Characters 16x16 (for menus)
30
+// ----------------------------------------------------------------------------
31
+
32
+void str3(uint16_t name, uint8_t x_off, uint8_t y_off,
33
+          uint8_t is_black_a, uint8_t is_black_b, uint8_t is_black_c) BANKED;
34
+void str_l(const char *s, uint8_t len, uint8_t x_off, uint8_t y_off, uint8_t is_black) BANKED;
35
+void str(const char *s, uint8_t x_off, uint8_t y_off, uint8_t is_black) BANKED;
36
+void str_center(const char *s, uint8_t y_off, uint8_t is_black) BANKED;
37
+void str_lines(const char *s, uint8_t y_off, uint8_t is_black) BANKED;
38
+
39
+// ----------------------------------------------------------------------------
40
+// Numbers 16x16 (for scores)
41
+// ----------------------------------------------------------------------------
42
+
43
+uint8_t number(int32_t score, uint8_t x_off, uint8_t y_off, uint8_t is_black) BANKED;
44
+
45
+// ----------------------------------------------------------------------------
46
+// GBC-only ASCII 8x8 font (for detailed / debug output)
47
+// ----------------------------------------------------------------------------
48
+
49
+void str_ascii_l(const char *s, uint8_t len, uint8_t x_off, uint8_t y_off, uint8_t light) BANKED;
50
+void str_ascii(const char *s, uint8_t x_off, uint8_t y_off, uint8_t light) BANKED;
51
+void str_ascii_lines(const char *s, uint8_t y_off, uint8_t light) BANKED;
52
+
53
+BANKREF_EXTERN(text)
54
+
55
+#endif // __TEXT_H__

+ 54
- 268
src/window.c View File

@@ -17,234 +17,25 @@
17 17
  * See <http://www.gnu.org/licenses/>.
18 18
  */
19 19
 
20
-#include <gbdk/platform.h>
21 20
 #include <string.h>
22 21
 #include <stdio.h>
23 22
 #include <assert.h>
24 23
 
25 24
 #include "banks.h"
26 25
 #include "config.h"
27
-#include "gb/hardware.h"
28 26
 #include "score.h"
29
-#include "title_map.h"
30
-#include "bg_map.h"
31
-#include "numbers_fnt16.h"
32
-#include "text_fnt16.h"
33
-#include "vincent_fnt8.h"
27
+#include "text.h"
34 28
 #include "git.h"
35 29
 #include "main.h"
30
+#include "maps.h"
31
+#include "map_data.h"
36 32
 #include "gbprinter.h"
37 33
 #include "multiplayer.h"
34
+#include "strings.h"
38 35
 #include "window.h"
39 36
 
40
-#define MAX_DIGITS 7
41
-#define LINE_WIDTH 10
42
-
43
-// TODO inverted score color not visible on DMG
44
-// TODO 8x8 font only available on GBC
45
-
46 37
 BANKREF(window)
47 38
 
48
-const palette_color_t num_pal_inv[4] = {
49
-  //RGB8(  0,  0,  0), RGB8(248,252,248), RGB8(  0,  0,  0), RGB8(  0,  0,  0)
50
-    RGB8(  0,  0,  0), RGB8(  0,  0,  0), RGB8(248,252,248), RGB8(  0,  0,  0)
51
-};
52
-
53
-static uint8_t fnt_off = 0;
54
-
55
-void win_init(uint8_t is_splash) NONBANKED {
56
-    fnt_off = is_splash ? title_map_TILE_COUNT : bg_map_TILE_COUNT;
57
-
58
-    START_ROM_BANK(BANK(numbers_fnt16)) {
59
-        set_bkg_palette(OAMF_CGB_PAL0 + bg_map_PALETTE_COUNT,
60
-                        numbers_fnt16_PALETTE_COUNT, numbers_fnt16_palettes);
61
-        set_win_data(fnt_off, numbers_fnt16_TILE_COUNT, numbers_fnt16_tiles);
62
-    } END_ROM_BANK
63
-
64
-    START_ROM_BANK_2(BANK(window)) {
65
-        set_bkg_palette(OAMF_CGB_PAL0 + bg_map_PALETTE_COUNT + numbers_fnt16_PALETTE_COUNT,
66
-                        numbers_fnt16_PALETTE_COUNT, num_pal_inv);
67
-    } END_ROM_BANK
68
-
69
-    if (is_splash) {
70
-        START_ROM_BANK_2(BANK(text_fnt16)) {
71
-            set_win_data(fnt_off + numbers_fnt16_TILE_COUNT,
72
-                         text_fnt16_TILE_COUNT, text_fnt16_tiles);
73
-        } END_ROM_BANK
74
-
75
-        if (_cpu == CGB_TYPE) {
76
-            VBK_REG = VBK_BANK_1;
77
-            START_ROM_BANK_2(BANK(vincent_fnt8)) {
78
-                set_win_data(0, vincent_fnt8_TILE_COUNT, vincent_fnt8_tiles);
79
-                set_bkg_palette(OAMF_CGB_PAL0 + bg_map_PALETTE_COUNT + (2 * numbers_fnt16_PALETTE_COUNT),
80
-                                vincent_fnt8_PALETTE_COUNT, vincent_fnt8_palettes);
81
-            } END_ROM_BANK
82
-        }
83
-    }
84
-}
85
-
86
-static void set_win_based(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
87
-                          const uint8_t *tiles, uint8_t base_tile, uint8_t tile_bank,
88
-                          const uint8_t *attributes, uint8_t attr_bank) NONBANKED {
89
-    if (attributes != NULL) {
90
-        START_ROM_BANK(attr_bank) {
91
-            VBK_REG = VBK_ATTRIBUTES;
92
-            set_win_tiles(x, y, w, h, attributes);
93
-        } END_ROM_BANK
94
-    } else {
95
-        VBK_REG = VBK_ATTRIBUTES;
96
-        fill_win_rect(x, y, w, h, 0x00);
97
-    }
98
-
99
-    START_ROM_BANK(tile_bank) {
100
-        VBK_REG = VBK_TILES;
101
-        set_win_based_tiles(x, y, w, h, tiles, base_tile);
102
-    } END_ROM_BANK
103
-}
104
-
105
-static void set_win_based_attr(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
106
-                               const uint8_t *tiles, uint8_t base_tile, uint8_t tile_bank,
107
-                               const uint8_t attr) NONBANKED {
108
-    VBK_REG = VBK_ATTRIBUTES;
109
-    fill_win_rect(x, y, w, h, attr);
110
-
111
-    START_ROM_BANK(tile_bank) {
112
-        VBK_REG = VBK_TILES;
113
-        set_win_based_tiles(x, y, w, h, tiles, base_tile);
114
-    } END_ROM_BANK
115
-}
116
-
117
-static void character(uint8_t c, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
118
-    uint8_t off = c * text_fnt16_WIDTH / text_fnt16_TILE_W;
119
-
120
-    set_win_based_attr(x_off + (pos * text_fnt16_WIDTH / text_fnt16_TILE_W), y_off,
121
-                       text_fnt16_WIDTH / text_fnt16_TILE_W, 1,
122
-                       text_fnt16_map + off, fnt_off + numbers_fnt16_TILE_COUNT,
123
-                       BANK(text_fnt16), is_black ? 0x82 : 0x81);
124
-
125
-    set_win_based_attr(x_off + (pos * text_fnt16_WIDTH / text_fnt16_TILE_W), y_off + 1,
126
-                       text_fnt16_WIDTH / text_fnt16_TILE_W, 1,
127
-                       text_fnt16_map + off + (sizeof(text_fnt16_map) / 2), fnt_off + numbers_fnt16_TILE_COUNT,
128
-                       BANK(text_fnt16), is_black ? 0x82 : 0x81);
129
-}
130
-
131
-static void char_ascii(uint8_t c, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t light) {
132
-    set_win_based_attr(x_off + pos, y_off, 1, 1,
133
-                       vincent_fnt8_map + c, 0,
134
-                       BANK(vincent_fnt8), light ? 0x88 : 0x8B);
135
-}
136
-
137
-static void str3(uint16_t name, uint8_t x_off, uint8_t y_off,
138
-                 uint8_t is_black_a, uint8_t is_black_b, uint8_t is_black_c) {
139
-    character((name >> 10) & 0x1F, 0, x_off, y_off, is_black_a);
140
-    character((name >>  5) & 0x1F, 1, x_off, y_off, is_black_b);
141
-    character((name >>  0) & 0x1F, 2, x_off, y_off, is_black_c);
142
-}
143
-
144
-static void digit(uint8_t val, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
145
-    uint8_t off = val * numbers_fnt16_WIDTH / numbers_fnt16_TILE_W;
146
-
147
-    set_win_based_attr(x_off + (pos * numbers_fnt16_WIDTH / numbers_fnt16_TILE_W), y_off,
148
-                       numbers_fnt16_WIDTH / numbers_fnt16_TILE_W, 1,
149
-                       numbers_fnt16_map + off, fnt_off,
150
-                       BANK(numbers_fnt16), is_black ? 0x82 : 0x81);
151
-
152
-    set_win_based_attr(x_off + (pos * numbers_fnt16_WIDTH / numbers_fnt16_TILE_W), y_off + 1,
153
-                       numbers_fnt16_WIDTH / numbers_fnt16_TILE_W, 1,
154
-                       numbers_fnt16_map + off + (sizeof(numbers_fnt16_map) / 2), fnt_off,
155
-                       BANK(numbers_fnt16), is_black ? 0x82 : 0x81);
156
-}
157
-
158
-static void str_l(const char *s, uint8_t len, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
159
-    for (uint8_t n = 0; (*s) && (n < LINE_WIDTH) && (n < len); n++) {
160
-        char c = *(s++);
161
-        if ((c >= 'A') && (c <= 'Z')) {
162
-            c = c - 'A' + 'a';
163
-        }
164
-        if ((c >= '0') && (c <= '9')) {
165
-            digit(c - '0', n, x_off, y_off, is_black);
166
-        } else if ((c >= 'a') && (c <= 'z')) {
167
-            character(c - 'a', n, x_off, y_off, is_black);
168
-        }
169
-    }
170
-}
171
-
172
-static void str(const char *s, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
173
-    str_l(s, 0xFF, x_off, y_off, is_black);
174
-}
175
-
176
-static void str_ascii_l(const char *s, uint8_t len, uint8_t x_off, uint8_t y_off, uint8_t light) {
177
-    for (uint8_t n = 0; (*s) && (n < (2 * LINE_WIDTH)) && (n < len); n++) {
178
-        char c = *(s++);
179
-        char_ascii(c, n, x_off, y_off, light);
180
-    }
181
-}
182
-
183
-static void str_ascii(const char *s, uint8_t x_off, uint8_t y_off, uint8_t light) {
184
-    str_ascii_l(s, 0xFF, x_off, y_off, light);
185
-}
186
-
187
-static void str_center(const char *s, uint8_t y_off, uint8_t is_black) {
188
-    uint8_t n = strlen(s);
189
-    if (n > LINE_WIDTH) n = LINE_WIDTH;
190
-    str(s, LINE_WIDTH - n, y_off, is_black);
191
-}
192
-
193
-void win_str_center(const char *s, uint8_t y_off, uint8_t is_black) NONBANKED {
194
-    START_ROM_BANK(BANK(window)) {
195
-        str_center(s, y_off, is_black);
196
-    } END_ROM_BANK
197
-}
198
-
199
-static void str_lines(const char *s, uint8_t y_off, uint8_t is_black) {
200
-    if (strlen(s) > 10) {
201
-        str(s, 0, y_off, is_black);
202
-        str_center(s + 10, y_off + 2, is_black);
203
-    } else {
204
-        str_center(s, y_off, is_black);
205
-    }
206
-}
207
-
208
-static void str_ascii_lines(const char *s, uint8_t y_off, uint8_t light) {
209
-    const char *nl = s;
210
-    uint8_t lines = 0;
211
-    do {
212
-        // find next newline
213
-        while (*nl && (*nl != '\n')) nl++;
214
-        str_ascii_l(s, nl - s, 0, y_off + lines, light);
215
-        lines++;
216
-        if (*nl) nl++;
217
-        s = nl;
218
-    } while (*nl);
219
-}
220
-
221
-static uint8_t number(int32_t score, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
222
-    // TODO can not set numbers larger than int16 max?!
223
-    //score = 32767 + 1; // wtf?!
224
-
225
-    uint8_t len = 0;
226
-    uint8_t digits[MAX_DIGITS];
227
-    do {
228
-        digits[len++] = score % 10L;
229
-        score = score / 10L;
230
-        if (len >= MAX_DIGITS) {
231
-            break;
232
-        }
233
-    } while (score > 0);
234
-
235
-    // if the number was too large for our buffer don't draw anything
236
-    if (score > 0) {
237
-        return 0;
238
-    }
239
-
240
-    uint8_t off = (x_off == 0xFF) ? (LINE_WIDTH - len) : ((x_off == 0xFE) ? ((LINE_WIDTH * 2) - (len * 2)) : x_off);
241
-    for (uint8_t i = 0; i < len; i++) {
242
-        digit(digits[len - i - 1], i, off, y_off, is_black);
243
-    }
244
-
245
-    return 8 * len * 2;
246
-}
247
-
248 39
 static void fill_win(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t tile, uint8_t attr) {
249 40
     VBK_REG = VBK_ATTRIBUTES;
250 41
     fill_win_rect(x, y, w, h, attr);
@@ -253,17 +44,15 @@ static void fill_win(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t tile, u
253 44
 }
254 45
 
255 46
 void win_splash_draw(int32_t lowest, int32_t highest) BANKED {
256
-    set_win_based(0, 0,
257
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
258
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
47
+    map_fill(MAP_TITLE, 0);
259 48
 
260 49
     // only show on splash if they fit
261 50
     if ((lowest <= 99999) && (highest <= 99999)) {
262 51
         number(lowest, 0, DEVICE_SCREEN_HEIGHT - 4, 1);
263 52
         number(highest, 0xFE, DEVICE_SCREEN_HEIGHT - 4, 0);
264 53
 
265
-        str("top", 0, DEVICE_SCREEN_HEIGHT - 2, 1);
266
-        str("score", 10, DEVICE_SCREEN_HEIGHT - 2, 0);
54
+        str(get_string(STR_TOP), 0, DEVICE_SCREEN_HEIGHT - 2, 1);
55
+        str(get_string(STR_SCORE), 10, DEVICE_SCREEN_HEIGHT - 2, 0);
267 56
     }
268 57
 }
269 58
 
@@ -280,13 +69,11 @@ void win_score_clear(uint8_t is_black, uint8_t no_bg) BANKED {
280 69
     if (no_bg) {
281 70
         fill_win(0, 0, DEVICE_SCREEN_WIDTH, DEVICE_SCREEN_HEIGHT, 1, 0x00);
282 71
     } else {
283
-        set_win_based(0, 0,
284
-                      title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
285
-                      title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
72
+        map_fill(MAP_TITLE, 0);
286 73
     }
287 74
 
288 75
     if (is_black < 2) {
289
-        str_center(is_black ? "black" : "white", 1, is_black);
76
+        str_center(is_black ? get_string(STR_BLACK) : get_string(STR_WHITE), 1, is_black);
290 77
     }
291 78
 }
292 79
 
@@ -299,25 +86,25 @@ void win_score_print(enum PRN_STATUS status) BANKED {
299 86
     static char buff[128];
300 87
 
301 88
     if (_cpu == CGB_TYPE) {
302
-        str_ascii("GB Printer", 0, 0, 0);
303
-        str_ascii("Score Printout", 0, 1, 0);
304
-        str_ascii("Result:", 0, 3, 0);
89
+        str_ascii(get_string(STR_GB_PRINTER), 0, 0, 0);
90
+        str_ascii(get_string(STR_SCORE_PRINTOUT), 0, 1, 0);
91
+        str_ascii(get_string(STR_RESULT), 0, 3, 0);
305 92
 
306 93
         if (status == PRN_STATUS_OK) {
307
-            str_ascii("success", 0, 8, 0);
94
+            str_ascii(get_string(STR_SUCCESS), 0, 8, 0);
308 95
         } else {
309
-            sprintf(buff, "error: 0x%04x", (uint16_t)status);
96
+            sprintf(buff, get_string(STR_PRINTF_ERROR), (uint16_t)status);
310 97
             str_ascii(buff, 0, 5, 0);
311 98
 
312 99
             gbprinter_error(status, buff);
313 100
             str_ascii_lines(buff, 6, 0);
314 101
         }
315 102
     } else {
316
-        str("printout", 0, 4, 0);
103
+        str(get_string(STR_PRINTOUT), 0, 4, 0);
317 104
         if (status == PRN_STATUS_OK) {
318
-            str("success", 0, 8, 0);
105
+            str(get_string(STR_SUCCESS), 0, 8, 0);
319 106
         } else {
320
-            str("error", 0, 8, 1);
107
+            str(get_string(STR_ERROR), 0, 8, 1);
321 108
             number(status, 11, 8, 1);
322 109
         }
323 110
     }
@@ -325,42 +112,47 @@ void win_score_print(enum PRN_STATUS status) BANKED {
325 112
 
326 113
 static void get_git(char *line_buff) NONBANKED {
327 114
     START_ROM_BANK(BANK(git)) {
328
-        strncpy(line_buff, git_version, 2 * LINE_WIDTH);
115
+        strncpy(line_buff, git_version, 2 * TEXT_LINE_WIDTH);
116
+    } END_ROM_BANK
117
+}
118
+
119
+void win_str_center(const char *s, uint8_t y_off, uint8_t is_black) NONBANKED {
120
+    START_ROM_BANK(BANK(text)) {
121
+        str_center(s, y_off, is_black);
329 122
     } END_ROM_BANK
330 123
 }
331 124
 
332 125
 void win_about(void) BANKED {
333
-    set_win_based(0, 0,
334
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
335
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
126
+    map_fill(MAP_TITLE, 0);
336 127
 
337
-    str_center("Duality", 0, 1);
338
-    str_center("xythobuz", 2, 1);
128
+    str_center(get_string(STR_DUALITY), 0, 1);
129
+    str_center(get_string(STR_XYTHOBUZ), 2, 1);
339 130
 
340
-    char line_buff[2 * LINE_WIDTH + 1] = {0};
131
+    char line_buff[2 * TEXT_LINE_WIDTH + 1] = {0};
341 132
     get_git(line_buff);
342 133
 
343 134
     if (_cpu == CGB_TYPE) {
344
-        str_ascii("Git Commit Hash:", 0, 6, 0);
135
+        str_ascii(get_string(STR_GIT), 0, 6, 0);
345 136
         str_ascii(line_buff, 0, 7, 0);
346 137
 
347
-        str_ascii("Build Date:", 0, 10, 0);
348
-        str_ascii(__DATE__, 0, 11, 0);
349
-        str_ascii(__TIME__, 0, 12, 0);
138
+        str_ascii(get_string(STR_BUILD_DATE), 0, 10, 0);
139
+        str_ascii(get_string(STR_DATE), 0, 11, 0);
140
+        str_ascii(get_string(STR_TIME), 0, 12, 0);
350 141
 
351
-        str_ascii("MP Tx:", 14, 11, 1);
352
-        str_ascii("Wait", 14, 12, 1);
142
+        str_ascii(get_string(STR_MP_TX), 14, 11, 1);
143
+        str_ascii(get_string(STR_WAIT), 14, 12, 1);
353 144
 
354
-        str_ascii("Visit:", 0, 15, 0);
355
-        str_ascii("https://xythobuz.de", 0, 16, 0);
145
+        str_ascii(get_string(STR_VISIT), 0, 15, 0);
146
+        str_ascii(get_string(STR_URL), 0, 16, 0);
356 147
     } else {
357 148
         str_lines(line_buff, 7, 0);
358 149
 
359
-        str_l(&__DATE__[7], 4,           0, 14, 1); // year (4)
360
-        str_l(&__DATE__[0], 3, (4 * 2) + 1, 14, 1); // month (3)
361
-        str_l(&__DATE__[4], 2, (7 * 2) + 2, 14, 1); // day (2)
150
+        const char *date = get_string(STR_DATE);
151
+        str_l(&date[7], 4,           0, 14, 1); // year (4)
152
+        str_l(&date[0], 3, (4 * 2) + 1, 14, 1); // month (3)
153
+        str_l(&date[4], 2, (7 * 2) + 2, 14, 1); // day (2)
362 154
 
363
-        str(__TIME__, 4, 16, 0);
155
+        str(get_string(STR_TIME), 4, 16, 0);
364 156
     }
365 157
 }
366 158
 
@@ -396,19 +188,17 @@ static uint8_t get_debug(char *name_buff, uint8_t i) NONBANKED {
396 188
 }
397 189
 
398 190
 void win_debug(void) BANKED {
399
-    set_win_based(0, 0,
400
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
401
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
191
+    map_fill(MAP_TITLE, 0);
402 192
 
403 193
     // TODO prettier pagination
404 194
     uint8_t off = (10 - (DEBUG_ENTRY_COUNT - debug_menu_index)) / 2;
405 195
 
406
-    str_center("Debug Menu", 0, 0);
196
+    str_center(get_string(STR_DEBUG_MENU), 0, 0);
407 197
 
408 198
     for (uint8_t i = debug_menu_index; (i < DEBUG_ENTRY_COUNT) && (i < (7 + debug_menu_index)); i++) {
409 199
         char name_buff[ENTRY_NAME_LEN + 2 + 1] = {0};
410 200
         uint8_t n_len = get_debug(name_buff, i);
411
-        str(name_buff, (LINE_WIDTH - n_len) * 2, ((i - debug_menu_index) * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
201
+        str(name_buff, (TEXT_LINE_WIDTH - n_len) * 2, ((i - debug_menu_index) * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
412 202
     }
413 203
 }
414 204
 
@@ -431,46 +221,42 @@ static uint8_t get_conf(char *name_buff, uint8_t i) NONBANKED {
431 221
 }
432 222
 
433 223
 void win_conf(void) BANKED {
434
-    set_win_based(0, 0,
435
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
436
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
224
+    map_fill(MAP_TITLE, 0);
437 225
 
438 226
     // TODO paging when more options added
439 227
     static_assert(CONF_ENTRY_COUNT <= 7, "too many conf menu entries");
440 228
     uint8_t off = (10 - CONF_ENTRY_COUNT) / 2;
441 229
 
442
-    str_center("Conf Menu", 0, 0);
230
+    str_center(get_string(STR_CONF_MENU), 0, 0);
443 231
 
444 232
     for (uint8_t i = 0; (i < CONF_ENTRY_COUNT) && (i < 7); i++) {
445 233
         char name_buff[ENTRY_NAME_LEN + 2 + 1] = {0};
446 234
         uint8_t n_len = get_conf(name_buff, i);
447
-        str(name_buff, (LINE_WIDTH - n_len) * 2, (i * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
235
+        str(name_buff, (TEXT_LINE_WIDTH - n_len) * 2, (i * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
448 236
     }
449 237
 }
450 238
 
451 239
 void win_name(int32_t score) BANKED {
452
-    set_win_based(0, 0,
453
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
454
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
240
+    map_fill(MAP_TITLE, 0);
455 241
 
456
-    str_center("score", 1, score < 0);
242
+    str_center(get_string(STR_SCORE), 1, score < 0);
457 243
     number(score < 0 ? -score : score, 0xFF, 3, score < 0);
458 244
 
459
-    str_center("enter", 6, score < 0);
460
-    str_center("name", 8, score < 0);
245
+    str_center(get_string(STR_ENTER), 6, score < 0);
246
+    str_center(get_string(STR_NAME), 8, score < 0);
461 247
 
462
-    str_center("start ok", 16, score < 0);
248
+    str_center(get_string(STR_START_OK), 16, score < 0);
463 249
 }
464 250
 
465 251
 void win_name_draw(uint16_t name, uint8_t is_black, uint8_t pos) BANKED {
466
-    str3(name, LINE_WIDTH - 3, 12,
252
+    str3(name, TEXT_LINE_WIDTH - 3, 12,
467 253
          (pos == 0) ? !is_black : is_black,
468 254
          (pos == 1) ? !is_black : is_black,
469 255
          (pos == 2) ? !is_black : is_black);
470 256
 }
471 257
 
472 258
 uint8_t win_game_draw(int32_t score) BANKED {
473
-    fill_win(0, 0, 10, 2, fnt_off + numbers_fnt16_TILE_COUNT, 0x81);
259
+    fill_win(0, 0, 10, 2, maps[FNT_ASCII_8].tile_offset, 0x81);
474 260
 
475 261
     uint8_t is_black = 0;
476 262
     if (score < 0) {

+ 0
- 1
src/window.h View File

@@ -26,7 +26,6 @@
26 26
 #include "score.h"
27 27
 #include "gbprinter.h"
28 28
 
29
-void win_init(uint8_t is_splash);
30 29
 void win_splash_draw(int32_t lowest, int32_t highest) BANKED;
31 30
 void win_splash_mp(void) BANKED;
32 31
 void win_score_clear(uint8_t is_black, uint8_t no_bg) BANKED;

Loading…
Cancel
Save