Last active
May 4, 2022 20:55
-
-
Save rniwase/299481f89302e898d98cac485520ed3d to your computer and use it in GitHub Desktop.
サイレンマシーンforGB proto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* use gbdk-2020 4.0.6 */ | |
/* <path-to-gbdk-env>/bin/lcc -Wa-l -Wl-m -Wl-j -o sirenmachine.gb sirenmachine.c */ | |
#include <gb/gb.h> | |
#include <stdio.h> | |
#include <gbdk/console.h> | |
UBYTE previous_keys; | |
BYTE keys; | |
#define UPDATE_KEYS() previous_keys = keys; keys = joypad() | |
#define KEY_ISPRESS(K) (keys & (K)) | |
#define KEY_PUSHED(K) ((keys & (K)) && !(previous_keys & (K))) | |
#define KEY_RELEASED(K) (!(keys & (K)) && (previous_keys & (K))) | |
#define KEY_ANY_EVENT(K) (keys & (K)) ^ (previous_keys & (K)) | |
UWORD lfo_count_max; | |
UWORD lfo_count_up; | |
UBYTE lfo_dir; | |
UBYTE lfo_waveform; | |
UBYTE osc_pw; | |
UBYTE osc_freq; | |
UBYTE lfo_rate; | |
const UBYTE lfo_period = 6U; | |
const UWORD freq_base [3] = {1407U, 1729U, 1887U}; | |
char lfo_waveform_name[4][8] = { | |
"Square ", | |
"Up ", | |
"Down ", | |
"Up-Down" | |
}; | |
void print_bar(UBYTE val) { | |
UBYTE i; | |
printf("["); | |
for (i = 0; i < 18; i++){ | |
if (i < val) { | |
printf("-"); | |
} else if (i == val) { | |
printf("*"); | |
} else { | |
printf(" "); | |
} | |
} | |
printf("]"); | |
} | |
void tim() { | |
__critical { | |
if (lfo_count_up < lfo_count_max) { | |
lfo_count_up += 1U << lfo_rate; | |
} else { | |
lfo_count_up = 0U; | |
lfo_dir = ~lfo_dir; | |
} | |
} | |
} | |
void print_osc_pw() { | |
gotoxy(0, 12); | |
switch (osc_pw) { | |
case 0 : printf("[--________________]"); break; | |
case 1 : printf("[-----_____________]"); break; | |
case 2 : printf("[---------_________]"); break; | |
} | |
} | |
void print_lfo_event() { | |
if (KEY_ANY_EVENT(J_DOWN | J_UP)) { | |
gotoxy(0, 6); | |
switch (lfo_rate) { | |
case 0: print_bar(0); break; | |
case 1: print_bar(9); break; | |
case 2: print_bar(17); break; | |
} | |
} | |
if (KEY_ANY_EVENT(J_LEFT | J_RIGHT)) { | |
gotoxy(0, 9); | |
switch (osc_freq) { | |
case 0: print_bar(0); break; | |
case 1: print_bar(9); break; | |
case 2: print_bar(17); break; | |
} | |
} | |
} | |
void main() { | |
__critical { | |
lfo_count_max = 376U; | |
lfo_count_up = 0U; | |
lfo_dir = 0U; | |
lfo_waveform = 0U; | |
osc_pw = 2U; | |
osc_freq = 1U; | |
lfo_rate = 1U; | |
add_TIM(tim); | |
} | |
UWORD freq = 0U; | |
NR52_REG = 0x80U; // Enable sound | |
/* Sound channel 1 */ | |
// NR10_REG = 0x17U; | |
// NR11_REG = 0x9FU; | |
// NR12_REG = 0xF0U; | |
// NR13_REG = 0x00FFU & freq_2; | |
// NR14_REG = 0x40 | (freq_2 >> 8); | |
/* Sound channel 2*/ | |
NR21_REG = (osc_pw & 0x03) << 6; | |
NR22_REG = 0xF0U; | |
/* Sound channel 3 */ | |
// NR30_REG = 0x00U; | |
// NR31_REG = 0x00U; | |
// NR32_REG = 0x20U; | |
// NR33_REG = 0xD6U; | |
// NR34_REG = 0x46U; | |
NR50_REG = 0x77U; // Set master volume | |
NR51_REG = 0xFFU; | |
gotoxy(0, 0); | |
printf("Siren Machine for GB"); | |
gotoxy(1, 2); | |
printf("LFO Waveform"); | |
gotoxy(1, 3); | |
printf("- Square"); | |
gotoxy(1, 5); | |
printf("LFO Rate"); | |
gotoxy(0, 6); | |
print_bar(9); | |
gotoxy(1, 8); | |
printf("OSC Freq. Offset"); | |
gotoxy(0, 9); | |
print_bar(9); | |
gotoxy(1, 11); | |
printf("OSC Pulse Width"); | |
print_osc_pw(); | |
gotoxy(1, 14); | |
printf("OSC Sound Off/On"); | |
gotoxy(1, 15); | |
printf("- Off"); | |
TMA_REG = 0xFFU - lfo_period; // Interrupt rate : 5641.3 Hz | |
TAC_REG = 0x07U; // Timer enable, Clock at 16384 Hz | |
set_interrupts(TIM_IFLAG); | |
while (1) { | |
if (KEY_PUSHED(J_A)) { | |
NR22_REG = 0xF0U; // max volume | |
NR24_REG = 0x80U; // restart sound | |
} | |
if (KEY_ISPRESS(J_A)) { | |
gotoxy(3, 15); | |
printf("On "); | |
} | |
if (KEY_RELEASED(J_A)) { | |
NR22_REG = 0x00U; // min volume, stop sound | |
gotoxy(3, 15); | |
printf("Off"); | |
} | |
__critical { | |
if (lfo_waveform == 0U) { | |
if (lfo_dir) { | |
freq = 0U; | |
} else { | |
freq = lfo_count_max; | |
} | |
} else if (lfo_waveform == 1U) { | |
freq = lfo_count_up; | |
} else if (lfo_waveform == 2U) { | |
freq = lfo_count_max - lfo_count_up; | |
} else { | |
if (lfo_dir) { | |
freq = lfo_count_up; | |
} else { | |
freq = lfo_count_max - lfo_count_up; | |
} | |
} | |
if (KEY_PUSHED(J_LEFT) && osc_freq > 0U) { | |
osc_freq--; | |
} else if (KEY_PUSHED(J_RIGHT) && osc_freq < 2U) { | |
osc_freq++; | |
} | |
} | |
freq = freq_base[osc_freq] + (freq >> osc_freq); | |
NR23_REG = 0x00FFU & freq; | |
NR24_REG = (freq >> 8); | |
if (KEY_PUSHED(J_B)) { | |
if (lfo_waveform < 3) { | |
lfo_waveform++; | |
} else { | |
lfo_waveform = 0U; | |
} | |
gotoxy(3, 3); | |
printf("%s", lfo_waveform_name[lfo_waveform]); | |
} | |
if (KEY_PUSHED(J_SELECT)) { | |
if (osc_pw < 2) { | |
osc_pw++; | |
} else { | |
osc_pw = 0U; | |
} | |
NR21_REG = (osc_pw & 0x03) << 6; | |
print_osc_pw(); | |
} | |
__critical { | |
if (KEY_PUSHED(J_DOWN) && lfo_rate > 0U) { | |
lfo_rate--; | |
} else if (KEY_PUSHED(J_UP) && lfo_rate < 2U) { | |
lfo_rate++; | |
} | |
} | |
print_lfo_event(); | |
UPDATE_KEYS(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment