diff options
Diffstat (limited to 'in_practice/breakout/linux.c')
-rw-r--r-- | in_practice/breakout/linux.c | 93 |
1 files changed, 81 insertions, 12 deletions
diff --git a/in_practice/breakout/linux.c b/in_practice/breakout/linux.c index 2150ed9..8b7f28a 100644 --- a/in_practice/breakout/linux.c +++ b/in_practice/breakout/linux.c @@ -1,26 +1,34 @@ #include "game.h" #include "sys.h" +#include "audio.h" #include <SDL3/SDL.h> #include <GL/glew.h> -#define DEBUG 1 +#include <stdio.h> -typedef struct { +#define DEBUG 0 + +struct sdl_context { SDL_Window *window; i32 width; i32 height; SDL_Renderer *renderer; + SDL_AudioDeviceID audio_device; + SDL_AudioStream *streams[max_sounds]; + i32 last_sound; u64 last_counter; f32 dt; -} sdl_context_t; +}; + +static struct sdl_context ctx; -static sdl_context_t init_sdl(i32 width, i32 height, i32 debug) +static struct sdl_context init_sdl(i32 width, i32 height, i32 debug) { - sdl_context_t ctx = {0}; + struct sdl_context ctx = {0}; ctx.width = width; ctx.height = height; - SDL_Init(SDL_INIT_VIDEO); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); u64 flags = SDL_WINDOW_OPENGL; SDL_CreateWindowAndRenderer("breakout", ctx.width, ctx.height, flags, &ctx.window, &ctx.renderer); if (debug) @@ -30,10 +38,13 @@ static sdl_context_t init_sdl(i32 width, i32 height, i32 debug) SDL_GL_SetSwapInterval(0); ctx.last_counter = SDL_GetPerformanceCounter(); glewInit(); + ctx.audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, 0); + if (!ctx.audio_device) + die("failed to open audio device"); return ctx; } -static void process_sdl_key(input_t *input, i32 scancode, i32 pressed) +static void process_sdl_key(struct input *input, i32 scancode, i32 pressed) { switch (scancode) { case SDL_SCANCODE_ESCAPE: @@ -45,15 +56,24 @@ static void process_sdl_key(input_t *input, i32 scancode, i32 pressed) case SDL_SCANCODE_LEFT: input->left.current = pressed; break; + case SDL_SCANCODE_UP: + input->up.current = pressed; + break; + case SDL_SCANCODE_DOWN: + input->down.current = pressed; + break; case SDL_SCANCODE_SPACE: input->space.current = pressed; break; + case SDL_SCANCODE_RETURN: + input->start.current = pressed; + break; default: break; } } -static void process_sdl_events(game_t *game) +static void process_sdl_events(struct game *game) { SDL_Event event; while (SDL_PollEvent(&event)) { @@ -74,11 +94,11 @@ static f32 get_elapsed(u64 last_counter) return (f32)(current_counter - last_counter) / (f32)frequency; } -static void lock_framerate_sdl(sdl_context_t *ctx, i32 fps) +static void lock_framerate_sdl(struct sdl_context *ctx, i32 fps) { f32 elapsed = get_elapsed(ctx->last_counter) * 1000.0f; f32 target = 1000.0f / (f32)fps; - f32 sleep = target - elapsed; + f32 sleep = target - elapsed - 1.0f; if (sleep > 0) SDL_Delay((u32)sleep); do { @@ -88,6 +108,7 @@ static void lock_framerate_sdl(sdl_context_t *ctx, i32 fps) ctx->last_counter = SDL_GetPerformanceCounter(); } +#if DEBUG static void fps_info(f32 dt, i32 again) { static f32 time = 0; @@ -112,18 +133,66 @@ static void fps_info(f32 dt, i32 again) } } } +#endif + +void load_wav(const char *dir, const char *filename, const char *name) +{ + char path[512] = {0}; + snprintf(path, 512, "%s/%s", (dir ? dir : "."), filename); + SDL_AudioSpec spec; + u8 *data; + u32 size; + if (!SDL_LoadWAV(path, &spec, &data, &size)) + die("failed to load wav \"%s\"", path); + if (ctx.last_sound >= max_sounds) { + info("max sounds reached"); + return; + } + sounds[ctx.last_sound] = (struct sound){data, size, name}; + if (!(ctx.streams[ctx.last_sound] = SDL_CreateAudioStream(&spec, 0))) + die("failed to create audio stream"); + if (!SDL_BindAudioStream(ctx.audio_device, ctx.streams[ctx.last_sound])) + die("failed to bind audio stream"); + ctx.last_sound++; + info("sound \"%s\" loaded successfuly", path); +} + +void play_audio(const char *name, i32 loop) +{ + i32 i = get_sound(name); + if (i == -1) + info("no audio with the name \"%s\"", name); + sounds[i].loop = loop; + if (SDL_GetAudioStreamQueued(ctx.streams[i])) + SDL_ClearAudioStream(ctx.streams[i]); + SDL_PutAudioStreamData(ctx.streams[i], sounds[i].data, sounds[i].size); +} + +static void update_audio(void) +{ + for (i32 i = 0; i < max_sounds; i++) { + if (sounds[i].loop) { + i32 queued = SDL_GetAudioStreamQueued(ctx.streams[i]); + if (queued < (i32)sounds[i].size) + SDL_PutAudioStreamData(ctx.streams[i], sounds[i].data, sounds[i].size); + } + } +} i32 main(void) { - sdl_context_t ctx = init_sdl(1600, 800, DEBUG); - game_t game = init_game(ctx.width, ctx.height); + ctx = init_sdl(800, 600, DEBUG); + struct game game = init_game(ctx.width, ctx.height); while (game.running) { process_sdl_events(&game); process_input(&game); update_game(&game, ctx.dt); + update_audio(); update_input(&game.input); lock_framerate_sdl(&ctx, 60); +#if DEBUG fps_info(ctx.dt, 10); +#endif render_game(game); SDL_GL_SwapWindow(ctx.window); } |