From 86610a003c0ae7ab88b67e3f275d97a78e605cb3 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sat, 17 Feb 2024 09:48:51 +0100 Subject: Allow user-customizable volume levels --- src/ahoy/config.h | 3 +++ src/ahoy/gui.c | 13 ++++++++++--- src/ahoy/main.c | 28 ++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/ahoy/config.h b/src/ahoy/config.h index 15ad895..23d756f 100644 --- a/src/ahoy/config.h +++ b/src/ahoy/config.h @@ -3,11 +3,14 @@ #include +#define VOLMAX 10'000 + struct config { bool scanls; bool seeded; uint16_t seed; unsigned cpu_hz; + int vol; }; extern struct config cfg; diff --git a/src/ahoy/gui.c b/src/ahoy/gui.c index d03e172..5ec20f3 100644 --- a/src/ahoy/gui.c +++ b/src/ahoy/gui.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -45,7 +46,7 @@ wininit(void) want = (SDL_AudioSpec){ .freq = 44100, - .format = AUDIO_S16LSB, + .format = AUDIO_S16SYS, .channels = 1, .samples = 512, .callback = audio_callback, @@ -142,9 +143,15 @@ readevnt(void) case SDLK_SPACE: estate = estate == ES_RUNNING ? ES_PAUSED : ES_RUNNING; break; - case SDLK_EQUALS: + case SDLK_p: estate = ES_RESET; break; + case SDLK_EQUALS: + cfg.vol = MIN(cfg.vol + 500, VOLMAX); + break; + case SDLK_MINUS: + cfg.vol = MAX(cfg.vol - 500, 0); + break; case SDLK_l: cfg.scanls = !cfg.scanls; windrw(); @@ -269,5 +276,5 @@ audio_callback(void *, uint8_t *stream, int len) crest of the wave, this will add the volume, otherwise it is the trough of the wave, and will add ‘negative’ volume. */ for (int i = 0; i < len / 2; i++) - data[i] = ((si++ / half_sqrwv_p) & 1) ? -3000 : +3000; + data[i] = ((si++ / half_sqrwv_p) & 1) ? -cfg.vol : +cfg.vol; } diff --git a/src/ahoy/main.c b/src/ahoy/main.c index fff7f9d..85db49e 100644 --- a/src/ahoy/main.c +++ b/src/ahoy/main.c @@ -20,6 +20,7 @@ #include "gui.h" #include "macros.h" +/* TODO: Remove this once stdckdint.h is in GCC / Glibc */ #if __has_include() # include # warning "stdckdint.h now available; remove manual ckd_*() implementations" @@ -27,7 +28,9 @@ # define ckd_add(r, a, b) ((bool)__builtin_add_overflow(a, b, r)) # define ckd_mul(r, a, b) ((bool)__builtin_mul_overflow(a, b, r)) #else -# error "Platform not supported at the moment" +# define ckd_add(r, a, b) +# define ckd_mul(r, a, b) +# warning "ckd_*() not supported on the current platform" #endif #define FPS 60 @@ -47,20 +50,24 @@ return n; \ } +STRTOX(int, i) STRTOX(unsigned, u) STRTOX(uint16_t, u16) [[noreturn]] static void usage(void); static void run(int, const char *); -struct config cfg; +struct config cfg = { + .cpu_hz = 700, + .vol = 3000, +}; static const char *argv0; void usage(void) { fprintf(stderr, - "Usage: %s [-S] [-c clock speed] [-s seed] [file]\n" + "Usage: %s [-S] [-c clock speed] [-s seed] [-v volume] [file]\n" " %s -h\n", argv0, argv0); exit(EXIT_FAILURE); @@ -70,7 +77,10 @@ usage(void) do { \ rune ch; \ T n = F(optarg, &ch); \ - if (ch >= '0' && ch <= '9') { \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wtype-limits\""); \ + if (n > M || (ch >= '0' && ch <= '9')) { \ + _Pragma("GCC diagnostic pop"); \ warnx(N " too high; may not exceed %" FMT, M); \ usage(); \ } else if (ch) { \ @@ -91,13 +101,15 @@ main(int argc, char **argv) {"help", no_argument, nullptr, 'h'}, {"seed", required_argument, nullptr, 's'}, {"scanlines", no_argument, nullptr, 'S'}, + {"volume", required_argument, nullptr, 'v'}, {nullptr, no_argument, nullptr, 0 }, }; argv0 = argv[0]; cerrinit(*argv); - while ((opt = getopt_long(argc, argv, "c:hs:S", longopts, nullptr)) != -1) { + while ((opt = getopt_long(argc, argv, "c:hs:Sv:", longopts, nullptr)) != -1) + { switch (opt) { case 'h': execlp("man", "man", "1", argv[0], nullptr); @@ -119,14 +131,14 @@ main(int argc, char **argv) case 'S': cfg.scanls = true; break; + case 'v': + NUMERIC_ARG(int, VOLMAX, "d", strtoi, vol, "volume"); + break; default: usage(); } } - if (!cfg.cpu_hz) - cfg.cpu_hz = 700; - argc -= optind; argv += optind; -- cgit v1.2.3