From 17e57f1fdebb8fa7a23a150caf1f0c53dd71b3c2 Mon Sep 17 00:00:00 2001 From: alistair Date: Mon, 30 Nov 2020 13:39:48 +1000 Subject: [PATCH] working game noises, SDL_mixer, 8bit synth, v basic --- Makefile | 4 +- src/draw.c | 2 + src/draw.h | 9 +-- src/environment.c | 11 ++++ src/main.c | 157 ++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 150 insertions(+), 33 deletions(-) diff --git a/Makefile b/Makefile index 5cab9b3..9ed28b2 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,11 @@ debug = true ifeq ($(target),windows) CC=x86_64-w64-mingw32-gcc - SDL_INCLUDE = -Dmain=SDL_main -Lsdllib -lSDL2main -lSDL2main -lSDL2 -lmingw32 -lSDL2main -lSDL2 -mwindows -Wl,-static -lpthread -lm + SDL_INCLUDE = -Dmain=SDL_main -Lsdllib -lSDL2main -lSDL2main -lSDL2 -lmingw32 -lSDL2main -lSDL2 -mwindows -lSDL2_mixer -Wl,-static -lpthread -lm CCFLAGS=$(SDL_INCLUDE) -O3 else CC=gcc - SDL_INCLUDE= -lSDL2 -lm -lSDL2_ttf + SDL_INCLUDE= -lSDL2 -lm -lSDL2_ttf -lSDL2_mixer CCFLAGS=$(SDL_INCLUDE) -O3 endif diff --git a/src/draw.c b/src/draw.c index 539ffcf..fa6e7b7 100644 --- a/src/draw.c +++ b/src/draw.c @@ -7,6 +7,8 @@ Vect viewport_pos; int width, height; +bool high_contrast_mode = 0; + /* generic rendering functions */ int MAX_ONSCREEN_OBJECTS = 99; diff --git a/src/draw.h b/src/draw.h index ded3047..c695b4a 100644 --- a/src/draw.h +++ b/src/draw.h @@ -31,12 +31,13 @@ void add_to_view(draw_type kind, void * object); void redraw_buffer(SDL_Renderer * ren); -extern Vect viewport_pos; - -extern int width, height; - void draw_text(SDL_Renderer *ren, Vect pos, struct colour colour, char *text); int draw_end_screen(SDL_Renderer *ren); +extern Vect viewport_pos; +extern int width, height; +extern bool high_contrast_mode; + + #endif diff --git a/src/environment.c b/src/environment.c index 05a8d7f..ef1f25d 100644 --- a/src/environment.c +++ b/src/environment.c @@ -1,5 +1,6 @@ #include "environment.h" #include "game.h" +#include "types.h" double linear_interpolate(double a0, double a1, double w) { return (1.0f - w) * a0 + w * a1; @@ -52,10 +53,20 @@ double perlin(Vect coordinate) { return linear_interpolate(ix0, ix1, sy); } +struct colour_pallete get_pallete_high_contrast(void) { + struct colour white = {.r = 255, .g=255,.b=255, .sp=CS_RGB}; + struct colour black = {.r = 0, .g=0,.b=0, .sp=CS_RGB}; + struct colour_pallete p = {.bg = black, .fg1 = white, .fg2 = white, .fg3 = white}; + return p; +} + struct colour_pallete get_pallete (int seed) { struct colour base; + if (high_contrast_mode) + return get_pallete_high_contrast(); + int red = get_rand(0) % 255; int blue = get_rand(0) % 255; int green = get_rand(0) % 255; diff --git a/src/main.c b/src/main.c index edfdfec..b0943d5 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,7 @@ +#include #include #include +#include #include #include #include @@ -7,6 +9,7 @@ #include #include #include +#include // only for mkdirat lol #include @@ -16,12 +19,28 @@ #include "game.h" #include "draw.h" #include "garbo.h" +#include "types.h" const int screen_width = 800; const int screen_height = 600; +SDL_AudioSpec audio_format = {.freq = 8000, .format = AUDIO_U8,.channels = 2, .samples=128}; + +#define G_AUDIO_SFREQ 8000 +#define G_AUDIO_BSIZE 512 SDL_sem *resume; +struct game_sounds { + unsigned int t; + Mix_Chunk *collision; + Mix_Chunk *rope_attach; + Mix_Chunk *rope_pull; + /* Looping samples (need backbuffer to fill while playing ) */ + Mix_Chunk *menu; +}; + +struct game_sounds game_sounds; + struct SDL_Window* make_window(void) { if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { @@ -29,7 +48,7 @@ struct SDL_Window* make_window(void) { } - return SDL_CreateWindow("sdl_tester", + return SDL_CreateWindow("space_game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 0, 0, @@ -41,23 +60,6 @@ void callbackfn2(void *unused, Uint8 *stream, int len); void callbackfn3(void *unused, Uint8 *stream, int len); -void start_audio(void) { - SDL_AudioSpec fmt = {.freq = 8000, .format = AUDIO_U8,.channels = 1, .samples=512}; - - fmt.callback = callbackfn3; - - if (SDL_OpenAudio(&fmt, NULL) < 0) { - fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError()); - exit(1); - } - SDL_PauseAudio(0); - -} - -void stop_audio(void) { - SDL_CloseAudio(); -} - unsigned int func1(int t) { int note = 10; if (!(t % 8000)) { @@ -67,27 +69,96 @@ unsigned int func1(int t) { return ((t & 110) % 73 | (t % 1711)); } -unsigned int func0(int t) { + +Uint8 big_hum(unsigned int t) { + return ( (sin(t*2*3.14159265/16000*200)+1) * 20) + ( (sin(t*2*3.14159265/16000*110)+1) * 20) + ( (sin(t*2*3.14159265/16000*230)+1) * 20) + ( (sin((t % 80)*2*3.14159265/16000 * 6)+1) * 12); +} + +unsigned int sine_wave_sound(int t) { + const double R=8000; // sample rate (samples per second) + const double C=261.625565; // frequency of middle-C (hertz) + const double F=R/256; // bytebeat frequency of 1*t due to 8-bit truncation (hertz) + const double V=127; // a volume constant + return (sin(t*2*M_PI/R*C)+1)*V; +} + +unsigned int winch_sound(int t) { + return (t % 80) | (t % 36) | (6 * (t % 6)); +} + +unsigned int beat_2(int t) { + return ((((t % 250) / 2)) | (t % 129)) % 110; +} + +Uint8 func0(int t) { int note = 18; if (t % 1240) { note = (1 + rand()) % 18 + 1; } - printf("%d %d\n", t, note); fflush(stdout); return (t % note); } + void fill_audio(void *func, Uint8 *stream, int len) { + Uint8 (*wavegen)(int) = func; + + static int t = 1; + for(int i = 0; i < len; i++,t++) { + stream[i] = wavegen(t); + } +} + + + +void generate_audio(void) { + + const int sfx_len_ms = 2000; + unsigned int sfx_len = (G_AUDIO_SFREQ/1000) * G_AUDIO_BSIZE * sfx_len_ms; + Uint8 raw_data[sfx_len]; // 10 seconds + + fill_audio(winch_sound, raw_data, sfx_len); + game_sounds.rope_pull = Mix_QuickLoad_RAW(raw_data, sfx_len); + fill_audio(beat_2, raw_data, sfx_len); + game_sounds.collision = Mix_QuickLoad_RAW(raw_data, sfx_len); +} + +void play_sound(Mix_Chunk *chunk, int times) { + Mix_PlayChannel(-1, chunk, times - 1); +} + void callbackfn3(void *unused, Uint8 *stream, int len) { static int t = 1; - int i; - int yeet = rand(); - for(i=0; i < len; i++,t++) { - stream[i] = func1(t); + for(int i = 0; i < len; i++,t++) { + stream[i] = big_hum(t); + stream[i] = 0; + } +} + +void start_audio(void) { + + audio_format.callback = callbackfn3; + /* just for playing background music + if (SDL_OpenAudio(&audio_format, NULL)) { + fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError()); + exit(1); } + */ + //SDL_PauseAudio(0); + if (Mix_OpenAudio(G_AUDIO_SFREQ,AUDIO_U8,1,G_AUDIO_BSIZE) < 0) { + fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError()); + exit(1); + } + generate_audio(); + Mix_Resume(-1); } +void stop_audio(void) { + SDL_CloseAudio(); +} + + void callbackfn2(void *unused, Uint8 *stream, int len) { static int t = 1; int i; @@ -127,7 +198,7 @@ int physics_loop(void *ptr) { // display end level screen game_paused = true; SDL_Delay(1000); - SDL_PauseAudio(1); + Mix_Pause(-1); in_game = false; SDL_SemWait(resume); add_time(level_time); @@ -139,11 +210,36 @@ int physics_loop(void *ptr) { SDL_UnlockMutex(player.physics->lock); SDL_Delay(1000); game_paused = 0; - SDL_PauseAudio(0); + Mix_Resume(-1); } } } +void play_game_sound(Mix_Chunk *chunk, int len, int channel) { + if (Mix_Playing(channel)) { + return; + } + Mix_FadeInChannelTimed(channel, chunk, -1, 1, len); +} + +void synthplay_now(Uint8 (*bbgen)(unsigned int t), int len) { + static Mix_Chunk *new_chunk = NULL; + + if (Mix_Playing(1)) { + return; + } + + if (new_chunk) + Mix_FreeChunk(new_chunk); + + int generate_len = len * (512) * 8; + + Uint8 raw_data[generate_len]; + fill_audio(bbgen, raw_data, generate_len); + + new_chunk = Mix_QuickLoad_RAW(raw_data, generate_len); + Mix_PlayChannelTimed(1, new_chunk, -1, -1); +} int game(void) { LOGLEVEL = DEBUG; @@ -182,6 +278,8 @@ int game(void) { physics_thread = SDL_CreateThread(physics_loop, "physics", (void *)ren); + start_audio(); + int count = 0; while (!close) { SDL_Event event; @@ -210,6 +308,12 @@ int game(void) { draw_end_screen(ren); } else { redraw(ren); + if (player.physics->colliding) { + count++; + play_game_sound(game_sounds.collision, 200, 1); + } else { + count = 0; + } } } } @@ -219,7 +323,6 @@ int main (int argc, char** argv) { mkdirat(AT_FDCWD, "saves", 0777); - start_audio(); game(); SDL_Quit(); //empty_cleanup_queue();