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
 compile_commands.json
4
 compile_commands.json
5
 bear.cfg
5
 bear.cfg
6
 tmp
6
 tmp
7
+*.sav

+ 26
- 18
Makefile View File

36
 PNGA := $(GBDK_HOME)/bin/png2asset
36
 PNGA := $(GBDK_HOME)/bin/png2asset
37
 ROMU := $(GBDK_HOME)/bin/romusage
37
 ROMU := $(GBDK_HOME)/bin/romusage
38
 GB_EMU := gearboy
38
 GB_EMU := gearboy
39
+SGB_EMU := sameboy
39
 
40
 
40
 LCCFLAGS := -Wa-l -Wl-m -Wp-MMD -Wf--opt-code-speed
41
 LCCFLAGS := -Wa-l -Wl-m -Wp-MMD -Wf--opt-code-speed
41
 LCCFLAGS += -I$(BUILD_DIR)/$(DATA_DIR)
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
 LCCFLAGS += -autobank -Wb-ext=.rel -Wb-v -Wf-bo255
44
 LCCFLAGS += -autobank -Wb-ext=.rel -Wb-v -Wf-bo255
44
 
45
 
45
 EMUFLAGS := $(BIN)
46
 EMUFLAGS := $(BIN)
58
 #DEPS=$(OBJS:%.o=%.d)
59
 #DEPS=$(OBJS:%.o=%.d)
59
 #-include $(DEPS)
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
 .PRECIOUS: $(BUILD_DIR)/$(DATA_DIR)/%.c $(BUILD_DIR)/$(DATA_DIR)/%.h
63
 .PRECIOUS: $(BUILD_DIR)/$(DATA_DIR)/%.c $(BUILD_DIR)/$(DATA_DIR)/%.h
63
 
64
 
64
 all: $(BIN)
65
 all: $(BIN)
80
 	@echo Emulating $<
81
 	@echo Emulating $<
81
 	@$(GB_EMU) $(EMUFLAGS)
82
 	@$(GB_EMU) $(EMUFLAGS)
82
 
83
 
84
+sgb_run: $(BIN)
85
+	@echo Emulating $<
86
+	@$(SGB_EMU) $(BIN)
87
+
83
 $(BUILD_DIR)/$(DATA_DIR)/%.c $(BUILD_DIR)/$(DATA_DIR)/%.h: $(DATA_DIR)/%.png
88
 $(BUILD_DIR)/$(DATA_DIR)/%.c $(BUILD_DIR)/$(DATA_DIR)/%.h: $(DATA_DIR)/%.png
84
 	@mkdir -p $(@D)
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
 $(BUILD_DIR)/%.o: %.c $(SPRITES)
110
 $(BUILD_DIR)/%.o: %.c $(SPRITES)
103
 	@mkdir -p $(@D)
111
 	@mkdir -p $(@D)

+ 1
- 0
README.md View File

23
 A copy of the license can be found in `COPYING`.
23
 A copy of the license can be found in `COPYING`.
24
 
24
 
25
 It uses the [GBDK-2020](https://gbdk.org) libraries and is based on their example code.
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
     This program is free software: you can redistribute it and/or modify
28
     This program is free software: you can redistribute it and/or modify
28
     it under the terms of the GNU General Public License as published by
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
 #include "input.h"
33
 #include "input.h"
34
 #include "game.h"
34
 #include "game.h"
35
 #include "score.h"
35
 #include "score.h"
36
+#include "sgb_border.h"
37
+#include "border_sgb.h"
36
 
38
 
37
 static void highscore(uint8_t is_black) NONBANKED {
39
 static void highscore(uint8_t is_black) NONBANKED {
38
     HIDE_WIN;
40
     HIDE_WIN;
164
     return name;
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
 void main(void) NONBANKED {
188
 void main(void) NONBANKED {
189
+    // load sgb border
190
+    sgb_init();
191
+
168
     // "cheat" and enable double-speed CPU mode on GBC
192
     // "cheat" and enable double-speed CPU mode on GBC
169
     if (_cpu == CGB_TYPE) {
193
     if (_cpu == CGB_TYPE) {
170
         cpu_fast();
194
         cpu_fast();

+ 73
- 0
src/sgb_border.c View File

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

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