git.y1.nz

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.