gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/examples/gb/sgb_sfx/main.c
1 #include <gb/gb.h>
2 #include <gb/sgb.h>
3
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <stdio.h>
7 #include <gbdk/console.h>
8
9 #include "sgb_snd_sfx.h"
10 #include "sgb_sfx_names.h"
11
12
13 // Stores button presses
14 uint8_t keys = 0x00, keys_last = 0x00;
15
16
17 // Default SFX attributes
18 uint8_t sgb_sfx_a_pitch = SGB_SND_PITCH_HI; // Bits 0..1
19 uint8_t sgb_sfx_a_vol = SGB_SND_VOL_HI; // Bits 2..3
20 uint8_t sgb_sfx_b_pitch = SGB_SND_PITCH_HI; // Bits 4..5
21 uint8_t sgb_sfx_b_vol = SGB_SND_VOL_HI; // Bits 6..7
22
23
24 // Default values for SFX types
25 uint8_t sfx_num_a = SGB_SND_EFFECT_A_MIN;
26 uint8_t sfx_num_b = SGB_SND_EFFECT_B_MIN;
27
28 static uint8_t sgb_buf[20]; // Should be sized to fit max payload bytes + 1 for command byte
29
30
31 // Play a SGB sound effect
32 //
33 // Setting either effect parameter to SGB_SND_EFFECT_EMPTY will skip it.
34 // The pitch and volume settings are not changed in this example, but could be.
35 void sgb_sound_effect(uint8_t sfx_a, uint8_t sfx_b) {
36 sgb_buf[0] = (SGB_SOUND << 3) | 1; // 1 is number of packets to transfer
37 sgb_buf[1] = sfx_a; // Effect A
38 sgb_buf[2] = sfx_b; // Effect B
39 sgb_buf[3] = sgb_sfx_a_pitch | (sgb_sfx_a_vol << 2) | (sgb_sfx_b_pitch << 4) | (sgb_sfx_b_vol << 6);
40 sgb_buf[4] = SGB_MUSIC_SCORE_CODE_NONE; // Must be zero if not used
41 sgb_transfer(sgb_buf);
42 }
43
44
45 #define DISP_SFX_A_START 3
46 #define DISP_SFX_B_START 10
47
48 // Display basic operation info on the screen
49 void init_display(void) {
50 gotoxy(0,1);
51 printf("SGB BUILT-IN SFX");
52
53 gotoxy(0,DISP_SFX_A_START);
54 printf("SFX A:\n");
55 printf(" PLAY: A\n");
56 printf(" STOP: SELECT + A\n");
57 printf(" TYPE: UP / DOWN\n");
58
59 gotoxy(0,DISP_SFX_B_START);
60 printf("SFX B:\n");
61 printf(" PLAY: B\n");
62 printf(" STOP: SELECT + B\n");
63 printf(" TYPE: LEFT / RIGHT\n");
64 }
65
66
67 // Update the display if either of the sfx types have changed
68 void update_display(void) {
69
70 gotoxy(7u, DISP_SFX_A_START);
71 printf("0x%hx", (uint8_t)sfx_num_a);
72 gotoxy(1u, DISP_SFX_A_START + 4u);
73 printf("%s", (const char *)sgb_sfx_names_table_a[sfx_num_a]);
74
75
76 gotoxy(7u, DISP_SFX_B_START);
77 printf("0x%hx", (uint8_t)sfx_num_b);
78 gotoxy(1u, DISP_SFX_B_START + 4u);
79 printf("%s", (const char *)sgb_sfx_names_table_b[sfx_num_b]);
80 }
81
82
83 // Process button presses
84 void handle_input(void) {
85
86 bool display_update_queued = false;
87
88 // Filter so only buttons newly pressed have their bits set
89 switch ((keys ^ keys_last) & keys) {
90
91 // Effect "A" playback controls
92 case J_A: if (keys & J_SELECT) {
93 // Stop the effect
94 sgb_sound_effect(SGB_SND_EFFECT_STOP, SGB_SND_EFFECT_EMPTY);
95 } else {
96 // Start the effect
97 sgb_sound_effect(sfx_num_a, SGB_SND_EFFECT_EMPTY);
98 }
99 break;
100
101 // Effect "B" playback controls
102 case J_B: if (keys & J_SELECT) {
103 // Stop the effect
104 sgb_sound_effect(SGB_SND_EFFECT_EMPTY, SGB_SND_EFFECT_STOP);
105 } else {
106 // Start the effect
107 sgb_sound_effect(SGB_SND_EFFECT_EMPTY, sfx_num_b);
108 }
109 break;
110
111
112 // Effect type selectors
113 case (J_UP): sfx_num_a++;
114 if (sfx_num_a > SGB_SND_EFFECT_A_MAX) sfx_num_a = SGB_SND_EFFECT_A_MIN;
115 display_update_queued = true;
116 break;
117
118 case (J_DOWN): sfx_num_a--;
119 if (sfx_num_a < SGB_SND_EFFECT_A_MIN) sfx_num_a = SGB_SND_EFFECT_A_MAX;
120 display_update_queued = true;
121 break;
122
123 case (J_RIGHT): sfx_num_b++;
124 if (sfx_num_b > SGB_SND_EFFECT_B_MAX) sfx_num_b = SGB_SND_EFFECT_B_MIN;
125 display_update_queued = true;
126 break;
127
128 case (J_LEFT): sfx_num_b--;
129 if (sfx_num_b < SGB_SND_EFFECT_B_MIN) sfx_num_b = SGB_SND_EFFECT_B_MAX;
130 display_update_queued = true;
131 break;
132 }
133
134 if (display_update_queued)
135 update_display();
136 }
137
138
139 void main(void) {
140
141 // Wait 4 frames
142 // For SGB on PAL SNES this delay is required on startup, otherwise borders don't show up
143 for (uint8_t i = 4; i != 0; i--) vsync();
144
145 DISPLAY_ON;
146
147 if (sgb_check()) {
148
149 init_display();
150 update_display();
151
152 while(1) {
153 vsync();
154
155 keys_last = keys;
156 keys = joypad();
157
158 handle_input();
159 }
160 } else {
161 printf("NO SGB DETECTED");
162 }
163
164 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.