Browse Source

remove small status sprites again, split map and window code

Thomas B 1 month ago
parent
commit
bea63ed2e7
11 changed files with 414 additions and 384 deletions
  1. BIN
      data/status_spr8.png
  2. 2
    0
      src/banks.h
  3. 2
    3
      src/game.c
  4. 1
    0
      src/main.c
  5. 0
    331
      src/maps.c
  6. 0
    16
      src/maps.h
  7. 12
    9
      src/obj.c
  8. 0
    23
      src/sprite_data.c
  9. 0
    2
      src/sprites.h
  10. 357
    0
      src/window.c
  11. 40
    0
      src/window.h

BIN
data/status_spr8.png View File


+ 2
- 0
src/banks.h View File

@@ -20,6 +20,8 @@
20 20
 #ifndef __BANKS_H__
21 21
 #define __BANKS_H__
22 22
 
23
+#include <gbdk/platform.h>
24
+
23 25
 #define START_ROM_BANK_2(x) __previous__bank = CURRENT_BANK; SWITCH_ROM(x)
24 26
 #define START_ROM_BANK(x) uint8_t START_ROM_BANK_2(x)
25 27
 #define END_ROM_BANK() SWITCH_ROM(__previous__bank)

+ 2
- 3
src/game.c View File

@@ -30,6 +30,7 @@
30 30
 #include "input.h"
31 31
 #include "main.h"
32 32
 #include "sample.h"
33
+#include "window.h"
33 34
 #include "game.h"
34 35
 
35 36
 #define BAR_OFFSET_X (4 - 80)
@@ -120,9 +121,6 @@ static void status(uint8_t health, uint8_t power, uint8_t *hiwater) NONBANKED {
120 121
                          ((power >> 6) == 0) ? 7 - ((power >> 3) & 7) : 0, hiwater);
121 122
         }
122 123
     }
123
-
124
-    spr_draw(SPR_STATUS_HEALTH, FLIP_NONE, BAR_OFFSET_X, HEALTH_OFFSET_Y - 24 - 9, 0, hiwater);
125
-    spr_draw(SPR_STATUS_POWER, FLIP_NONE, BAR_OFFSET_X, POWER_OFFSET_Y + 0 - 9, 1, hiwater);
126 124
 }
127 125
 
128 126
 static void show_explosion(uint16_t power) NONBANKED {
@@ -132,6 +130,7 @@ static void show_explosion(uint16_t power) NONBANKED {
132 130
 
133 131
     for (uint8_t n = 0; n < (4 * 4 * 4); n++) {
134 132
         uint8_t hiwater = SPR_NUM_START;
133
+        status(0, power, &hiwater);
135 134
         if (n < (4 * 4)) {
136 135
             spr_draw(SPR_EXPL, FLIP_NONE, 0, 0, n >> 2, &hiwater);
137 136
         }

+ 1
- 0
src/main.c View File

@@ -37,6 +37,7 @@
37 37
 #include "border_sgb.h"
38 38
 #include "timer.h"
39 39
 #include "sample.h"
40
+#include "window.h"
40 41
 #include "main.h"
41 42
 
42 43
 uint8_t debug_menu_index = 0;

+ 0
- 331
src/maps.c View File

@@ -17,52 +17,11 @@
17 17
  * See <http://www.gnu.org/licenses/>.
18 18
  */
19 19
 
20
-#include <gbdk/platform.h>
21
-#include <string.h>
22
-
23 20
 #include "banks.h"
24
-#include "config.h"
25
-#include "score.h"
26 21
 #include "title_map.h"
27 22
 #include "bg_map.h"
28
-#include "numbers_fnt.h"
29
-#include "text_fnt.h"
30
-#include "git.h"
31
-#include "main.h"
32 23
 #include "maps.h"
33 24
 
34
-#define MAX_DIGITS 7
35
-#define LINE_WIDTH 10
36
-
37
-// TODO inverted score color not visible on DMG
38
-
39
-BANKREF(maps)
40
-
41
-const unsigned char num_attr_1[104] = {
42
-    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
43
-    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
44
-    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
45
-    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
46
-    0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,
47
-    0x81,0x81,0x81,0x81,
48
-};
49
-
50
-const unsigned char num_attr_2[104] = {
51
-    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
52
-    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
53
-    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
54
-    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
55
-    0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,
56
-    0x82,0x82,0x82,0x82,
57
-};
58
-
59
-const palette_color_t num_pal_inv[4] = {
60
-  //RGB8(  0,  0,  0), RGB8(248,252,248), RGB8(  0,  0,  0), RGB8(  0,  0,  0)
61
-    RGB8(  0,  0,  0), RGB8(  0,  0,  0), RGB8(248,252,248), RGB8(  0,  0,  0)
62
-};
63
-
64
-static uint8_t fnt_off = 0;
65
-
66 25
 void map_title(void) NONBANKED {
67 26
     START_ROM_BANK(BANK(title_map));
68 27
         set_bkg_palette(OAMF_CGB_PAL0, title_map_PALETTE_COUNT, title_map_palettes);
@@ -100,293 +59,3 @@ void map_game(void) NONBANKED {
100 59
         set_bkg_tiles(0, 0, bg_map_WIDTH / bg_map_TILE_W, bg_map_HEIGHT / bg_map_TILE_H, bg_map_map);
101 60
     END_ROM_BANK();
102 61
 }
103
-
104
-void win_init(uint8_t is_splash) NONBANKED {
105
-    fnt_off = is_splash ? title_map_TILE_COUNT : bg_map_TILE_COUNT;
106
-
107
-    START_ROM_BANK(BANK(numbers_fnt));
108
-        set_bkg_palette(OAMF_CGB_PAL0 + bg_map_PALETTE_COUNT, numbers_fnt_PALETTE_COUNT, numbers_fnt_palettes);
109
-        set_win_data(fnt_off, numbers_fnt_TILE_COUNT, numbers_fnt_tiles);
110
-    END_ROM_BANK();
111
-
112
-    START_ROM_BANK_2(BANK(maps));
113
-        set_bkg_palette(OAMF_CGB_PAL0 + bg_map_PALETTE_COUNT + numbers_fnt_PALETTE_COUNT, numbers_fnt_PALETTE_COUNT, num_pal_inv);
114
-    END_ROM_BANK();
115
-
116
-    if (is_splash) {
117
-        START_ROM_BANK_2(BANK(text_fnt));
118
-            set_win_data(fnt_off + numbers_fnt_TILE_COUNT, text_fnt_TILE_COUNT, text_fnt_tiles);
119
-        END_ROM_BANK();
120
-    }
121
-}
122
-
123
-static void set_win_based(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
124
-                          const uint8_t *tiles, uint8_t base_tile, uint8_t tile_bank,
125
-                          const uint8_t *attributes, uint8_t attr_bank) NONBANKED {
126
-    if (attributes != NULL) {
127
-        START_ROM_BANK(attr_bank);
128
-            VBK_REG = VBK_ATTRIBUTES;
129
-            set_win_tiles(x, y, w, h, attributes);
130
-        END_ROM_BANK();
131
-    } else {
132
-        VBK_REG = VBK_ATTRIBUTES;
133
-        fill_win_rect(x, y, w, h, 0x00);
134
-    }
135
-
136
-    START_ROM_BANK(tile_bank);
137
-        VBK_REG = VBK_TILES;
138
-        set_win_based_tiles(x, y, w, h, tiles, base_tile);
139
-    END_ROM_BANK();
140
-}
141
-
142
-static void character(uint8_t c, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black) NONBANKED {
143
-    uint8_t off = c * text_fnt_WIDTH / text_fnt_TILE_W;
144
-
145
-    set_win_based(x_off + (pos * text_fnt_WIDTH / text_fnt_TILE_W), y_off,
146
-                  text_fnt_WIDTH / text_fnt_TILE_W, 1,
147
-                  text_fnt_map + off, fnt_off + numbers_fnt_TILE_COUNT, BANK(text_fnt),
148
-                  (is_black ? num_attr_2 : num_attr_1) + off, BANK(maps));
149
-
150
-    set_win_based(x_off + (pos * text_fnt_WIDTH / text_fnt_TILE_W), y_off + 1,
151
-                  text_fnt_WIDTH / text_fnt_TILE_W, 1,
152
-                  text_fnt_map + off + (sizeof(text_fnt_map) / 2), fnt_off + numbers_fnt_TILE_COUNT, BANK(text_fnt),
153
-                  (is_black ? num_attr_2 : num_attr_1) + off, BANK(maps));
154
-}
155
-
156
-static void str3(uint16_t name, uint8_t x_off, uint8_t y_off,
157
-                 uint8_t is_black_a, uint8_t is_black_b, uint8_t is_black_c) NONBANKED {
158
-    character((name >> 10) & 0x1F, 0, x_off, y_off, is_black_a);
159
-    character((name >>  5) & 0x1F, 1, x_off, y_off, is_black_b);
160
-    character((name >>  0) & 0x1F, 2, x_off, y_off, is_black_c);
161
-}
162
-
163
-static void digit(uint8_t val, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black) NONBANKED {
164
-    uint8_t off = val * numbers_fnt_WIDTH / numbers_fnt_TILE_W;
165
-
166
-    set_win_based(x_off + (pos * numbers_fnt_WIDTH / numbers_fnt_TILE_W), y_off,
167
-                  numbers_fnt_WIDTH / numbers_fnt_TILE_W, 1,
168
-                  numbers_fnt_map + off, fnt_off, BANK(numbers_fnt),
169
-                  (is_black ? num_attr_2 : num_attr_1) + off, BANK(maps));
170
-
171
-    set_win_based(x_off + (pos * numbers_fnt_WIDTH / numbers_fnt_TILE_W), y_off + 1,
172
-                  numbers_fnt_WIDTH / numbers_fnt_TILE_W, 1,
173
-                  numbers_fnt_map + off + (sizeof(numbers_fnt_map) / 2), fnt_off, BANK(numbers_fnt),
174
-                  (is_black ? num_attr_2 : num_attr_1) + off, BANK(maps));
175
-}
176
-
177
-static void str_l(const char *s, uint8_t len, uint8_t x_off, uint8_t y_off, uint8_t is_black) NONBANKED {
178
-    for (uint8_t n = 0; (*s) && (n < LINE_WIDTH) && (n < len); n++) {
179
-        char c = *(s++);
180
-        if ((c >= 'A') && (c <= 'Z')) {
181
-            c = c - 'A' + 'a';
182
-        }
183
-        if ((c >= '0') && (c <= '9')) {
184
-            digit(c - '0', n, x_off, y_off, is_black);
185
-        } else if ((c >= 'a') && (c <= 'z')) {
186
-            character(c - 'a', n, x_off, y_off, is_black);
187
-        }
188
-    }
189
-}
190
-
191
-static void str(const char *s, uint8_t x_off, uint8_t y_off, uint8_t is_black) NONBANKED {
192
-    str_l(s, 0xFF, x_off, y_off, is_black);
193
-}
194
-
195
-static void str_center(const char *s, uint8_t y_off, uint8_t is_black) NONBANKED {
196
-    uint8_t n = strlen(s);
197
-    if (n > LINE_WIDTH) n = LINE_WIDTH;
198
-    str(s, LINE_WIDTH - n, y_off, is_black);
199
-}
200
-
201
-static void str_lines(const char *s, uint8_t y_off, uint8_t is_black) NONBANKED {
202
-    if (strlen(s) > 10) {
203
-        str(s, 0, y_off, is_black);
204
-        str_center(s + 10, y_off + 2, is_black);
205
-    } else {
206
-        str_center(s, y_off, is_black);
207
-    }
208
-}
209
-
210
-static uint8_t number(int32_t score, uint8_t x_off, uint8_t y_off, uint8_t is_black) NONBANKED {
211
-    // TODO can not set numbers larger than int16 max?!
212
-    //score = 32767 + 1; // wtf?!
213
-
214
-    uint8_t len = 0;
215
-    uint8_t digits[MAX_DIGITS];
216
-    do {
217
-        digits[len++] = score % 10L;
218
-        score = score / 10L;
219
-        if (len >= MAX_DIGITS) {
220
-            break;
221
-        }
222
-    } while (score > 0);
223
-
224
-    // if the number was too large for our buffer don't draw anything
225
-    if (score > 0) {
226
-        return 0;
227
-    }
228
-
229
-    uint8_t off = (x_off == 0xFF) ? (LINE_WIDTH - len) : ((x_off == 0xFE) ? ((LINE_WIDTH * 2) - (len * 2)) : x_off);
230
-    for (uint8_t i = 0; i < len; i++) {
231
-        digit(digits[len - i - 1], i, off, y_off, is_black);
232
-    }
233
-
234
-    return 8 * len * 2;
235
-}
236
-
237
-static void fill_win(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t tile, uint8_t attr) NONBANKED {
238
-    VBK_REG = VBK_ATTRIBUTES;
239
-    fill_win_rect(x, y, w, h, attr);
240
-    VBK_REG = VBK_TILES;
241
-    fill_win_rect(x, y, w, h, tile);
242
-}
243
-
244
-void win_splash_draw(int32_t lowest, int32_t highest) NONBANKED {
245
-    // reuse full black and white tiles at 0 and 1 from splash bg
246
-    fill_win(0, 0, 10, 4, 0, 0x00);
247
-    fill_win(10, 0, 10, 4, 1, 0x00);
248
-
249
-    // only show on splash if they fit
250
-    if ((lowest <= 99999) && (highest <= 99999)) {
251
-        number(lowest, 0, 0, 1);
252
-        number(highest, 0xFE, 0, 0);
253
-
254
-        str("top", 0, 2, 1);
255
-        str("score", 10, 2, 0);
256
-    }
257
-}
258
-
259
-void win_score_clear(uint8_t is_black) NONBANKED {
260
-    set_win_based(0, 0,
261
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
262
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
263
-
264
-    str_center(is_black ? "black" : "white", 1, is_black);
265
-}
266
-
267
-void win_score_draw(struct scores score, uint8_t off, uint8_t is_black) NONBANKED {
268
-    str3(score.name, 0, 4 + off * 3, is_black, is_black, is_black);
269
-    number(is_black ? -score.score : score.score, 7, 4 + off * 3, is_black);
270
-}
271
-
272
-void win_about(void) NONBANKED {
273
-    set_win_based(0, 0,
274
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
275
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
276
-
277
-    str_center("Duality", 0, 1);
278
-    str_center("xythobuz", 2, 1);
279
-
280
-    char line_buff[2 * LINE_WIDTH + 1] = {0};
281
-
282
-    START_ROM_BANK(BANK(git));
283
-        strncpy(line_buff, git_version, 2 * LINE_WIDTH);
284
-    END_ROM_BANK();
285
-
286
-    str_lines(line_buff, 7, 0);
287
-
288
-    str_l(&__DATE__[7], 4,           0, 14, 1); // year (4)
289
-    str_l(&__DATE__[0], 3, (4 * 2) + 1, 14, 1); // month (3)
290
-    str_l(&__DATE__[4], 2, (7 * 2) + 2, 14, 1); // day (2)
291
-
292
-    str(__TIME__, 4, 16, 0);
293
-}
294
-
295
-void win_debug(void) NONBANKED {
296
-    set_win_based(0, 0,
297
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
298
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
299
-
300
-    // TODO paging when more options added
301
-    uint8_t off = (10 - DEBUG_ENTRY_COUNT) / 2;
302
-
303
-    str_center("Debug Menu", 0, 0);
304
-
305
-    for (uint8_t i = 0; (i < DEBUG_ENTRY_COUNT) && (i < 7); i++) {
306
-        char name_buff[ENTRY_NAME_LEN + 2 + 1] = {0};
307
-
308
-        START_ROM_BANK(BANK(main));
309
-            strncpy(name_buff, debug_entries[i].name, ENTRY_NAME_LEN + 1);
310
-
311
-            uint8_t n_len = strlen(name_buff);
312
-            name_buff[n_len] = ' ';
313
-            if (debug_entries[i].flag == DBG_NONE) {
314
-                if (debug_menu_index == i) {
315
-                    name_buff[n_len + 1] = debug_special_value + '0';
316
-                } else {
317
-                    name_buff[n_len + 1] = '0';
318
-                }
319
-            } else {
320
-                name_buff[n_len + 1] = (conf_get()->debug_flags & debug_entries[i].flag) ? '1' : '0';
321
-            }
322
-            name_buff[n_len + 2] = '\0';
323
-            n_len += 2;
324
-        END_ROM_BANK();
325
-
326
-        str(name_buff, (LINE_WIDTH - n_len) * 2, (i * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
327
-    }
328
-}
329
-
330
-void win_conf(void) NONBANKED {
331
-    set_win_based(0, 0,
332
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
333
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
334
-
335
-    // TODO paging when more options added
336
-    uint8_t off = (10 - CONF_ENTRY_COUNT) / 2;
337
-
338
-    str_center("Conf Menu", 0, 0);
339
-
340
-    for (uint8_t i = 0; (i < CONF_ENTRY_COUNT) && (i < 7); i++) {
341
-        char name_buff[ENTRY_NAME_LEN + 2 + 1] = {0};
342
-
343
-        START_ROM_BANK(BANK(main));
344
-            strncpy(name_buff, conf_entries[i].name, ENTRY_NAME_LEN + 1);
345
-
346
-            uint8_t n_len = strlen(name_buff);
347
-            name_buff[n_len] = ' ';
348
-            if (*conf_entries[i].var < 10) {
349
-                name_buff[n_len + 1] = *conf_entries[i].var + '0';
350
-            } else {
351
-                name_buff[n_len + 1] = *conf_entries[i].var - 10 + 'A';
352
-            }
353
-            name_buff[n_len + 2] = '\0';
354
-            n_len += 2;
355
-        END_ROM_BANK();
356
-
357
-        str(name_buff, (LINE_WIDTH - n_len) * 2, (i * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
358
-    }
359
-}
360
-
361
-void win_name(int32_t score) NONBANKED {
362
-    set_win_based(0, 0,
363
-                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
364
-                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
365
-
366
-    str_center("score", 1, score < 0);
367
-    number(score < 0 ? -score : score, 0xFF, 3, score < 0);
368
-
369
-    str_center("enter", 6, score < 0);
370
-    str_center("name", 8, score < 0);
371
-
372
-    str_center("start ok", 16, score < 0);
373
-}
374
-
375
-void win_name_draw(uint16_t name, uint8_t is_black, uint8_t pos) NONBANKED {
376
-    str3(name, LINE_WIDTH - 3, 12,
377
-         (pos == 0) ? !is_black : is_black,
378
-         (pos == 1) ? !is_black : is_black,
379
-         (pos == 2) ? !is_black : is_black);
380
-}
381
-
382
-uint8_t win_game_draw(int32_t score) NONBANKED {
383
-    fill_win(0, 0, 10, 2, fnt_off + numbers_fnt_TILE_COUNT, 0x81);
384
-
385
-    uint8_t is_black = 0;
386
-    if (score < 0) {
387
-        score = -score;
388
-        is_black = 1;
389
-    }
390
-
391
-    return number(score, 0, 0, is_black);
392
-}

+ 0
- 16
src/maps.h View File

@@ -20,23 +20,7 @@
20 20
 #ifndef __MAPS_H__
21 21
 #define __MAPS_H__
22 22
 
23
-#include <stdint.h>
24
-#include "score.h"
25
-
26 23
 void map_title(void);
27 24
 void map_game(void);
28 25
 
29
-void win_init(uint8_t is_splash);
30
-void win_splash_draw(int32_t lowest, int32_t highest);
31
-void win_score_clear(uint8_t is_black);
32
-void win_score_draw(struct scores score, uint8_t off, uint8_t is_black);
33
-void win_about(void);
34
-void win_conf(void);
35
-void win_debug(void);
36
-void win_name(int32_t score);
37
-void win_name_draw(uint16_t name, uint8_t is_black, uint8_t pos);
38
-uint8_t win_game_draw(int32_t score);
39
-
40
-BANKREF_EXTERN(maps)
41
-
42 26
 #endif // __MAPS_H__

+ 12
- 9
src/obj.c View File

@@ -32,23 +32,26 @@
32 32
  *
33 33
  * fixed:
34 34
  * status bars: 8
35
- * ship: 5
36
- * thruster: 1
37
- * --> 14 fixed
35
+ * ship + thruster: 7
36
+ * --> 15 fixed
38 37
  *
39
- * hardware tiles: 40 - 14 = 26
38
+ * hardware tiles: 40 - 15 = 25
40 39
  *
41 40
  * dynamic:
42
- * shot: 1
41
+ * shot / small: 1
42
+ * expl: 4
43 43
  * light: 4
44 44
  * dark: 4
45
- * --> 2x dark & 2x light = 16
46
- * --> 5x shot & 4x small = 9
47
- * --> 16 + 9 = 25
45
+ * --> 2x dark & 2x light & 1x expl = 20
46
+ * --> 2x shot & 4x small = 6
47
+ * --> 20 + 6 = 26
48
+ *
49
+ * TODO we will sometimes have glitches
50
+ * 1 sprite tile too much
48 51
  */
49 52
 #define MAX_DARK 2
50 53
 #define MAX_LIGHT 2
51
-#define MAX_SHOT 2 //5 /* TODO !! */
54
+#define MAX_SHOT 2
52 55
 #define MAX_SHOT_DARK 2
53 56
 #define MAX_SHOT_LIGHT 2
54 57
 #define MAX_OBJ ((4 * MAX_DARK) + (4 * MAX_LIGHT) + MAX_SHOT + MAX_SHOT_DARK + MAX_SHOT_LIGHT)

+ 0
- 23
src/sprite_data.c View File

@@ -29,7 +29,6 @@
29 29
 #include "bar_spr8.h"
30 30
 #include "expl_spr16.h"
31 31
 #include "pause.h"
32
-#include "status_spr8.h"
33 32
 #include "debug_marker.h"
34 33
 #include "debug_marker_spr32.h"
35 34
 
@@ -165,28 +164,6 @@ struct sprites metasprites[SPRITE_COUNT] = {
165 164
         .off = TILE_NUM_START,
166 165
         .bank = BANK(pause),
167 166
     },
168
-    { // SPR_STATUS_HEALTH
169
-        .ms = status_spr8_metasprites,
170
-        .ms_n = ARR_LEN(status_spr8_metasprites),
171
-        .ti = status_spr8_tiles,
172
-        .pa = NULL,
173
-        .pa_n = status_spr8_PALETTE_COUNT,
174
-        .pa_i = OAMF_CGB_PAL5,
175
-        .cnt = status_spr8_TILE_COUNT,
176
-        .off = TILE_NUM_START,
177
-        .bank = BANK(status_spr8),
178
-    },
179
-    { // SPR_STATUS_POWER
180
-        .ms = status_spr8_metasprites,
181
-        .ms_n = ARR_LEN(status_spr8_metasprites),
182
-        .ti = status_spr8_tiles,
183
-        .pa = NULL,
184
-        .pa_n = status_spr8_PALETTE_COUNT,
185
-        .pa_i = OAMF_CGB_PAL6,
186
-        .cnt = status_spr8_TILE_COUNT,
187
-        .off = SPR_STATUS_HEALTH,
188
-        .bank = BANK(status_spr8),
189
-    },
190 167
     { // SPR_DEBUG
191 168
         .ms = debug_marker_metasprites,
192 169
         .ms_n = ARR_LEN(debug_marker_metasprites),

+ 0
- 2
src/sprites.h View File

@@ -36,8 +36,6 @@ enum SPRITES {
36 36
     SPR_POWER,
37 37
     SPR_EXPL,
38 38
     SPR_PAUSE,
39
-    SPR_STATUS_HEALTH,
40
-    SPR_STATUS_POWER,
41 39
     SPR_DEBUG,
42 40
     SPR_DEBUG_LARGE,
43 41
 

+ 357
- 0
src/window.c View File

@@ -0,0 +1,357 @@
1
+/*
2
+ * window.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
+
23
+#include "banks.h"
24
+#include "config.h"
25
+#include "score.h"
26
+#include "title_map.h"
27
+#include "bg_map.h"
28
+#include "numbers_fnt.h"
29
+#include "text_fnt.h"
30
+#include "git.h"
31
+#include "main.h"
32
+#include "window.h"
33
+
34
+#define MAX_DIGITS 7
35
+#define LINE_WIDTH 10
36
+
37
+// TODO inverted score color not visible on DMG
38
+
39
+BANKREF(window)
40
+
41
+const palette_color_t num_pal_inv[4] = {
42
+  //RGB8(  0,  0,  0), RGB8(248,252,248), RGB8(  0,  0,  0), RGB8(  0,  0,  0)
43
+    RGB8(  0,  0,  0), RGB8(  0,  0,  0), RGB8(248,252,248), RGB8(  0,  0,  0)
44
+};
45
+
46
+static uint8_t fnt_off = 0;
47
+
48
+void win_init(uint8_t is_splash) NONBANKED {
49
+    fnt_off = is_splash ? title_map_TILE_COUNT : bg_map_TILE_COUNT;
50
+
51
+    START_ROM_BANK(BANK(numbers_fnt));
52
+        set_bkg_palette(OAMF_CGB_PAL0 + bg_map_PALETTE_COUNT, numbers_fnt_PALETTE_COUNT, numbers_fnt_palettes);
53
+        set_win_data(fnt_off, numbers_fnt_TILE_COUNT, numbers_fnt_tiles);
54
+    END_ROM_BANK();
55
+
56
+    START_ROM_BANK_2(BANK(window));
57
+        set_bkg_palette(OAMF_CGB_PAL0 + bg_map_PALETTE_COUNT + numbers_fnt_PALETTE_COUNT, numbers_fnt_PALETTE_COUNT, num_pal_inv);
58
+    END_ROM_BANK();
59
+
60
+    if (is_splash) {
61
+        START_ROM_BANK_2(BANK(text_fnt));
62
+            set_win_data(fnt_off + numbers_fnt_TILE_COUNT, text_fnt_TILE_COUNT, text_fnt_tiles);
63
+        END_ROM_BANK();
64
+    }
65
+}
66
+
67
+static void set_win_based(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
68
+                          const uint8_t *tiles, uint8_t base_tile, uint8_t tile_bank,
69
+                          const uint8_t *attributes, uint8_t attr_bank) NONBANKED {
70
+    if (attributes != NULL) {
71
+        START_ROM_BANK(attr_bank);
72
+            VBK_REG = VBK_ATTRIBUTES;
73
+            set_win_tiles(x, y, w, h, attributes);
74
+        END_ROM_BANK();
75
+    } else {
76
+        VBK_REG = VBK_ATTRIBUTES;
77
+        fill_win_rect(x, y, w, h, 0x00);
78
+    }
79
+
80
+    START_ROM_BANK(tile_bank);
81
+        VBK_REG = VBK_TILES;
82
+        set_win_based_tiles(x, y, w, h, tiles, base_tile);
83
+    END_ROM_BANK();
84
+}
85
+
86
+static void set_win_based_attr(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 attr) NONBANKED {
89
+    VBK_REG = VBK_ATTRIBUTES;
90
+    fill_win_rect(x, y, w, h, attr);
91
+
92
+    START_ROM_BANK(tile_bank);
93
+        VBK_REG = VBK_TILES;
94
+        set_win_based_tiles(x, y, w, h, tiles, base_tile);
95
+    END_ROM_BANK();
96
+}
97
+
98
+static void character(uint8_t c, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
99
+    uint8_t off = c * text_fnt_WIDTH / text_fnt_TILE_W;
100
+
101
+    set_win_based_attr(x_off + (pos * text_fnt_WIDTH / text_fnt_TILE_W), y_off,
102
+                       text_fnt_WIDTH / text_fnt_TILE_W, 1,
103
+                       text_fnt_map + off, fnt_off + numbers_fnt_TILE_COUNT,
104
+                       BANK(text_fnt), is_black ? 0x82 : 0x81);
105
+
106
+    set_win_based_attr(x_off + (pos * text_fnt_WIDTH / text_fnt_TILE_W), y_off + 1,
107
+                       text_fnt_WIDTH / text_fnt_TILE_W, 1,
108
+                       text_fnt_map + off + (sizeof(text_fnt_map) / 2), fnt_off + numbers_fnt_TILE_COUNT,
109
+                       BANK(text_fnt), is_black ? 0x82 : 0x81);
110
+}
111
+
112
+static void str3(uint16_t name, uint8_t x_off, uint8_t y_off,
113
+                 uint8_t is_black_a, uint8_t is_black_b, uint8_t is_black_c) {
114
+    character((name >> 10) & 0x1F, 0, x_off, y_off, is_black_a);
115
+    character((name >>  5) & 0x1F, 1, x_off, y_off, is_black_b);
116
+    character((name >>  0) & 0x1F, 2, x_off, y_off, is_black_c);
117
+}
118
+
119
+static void digit(uint8_t val, uint8_t pos, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
120
+    uint8_t off = val * numbers_fnt_WIDTH / numbers_fnt_TILE_W;
121
+
122
+    set_win_based_attr(x_off + (pos * numbers_fnt_WIDTH / numbers_fnt_TILE_W), y_off,
123
+                       numbers_fnt_WIDTH / numbers_fnt_TILE_W, 1,
124
+                       numbers_fnt_map + off, fnt_off,
125
+                       BANK(numbers_fnt), is_black ? 0x82 : 0x81);
126
+
127
+    set_win_based_attr(x_off + (pos * numbers_fnt_WIDTH / numbers_fnt_TILE_W), y_off + 1,
128
+                       numbers_fnt_WIDTH / numbers_fnt_TILE_W, 1,
129
+                       numbers_fnt_map + off + (sizeof(numbers_fnt_map) / 2), fnt_off,
130
+                       BANK(numbers_fnt), is_black ? 0x82 : 0x81);
131
+}
132
+
133
+static void str_l(const char *s, uint8_t len, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
134
+    for (uint8_t n = 0; (*s) && (n < LINE_WIDTH) && (n < len); n++) {
135
+        char c = *(s++);
136
+        if ((c >= 'A') && (c <= 'Z')) {
137
+            c = c - 'A' + 'a';
138
+        }
139
+        if ((c >= '0') && (c <= '9')) {
140
+            digit(c - '0', n, x_off, y_off, is_black);
141
+        } else if ((c >= 'a') && (c <= 'z')) {
142
+            character(c - 'a', n, x_off, y_off, is_black);
143
+        }
144
+    }
145
+}
146
+
147
+static void str(const char *s, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
148
+    str_l(s, 0xFF, x_off, y_off, is_black);
149
+}
150
+
151
+static void str_center(const char *s, uint8_t y_off, uint8_t is_black) {
152
+    uint8_t n = strlen(s);
153
+    if (n > LINE_WIDTH) n = LINE_WIDTH;
154
+    str(s, LINE_WIDTH - n, y_off, is_black);
155
+}
156
+
157
+static void str_lines(const char *s, uint8_t y_off, uint8_t is_black) {
158
+    if (strlen(s) > 10) {
159
+        str(s, 0, y_off, is_black);
160
+        str_center(s + 10, y_off + 2, is_black);
161
+    } else {
162
+        str_center(s, y_off, is_black);
163
+    }
164
+}
165
+
166
+static uint8_t number(int32_t score, uint8_t x_off, uint8_t y_off, uint8_t is_black) {
167
+    // TODO can not set numbers larger than int16 max?!
168
+    //score = 32767 + 1; // wtf?!
169
+
170
+    uint8_t len = 0;
171
+    uint8_t digits[MAX_DIGITS];
172
+    do {
173
+        digits[len++] = score % 10L;
174
+        score = score / 10L;
175
+        if (len >= MAX_DIGITS) {
176
+            break;
177
+        }
178
+    } while (score > 0);
179
+
180
+    // if the number was too large for our buffer don't draw anything
181
+    if (score > 0) {
182
+        return 0;
183
+    }
184
+
185
+    uint8_t off = (x_off == 0xFF) ? (LINE_WIDTH - len) : ((x_off == 0xFE) ? ((LINE_WIDTH * 2) - (len * 2)) : x_off);
186
+    for (uint8_t i = 0; i < len; i++) {
187
+        digit(digits[len - i - 1], i, off, y_off, is_black);
188
+    }
189
+
190
+    return 8 * len * 2;
191
+}
192
+
193
+static void fill_win(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t tile, uint8_t attr) {
194
+    VBK_REG = VBK_ATTRIBUTES;
195
+    fill_win_rect(x, y, w, h, attr);
196
+    VBK_REG = VBK_TILES;
197
+    fill_win_rect(x, y, w, h, tile);
198
+}
199
+
200
+void win_splash_draw(int32_t lowest, int32_t highest) BANKED {
201
+    // reuse full black and white tiles at 0 and 1 from splash bg
202
+    fill_win(0, 0, 10, 4, 0, 0x00);
203
+    fill_win(10, 0, 10, 4, 1, 0x00);
204
+
205
+    // only show on splash if they fit
206
+    if ((lowest <= 99999) && (highest <= 99999)) {
207
+        number(lowest, 0, 0, 1);
208
+        number(highest, 0xFE, 0, 0);
209
+
210
+        str("top", 0, 2, 1);
211
+        str("score", 10, 2, 0);
212
+    }
213
+}
214
+
215
+void win_score_clear(uint8_t is_black) BANKED {
216
+    set_win_based(0, 0,
217
+                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
218
+                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
219
+
220
+    str_center(is_black ? "black" : "white", 1, is_black);
221
+}
222
+
223
+void win_score_draw(struct scores score, uint8_t off, uint8_t is_black) BANKED {
224
+    str3(score.name, 0, 4 + off * 3, is_black, is_black, is_black);
225
+    number(is_black ? -score.score : score.score, 7, 4 + off * 3, is_black);
226
+}
227
+
228
+static void get_git(char *line_buff) NONBANKED {
229
+    START_ROM_BANK(BANK(git));
230
+        strncpy(line_buff, git_version, 2 * LINE_WIDTH);
231
+    END_ROM_BANK();
232
+}
233
+
234
+void win_about(void) BANKED {
235
+    set_win_based(0, 0,
236
+                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
237
+                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
238
+
239
+    str_center("Duality", 0, 1);
240
+    str_center("xythobuz", 2, 1);
241
+
242
+    char line_buff[2 * LINE_WIDTH + 1] = {0};
243
+    get_git(line_buff);
244
+
245
+    str_lines(line_buff, 7, 0);
246
+
247
+    str_l(&__DATE__[7], 4,           0, 14, 1); // year (4)
248
+    str_l(&__DATE__[0], 3, (4 * 2) + 1, 14, 1); // month (3)
249
+    str_l(&__DATE__[4], 2, (7 * 2) + 2, 14, 1); // day (2)
250
+
251
+    str(__TIME__, 4, 16, 0);
252
+}
253
+
254
+static uint8_t get_debug(char *name_buff, uint8_t i) NONBANKED {
255
+    START_ROM_BANK(BANK(main));
256
+        strncpy(name_buff, debug_entries[i].name, ENTRY_NAME_LEN + 1);
257
+
258
+        uint8_t n_len = strlen(name_buff);
259
+        name_buff[n_len] = ' ';
260
+        if (debug_entries[i].flag == DBG_NONE) {
261
+            if (debug_menu_index == i) {
262
+                name_buff[n_len + 1] = debug_special_value + '0';
263
+            } else {
264
+                name_buff[n_len + 1] = '0';
265
+            }
266
+        } else {
267
+            name_buff[n_len + 1] = (conf_get()->debug_flags & debug_entries[i].flag) ? '1' : '0';
268
+        }
269
+        name_buff[n_len + 2] = '\0';
270
+        n_len += 2;
271
+    END_ROM_BANK();
272
+    return n_len;
273
+}
274
+
275
+void win_debug(void) BANKED {
276
+    set_win_based(0, 0,
277
+                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
278
+                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
279
+
280
+    // TODO paging when more options added
281
+    uint8_t off = (10 - DEBUG_ENTRY_COUNT) / 2;
282
+
283
+    str_center("Debug Menu", 0, 0);
284
+
285
+    for (uint8_t i = 0; (i < DEBUG_ENTRY_COUNT) && (i < 7); i++) {
286
+        char name_buff[ENTRY_NAME_LEN + 2 + 1] = {0};
287
+        uint8_t n_len = get_debug(name_buff, i);
288
+        str(name_buff, (LINE_WIDTH - n_len) * 2, (i * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
289
+    }
290
+}
291
+
292
+static uint8_t get_conf(char *name_buff, uint8_t i) NONBANKED {
293
+    START_ROM_BANK(BANK(main));
294
+        strncpy(name_buff, conf_entries[i].name, ENTRY_NAME_LEN + 1);
295
+
296
+        uint8_t n_len = strlen(name_buff);
297
+        name_buff[n_len] = ' ';
298
+        if (*conf_entries[i].var < 10) {
299
+            name_buff[n_len + 1] = *conf_entries[i].var + '0';
300
+        } else {
301
+            name_buff[n_len + 1] = *conf_entries[i].var - 10 + 'A';
302
+        }
303
+        name_buff[n_len + 2] = '\0';
304
+        n_len += 2;
305
+    END_ROM_BANK();
306
+    return n_len;
307
+}
308
+
309
+void win_conf(void) BANKED {
310
+    set_win_based(0, 0,
311
+                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
312
+                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
313
+
314
+    // TODO paging when more options added
315
+    uint8_t off = (10 - CONF_ENTRY_COUNT) / 2;
316
+
317
+    str_center("Conf Menu", 0, 0);
318
+
319
+    for (uint8_t i = 0; (i < CONF_ENTRY_COUNT) && (i < 7); i++) {
320
+        char name_buff[ENTRY_NAME_LEN + 2 + 1] = {0};
321
+        uint8_t n_len = get_conf(name_buff, i);
322
+        str(name_buff, (LINE_WIDTH - n_len) * 2, (i * 2) + 3 + off, (debug_menu_index == i) ? 1 : 0);
323
+    }
324
+}
325
+
326
+void win_name(int32_t score) BANKED {
327
+    set_win_based(0, 0,
328
+                  title_map_WIDTH / title_map_TILE_W, title_map_HEIGHT / title_map_TILE_H,
329
+                  title_map_map, 0, BANK(title_map), title_map_MAP_ATTRIBUTES, BANK(title_map));
330
+
331
+    str_center("score", 1, score < 0);
332
+    number(score < 0 ? -score : score, 0xFF, 3, score < 0);
333
+
334
+    str_center("enter", 6, score < 0);
335
+    str_center("name", 8, score < 0);
336
+
337
+    str_center("start ok", 16, score < 0);
338
+}
339
+
340
+void win_name_draw(uint16_t name, uint8_t is_black, uint8_t pos) BANKED {
341
+    str3(name, LINE_WIDTH - 3, 12,
342
+         (pos == 0) ? !is_black : is_black,
343
+         (pos == 1) ? !is_black : is_black,
344
+         (pos == 2) ? !is_black : is_black);
345
+}
346
+
347
+uint8_t win_game_draw(int32_t score) BANKED {
348
+    fill_win(0, 0, 10, 2, fnt_off + numbers_fnt_TILE_COUNT, 0x81);
349
+
350
+    uint8_t is_black = 0;
351
+    if (score < 0) {
352
+        score = -score;
353
+        is_black = 1;
354
+    }
355
+
356
+    return number(score, 0, 0, is_black);
357
+}

+ 40
- 0
src/window.h View File

@@ -0,0 +1,40 @@
1
+/*
2
+ * window.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 __WINDOW_H__
21
+#define __WINDOW_H__
22
+
23
+#include <gbdk/platform.h>
24
+#include <stdint.h>
25
+#include "score.h"
26
+
27
+void win_init(uint8_t is_splash);
28
+void win_splash_draw(int32_t lowest, int32_t highest) BANKED;
29
+void win_score_clear(uint8_t is_black) BANKED;
30
+void win_score_draw(struct scores score, uint8_t off, uint8_t is_black) BANKED;
31
+void win_about(void) BANKED;
32
+void win_conf(void) BANKED;
33
+void win_debug(void) BANKED;
34
+void win_name(int32_t score) BANKED;
35
+void win_name_draw(uint16_t name, uint8_t is_black, uint8_t pos) BANKED;
36
+uint8_t win_game_draw(int32_t score) BANKED;
37
+
38
+BANKREF_EXTERN(window)
39
+
40
+#endif // __WINDOW_H__

Loading…
Cancel
Save