Browse Source

add sgb border support

Thomas B 1 month ago
parent
commit
05a71b8c6b
7 changed files with 152 additions and 18 deletions
  1. 1
    0
      .gitignore
  2. 26
    18
      Makefile
  3. 1
    0
      README.md
  4. BIN
      data/border_sgb.png
  5. 24
    0
      src/main.c
  6. 73
    0
      src/sgb_border.c
  7. 27
    0
      src/sgb_border.h

+ 1
- 0
.gitignore View File

@@ -4,3 +4,4 @@ build
4 4
 compile_commands.json
5 5
 bear.cfg
6 6
 tmp
7
+*.sav

+ 26
- 18
Makefile View File

@@ -36,10 +36,11 @@ LCC := $(GBDK_HOME)/bin/lcc
36 36
 PNGA := $(GBDK_HOME)/bin/png2asset
37 37
 ROMU := $(GBDK_HOME)/bin/romusage
38 38
 GB_EMU := gearboy
39
+SGB_EMU := sameboy
39 40
 
40 41
 LCCFLAGS := -Wa-l -Wl-m -Wp-MMD -Wf--opt-code-speed
41 42
 LCCFLAGS += -I$(BUILD_DIR)/$(DATA_DIR)
42
-LCCFLAGS += -Wm"-yn Duality" -Wm-yt0x1B -Wm-yoA -Wm-ya16 -Wm-yc
43
+LCCFLAGS += -Wm"-yn Duality" -Wm-yt0x1B -Wm-yoA -Wm-ya16 -Wm-yc -Wm-ys
43 44
 LCCFLAGS += -autobank -Wb-ext=.rel -Wb-v -Wf-bo255
44 45
 
45 46
 EMUFLAGS := $(BIN)
@@ -58,7 +59,7 @@ $(info BUILD_TYPE is $(BUILD_TYPE))
58 59
 #DEPS=$(OBJS:%.o=%.d)
59 60
 #-include $(DEPS)
60 61
 
61
-.PHONY: all run clean compile_commands.json usage
62
+.PHONY: all run sgb_run clean compile_commands.json usage
62 63
 .PRECIOUS: $(BUILD_DIR)/$(DATA_DIR)/%.c $(BUILD_DIR)/$(DATA_DIR)/%.h
63 64
 
64 65
 all: $(BIN)
@@ -80,24 +81,31 @@ run: $(BIN)
80 81
 	@echo Emulating $<
81 82
 	@$(GB_EMU) $(EMUFLAGS)
82 83
 
84
+sgb_run: $(BIN)
85
+	@echo Emulating $<
86
+	@$(SGB_EMU) $(BIN)
87
+
83 88
 $(BUILD_DIR)/$(DATA_DIR)/%.c $(BUILD_DIR)/$(DATA_DIR)/%.h: $(DATA_DIR)/%.png
84 89
 	@mkdir -p $(@D)
85
-	$(if $(findstring _map,$<),           \
86
-		@echo "Converting map $<" &&  \
87
-		$(PNGA) $< -o $@ -spr8x8 -map -use_map_attributes -noflip \
88
-	,$(if $(findstring _fnt,$<), \
89
-		@echo "Converting font $<" && \
90
-		$(PNGA) $< -o $@ -spr8x8 -sw 16 -sh 16 -map -noflip \
91
-	,$(if $(findstring _spr8,$<), \
92
-		@echo "Converting 8x8 sprite $<" && \
93
-		$(PNGA) $< -o $@ -spr8x8 -sw 8 -sh 8 -noflip \
94
-	,$(if $(findstring _spr16,$<), \
95
-		@echo "Converting 16x16 sprite $<" && \
96
-		$(PNGA) $< -o $@ -spr8x8 -sw 16 -sh 16 -noflip \
97
-	,                                     \
98
-		@echo "Converting tile $<" && \
99
-		$(PNGA) $< -o $@ -spr8x8      \
100
-	))))
90
+	$(if $(findstring _map,$<),                                                             \
91
+		@echo "Converting map $<" &&                                                    \
92
+		$(PNGA) $< -o $@ -spr8x8 -map -use_map_attributes -noflip                       \
93
+	,$(if $(findstring _fnt,$<),                                                            \
94
+		@echo "Converting font $<" &&                                                   \
95
+		$(PNGA) $< -o $@ -spr8x8 -sw 16 -sh 16 -map -noflip                             \
96
+	,$(if $(findstring _spr8,$<),                                                           \
97
+		@echo "Converting 8x8 sprite $<" &&                                             \
98
+		$(PNGA) $< -o $@ -spr8x8 -sw 8 -sh 8 -noflip                                    \
99
+	,$(if $(findstring _spr16,$<),                                                          \
100
+		@echo "Converting 16x16 sprite $<" &&                                           \
101
+		$(PNGA) $< -o $@ -spr8x8 -sw 16 -sh 16 -noflip                                  \
102
+	,$(if $(findstring _sgb,$<),                                                            \
103
+		@echo "Converting sgb border $<" &&                                             \
104
+		$(PNGA) $< -o $@ -map -bpp 4 -max_palettes 4 -pack_mode sgb -use_map_attributes \
105
+	,                                                                                       \
106
+		@echo "Converting tile $<" &&                                                   \
107
+		$(PNGA) $< -o $@ -spr8x8                                                        \
108
+	)))))
101 109
 
102 110
 $(BUILD_DIR)/%.o: %.c $(SPRITES)
103 111
 	@mkdir -p $(@D)

+ 1
- 0
README.md View File

@@ -23,6 +23,7 @@ This Duality GameBoy clone is licensed as GPLv3.
23 23
 A copy of the license can be found in `COPYING`.
24 24
 
25 25
 It uses the [GBDK-2020](https://gbdk.org) libraries and is based on their example code.
26
+The files `sgb_border.c` and `sgb_border.h` are copied directly from their `sgb_border` example.
26 27
 
27 28
     This program is free software: you can redistribute it and/or modify
28 29
     it under the terms of the GNU General Public License as published by

BIN
data/border_sgb.png View File


+ 24
- 0
src/main.c View File

@@ -33,6 +33,8 @@
33 33
 #include "input.h"
34 34
 #include "game.h"
35 35
 #include "score.h"
36
+#include "sgb_border.h"
37
+#include "border_sgb.h"
36 38
 
37 39
 static void highscore(uint8_t is_black) NONBANKED {
38 40
     HIDE_WIN;
@@ -164,7 +166,29 @@ uint16_t ask_name(int32_t score) NONBANKED {
164 166
     return name;
165 167
 }
166 168
 
169
+static void sgb_init(void) NONBANKED {
170
+    // Wait 4 frames
171
+    // For SGB on PAL SNES this delay is required on startup, otherwise borders don't show up
172
+    for (uint8_t i = 0; i < 4; i++) {
173
+        vsync();
174
+    }
175
+
176
+    DISPLAY_ON;
177
+
178
+    SWITCH_ROM(BANK(border_sgb));
179
+
180
+    set_sgb_border((const uint8_t *)border_sgb_tiles, sizeof(border_sgb_tiles),
181
+                   (const uint8_t *)border_sgb_map, sizeof(border_sgb_map),
182
+                   (const uint8_t *)border_sgb_palettes, sizeof(border_sgb_palettes));
183
+
184
+    DISPLAY_OFF;
185
+
186
+}
187
+
167 188
 void main(void) NONBANKED {
189
+    // load sgb border
190
+    sgb_init();
191
+
168 192
     // "cheat" and enable double-speed CPU mode on GBC
169 193
     if (_cpu == CGB_TYPE) {
170 194
         cpu_fast();

+ 73
- 0
src/sgb_border.c View File

@@ -0,0 +1,73 @@
1
+#include "sgb_border.h"
2
+
3
+#include <gb/gb.h>
4
+#include <stdint.h>
5
+#include <gb/sgb.h>
6
+#include <string.h>
7
+
8
+#define SGB_CHR_BLOCK0 0
9
+#define SGB_CHR_BLOCK1 1
10
+
11
+#define SGB_SCR_FREEZE 1
12
+#define SGB_SCR_UNFREEZE 0
13
+
14
+#define SGB_TRANSFER(A,B) map_buf[0]=(A),map_buf[1]=(B),sgb_transfer(map_buf)
15
+
16
+// The display must be turned on before calling this function
17
+// (with @ref DISPLAY_ON).
18
+void set_sgb_border(const uint8_t *tiledata, size_t tiledata_size,
19
+                    const uint8_t *tilemap, size_t tilemap_size,
20
+                    const uint8_t *palette, size_t palette_size) NONBANKED {
21
+    if (!sgb_check()) {
22
+        return;
23
+    }
24
+
25
+    unsigned char map_buf[20];
26
+    memset(map_buf, 0, sizeof(map_buf));
27
+
28
+    SGB_TRANSFER((SGB_MASK_EN << 3) | 1, SGB_SCR_FREEZE);
29
+
30
+    BGP_REG = OBP0_REG = OBP1_REG = 0xE4U;
31
+    SCX_REG = SCY_REG = 0U;
32
+
33
+    uint8_t tmp_lcdc = LCDC_REG;
34
+
35
+    HIDE_SPRITES, HIDE_WIN, SHOW_BKG;
36
+    DISPLAY_ON;
37
+    // prepare tilemap for SGB_BORDER_CHR_TRN (should display all 256 tiles)
38
+    uint8_t i = 0U;
39
+    for (uint8_t y = 0; y != 14U; ++y) {
40
+        uint8_t * dout = map_buf;
41
+        for (uint8_t x = 0U; x != 20U; ++x) {
42
+            *dout++ = i++;
43
+        }
44
+        set_bkg_tiles(0, y, 20, 1, map_buf);
45
+    }
46
+    memset(map_buf, 0, sizeof(map_buf));
47
+
48
+    // transfer tile data
49
+    uint8_t ntiles = (tiledata_size > 256 * 32) ? 0 : tiledata_size >> 5;
50
+    if ((!ntiles) || (ntiles > 128U)) {
51
+        set_bkg_data(0, 0, tiledata);
52
+        SGB_TRANSFER((SGB_CHR_TRN << 3) | 1, SGB_CHR_BLOCK0);
53
+        if (ntiles) ntiles -= 128U;
54
+        tiledata += (128 * 32);
55
+        set_bkg_data(0, ntiles << 1, tiledata);
56
+        SGB_TRANSFER((SGB_CHR_TRN << 3) | 1, SGB_CHR_BLOCK1);
57
+    } else {
58
+        set_bkg_data(0, ntiles << 1, tiledata);
59
+        SGB_TRANSFER((SGB_CHR_TRN << 3) | 1, SGB_CHR_BLOCK0);
60
+    }
61
+
62
+    // transfer map and palettes
63
+    set_bkg_data(0, (uint8_t)(tilemap_size >> 4), tilemap);
64
+    set_bkg_data(128, (uint8_t)(palette_size >> 4), palette);
65
+    SGB_TRANSFER((SGB_PCT_TRN << 3) | 1, 0);
66
+
67
+    LCDC_REG = tmp_lcdc;
68
+
69
+    // clear SCREEN
70
+    fill_bkg_rect(0, 0, 20, 18, 0);
71
+
72
+    SGB_TRANSFER((SGB_MASK_EN << 3) | 1, SGB_SCR_UNFREEZE);
73
+}

+ 27
- 0
src/sgb_border.h View File

@@ -0,0 +1,27 @@
1
+#ifndef __SGB_BORDER_H_INCLUDE
2
+#define __SGB_BORDER_H_INCLUDE
3
+
4
+#include <gb/gb.h>
5
+#include <stdint.h>
6
+
7
+#define SNES_RGB(R,G,B) (uint16_t)((B) << 10 | (G) << 5 | (R))
8
+
9
+/** sets SGB border
10
+
11
+    The display must be turned on before calling this function
12
+    (with @ref DISPLAY_ON).
13
+
14
+    When using the SGB with a PAL SNES, a delay should be added
15
+    just after program startup such as:
16
+
17
+    \code{.c}
18
+    // Wait 4 frames
19
+    // For PAL SNES this delay is required on startup
20
+    for (uint8_t i = 4; i != 0; i--) vsync();
21
+    \endcode
22
+*/
23
+void set_sgb_border(const unsigned char * tiledata, size_t tiledata_size,
24
+                    const unsigned char * tilemap, size_t tilemap_size,
25
+                    const unsigned char * palette, size_t palette_size);
26
+
27
+#endif

Loading…
Cancel
Save