Browse Source

start work on mirroring background on scroll (still disabled)

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

+ 4
- 2
src/config.h View File

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

+ 7
- 11
src/game.c View File

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

+ 7
- 8
src/main.c View File

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

+ 1
- 1
src/main.h View File

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

+ 130
- 3
src/maps.c View File

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

+ 4
- 0
src/maps.h View File

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

+ 1
- 2
src/sound.c View File

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

+ 29
- 0
src/util.h View File

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

+ 5
- 2
src/window.c View File

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

Loading…
Cancel
Save