Fix dynamic sound disabling, add notification system
This commit is contained in:
parent
aee5129723
commit
6a9bcd41b6
7 changed files with 64 additions and 45 deletions
1
Makefile
1
Makefile
|
@ -54,7 +54,6 @@ bootsect: $(BOOTSECT_OBJS)
|
|||
kernel: $(KERNEL_OBJS)
|
||||
$(LD) -o ./bin/$(KERNEL) $^ $(LDFLAGS) -Tsrc/link.ld
|
||||
|
||||
<<<<<<< HEAD
|
||||
img: dirs bootsect kernel
|
||||
dd if=/dev/zero of=$(IMG) bs=512 count=2880
|
||||
dd if=./bin/$(BOOTSECT) of=boot.img conv=notrunc bs=512 seek=0 count=1
|
||||
|
|
31
src/main.c
31
src/main.c
|
@ -1,6 +1,3 @@
|
|||
// remove to disable music, useful when building for hardware without an SB16
|
||||
#define ENABLE_MUSIC
|
||||
|
||||
#include "util.h"
|
||||
#include "screen.h"
|
||||
#include "idt.h"
|
||||
|
@ -12,11 +9,8 @@
|
|||
#include "keyboard.h"
|
||||
#include "speaker.h"
|
||||
#include "fpu.h"
|
||||
|
||||
#ifdef ENABLE_MUSIC
|
||||
#include "sound.h"
|
||||
#include "music.h"
|
||||
#endif
|
||||
|
||||
#define FPS 30
|
||||
#define LEVELS 30
|
||||
|
@ -702,12 +696,13 @@ void _main(u32 magic) {
|
|||
keyboard_init();
|
||||
generate_sprites();
|
||||
|
||||
#ifdef ENABLE_MUSIC
|
||||
sound_init();
|
||||
music_init();
|
||||
state.music = true;
|
||||
sound_master(255);
|
||||
#endif
|
||||
|
||||
if (sound_enabled()) {
|
||||
music_init();
|
||||
state.music = true;
|
||||
sound_master(255);
|
||||
}
|
||||
|
||||
state.menu = true;
|
||||
|
||||
|
@ -718,12 +713,10 @@ void _main(u32 magic) {
|
|||
while (true) {
|
||||
const u32 now = (u32) timer_get();
|
||||
|
||||
#ifdef ENABLE_MUSIC
|
||||
if (now != last) {
|
||||
if (sound_enabled() && now != last) {
|
||||
music_tick();
|
||||
last = now;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((now - last_frame) > (TIMER_TPS / FPS)) {
|
||||
last_frame = now;
|
||||
|
@ -736,8 +729,7 @@ void _main(u32 magic) {
|
|||
render();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MUSIC
|
||||
if (keyboard_char('m')) {
|
||||
if (sound_enabled() && keyboard_char('m')) {
|
||||
if (!last_music_toggle) {
|
||||
state.music = !state.music;
|
||||
sound_master(state.music ? 255 : 0);
|
||||
|
@ -747,7 +739,12 @@ void _main(u32 magic) {
|
|||
} else {
|
||||
last_music_toggle = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// controlled in system.c
|
||||
const char *notification = get_notification();
|
||||
if (notification != NULL) {
|
||||
font_str_doubled(notification, 0, 0, COLOR(6, 1, 1));
|
||||
}
|
||||
|
||||
screen_swap();
|
||||
state.frames++;
|
||||
|
|
|
@ -303,11 +303,7 @@ static size_t PART_LENGTHS[TRACK_PARTS];
|
|||
static i32 indices[TRACK_PARTS];
|
||||
static struct NoteActive current[NUM_NOTES];
|
||||
|
||||
extern bool sound_enabled;
|
||||
|
||||
void music_tick() {
|
||||
if (!sound_enabled) return;
|
||||
|
||||
for (size_t i = 0; i < TRACK_PARTS; i++) {
|
||||
if (indices[i] == -1 || (current[i].ticks -= 1) <= 0) {
|
||||
indices[i] = (indices[i] + 1) % PART_LENGTHS[i];
|
||||
|
@ -329,8 +325,6 @@ void music_tick() {
|
|||
}
|
||||
|
||||
void music_init() {
|
||||
if (!sound_enabled) return;
|
||||
|
||||
sound_wave(0, WAVE_TRIANGLE);
|
||||
sound_volume(0, 255);
|
||||
|
||||
|
|
41
src/sound.c
41
src/sound.c
|
@ -147,12 +147,12 @@ static const f64 NOTES[NUM_OCTAVES * OCTAVE_SIZE] = {
|
|||
#define DSP_VOLUME 0x22
|
||||
#define DSP_IRQ 0x80
|
||||
|
||||
#define SAMPLE_RATE 48000
|
||||
#define SAMPLE_RATE 21500
|
||||
#define BUFFER_MS 40
|
||||
|
||||
#define BUFFER_SIZE ((size_t) (SAMPLE_RATE * (BUFFER_MS / 1000.0)))
|
||||
|
||||
bool sound_enabled = false;
|
||||
static bool is_enabled = false;
|
||||
|
||||
static i16 buffer[BUFFER_SIZE];
|
||||
static bool buffer_flip = false;
|
||||
|
@ -164,6 +164,14 @@ static u8 volumes[NUM_NOTES];
|
|||
static u8 notes[NUM_NOTES];
|
||||
static u8 waves[NUM_NOTES];
|
||||
|
||||
bool sound_enabled() {
|
||||
return is_enabled;
|
||||
}
|
||||
|
||||
void sound_set_enabled(bool enabled) {
|
||||
is_enabled = enabled;
|
||||
}
|
||||
|
||||
void sound_note(u8 index, u8 octave, u8 note) {
|
||||
notes[index] = (octave << 4) | note;
|
||||
}
|
||||
|
@ -181,8 +189,6 @@ void sound_wave(u8 index, u8 wave) {
|
|||
}
|
||||
|
||||
static void fill(i16 *buf, size_t len) {
|
||||
if (!sound_enabled) return;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
double f = 0.0;
|
||||
|
||||
|
@ -230,15 +236,11 @@ static void fill(i16 *buf, size_t len) {
|
|||
}
|
||||
|
||||
static void dsp_write(u8 b) {
|
||||
if (!sound_enabled) return;
|
||||
|
||||
while (inportb(DSP_WRITE) & 0x80);
|
||||
outportb(DSP_WRITE, b);
|
||||
}
|
||||
|
||||
static void dsp_read(u8 b) {
|
||||
if (!sound_enabled) return;
|
||||
|
||||
while (inportb(DSP_READ_STATUS) & 0x80);
|
||||
outportb(DSP_READ, b);
|
||||
}
|
||||
|
@ -247,11 +249,6 @@ static void reset() {
|
|||
char buf0[128], buf1[128];
|
||||
|
||||
outportb(DSP_RESET, 1);
|
||||
|
||||
// TODO: maybe not necessary
|
||||
// ~3 microseconds?
|
||||
for (size_t i = 0; i < 1000000; i++);
|
||||
|
||||
outportb(DSP_RESET, 0);
|
||||
|
||||
u8 status = inportb(DSP_READ_STATUS);
|
||||
|
@ -273,22 +270,23 @@ static void reset() {
|
|||
goto fail;
|
||||
}
|
||||
|
||||
sound_enabled = true;
|
||||
sound_set_enabled(true);
|
||||
return;
|
||||
fail:
|
||||
strlcpy(buf0, "FAILED TO RESET SB16: ", 128);
|
||||
itoa(status, buf1, 128);
|
||||
strlcat(buf0, buf1, 128);
|
||||
notify(buf0);
|
||||
return;
|
||||
}
|
||||
|
||||
static void set_sample_rate(u16 hz) {
|
||||
if (!sound_enabled) return;
|
||||
|
||||
dsp_write(DSP_SET_RATE);
|
||||
dsp_write((u8) ((hz >> 8) & 0xFF));
|
||||
dsp_write((u8) (hz & 0xFF));
|
||||
}
|
||||
|
||||
static void transfer(void *buf, u32 len) {
|
||||
if (!sound_enabled) return;
|
||||
|
||||
u8 mode = 0x48;
|
||||
|
||||
// disable DMA channel
|
||||
|
@ -317,8 +315,6 @@ static void transfer(void *buf, u32 len) {
|
|||
}
|
||||
|
||||
static void sb16_irq_handler(struct Registers *regs) {
|
||||
if (!sound_enabled) return;
|
||||
|
||||
buffer_flip = !buffer_flip;
|
||||
|
||||
fill(
|
||||
|
@ -348,7 +344,10 @@ static void configure() {
|
|||
void sound_init() {
|
||||
irq_install(MIXER_IRQ, sb16_irq_handler);
|
||||
reset();
|
||||
if (!sound_enabled) return;
|
||||
|
||||
if (!sound_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
configure();
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
#define WAVE_NOISE 2
|
||||
#define WAVE_TRIANGLE 3
|
||||
|
||||
bool sound_enabled();
|
||||
void sound_set_enabled(bool enabled);
|
||||
void sound_init();
|
||||
void sound_note(u8 index, u8 octave, u8 note);
|
||||
void sound_master(u8 v);
|
||||
|
|
26
src/system.c
26
src/system.c
|
@ -1,6 +1,16 @@
|
|||
#include "system.h"
|
||||
#include "screen.h"
|
||||
#include "font.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define NOTIFICATION_DURATION_TICKS (TIMER_TPS * 2)
|
||||
|
||||
static struct {
|
||||
char content[512];
|
||||
u64 ticks;
|
||||
} notification = {
|
||||
"", -1
|
||||
};
|
||||
|
||||
static u32 rseed = 1;
|
||||
|
||||
|
@ -33,3 +43,19 @@ void panic(const char *err) {
|
|||
screen_swap();
|
||||
for (;;) {}
|
||||
}
|
||||
|
||||
const char *get_notification() {
|
||||
return timer_get() - notification.ticks <= NOTIFICATION_DURATION_TICKS ?
|
||||
((const char *) ¬ification.content) : NULL;
|
||||
}
|
||||
|
||||
void notify(const char *message) {
|
||||
memcpy(
|
||||
¬ification.content,
|
||||
message,
|
||||
MIN(strlen(message) + 1, sizeof(notification.content))
|
||||
);
|
||||
|
||||
notification.content[sizeof(notification.content) - 1] = 0;
|
||||
notification.ticks = timer_get();
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
_assert_1(__VA_ARGS__),\
|
||||
_assert_0(__VA_ARGS__))
|
||||
|
||||
const char *get_notification();
|
||||
void notify(const char *err);
|
||||
void panic(const char *err);
|
||||
u32 rand();
|
||||
void seed(u32 s);
|
||||
|
|
Reference in a new issue