From d3fdd327d54128f8d4e5fde52822e61497247a65 Mon Sep 17 00:00:00 2001 From: Frost-Phoenix <67cyril6767@gmail.com> Date: Tue, 4 Feb 2025 21:08:54 +0100 Subject: [PATCH] example: add audio_module_playing --- build.zig | 5 ++ examples/audio/module_playing.zig | 141 ++++++++++++++++++++++++++++++ resources/audio/mini1111.xm | Bin 0 -> 25676 bytes 3 files changed, 146 insertions(+) create mode 100644 examples/audio/module_playing.zig create mode 100644 resources/audio/mini1111.xm diff --git a/build.zig b/build.zig index cadabc4..2dbbfad 100644 --- a/build.zig +++ b/build.zig @@ -212,6 +212,11 @@ pub fn build(b: *std.Build) !void { .path = "examples/audio/sound_loading.zig", .desc = "Load and play a song", }, + .{ + .name = "module_playing", + .path = "examples/audio/module_playing.zig", + .desc = "Module playing (streaming)", + }, .{ .name = "basic_screen_manager", .path = "examples/core/basic_screen_manager.zig", diff --git a/examples/audio/module_playing.zig b/examples/audio/module_playing.zig new file mode 100644 index 0000000..9016557 --- /dev/null +++ b/examples/audio/module_playing.zig @@ -0,0 +1,141 @@ +const rl = @import("raylib"); + +const MAX_CIRCLES = 64; + +const CircleWave = struct { + position: rl.Vector2, + radius: f32, + alpha: f32, + speed: f32, + color: rl.Color, +}; + +const screenWidth = 800; +const screenHeight = 450; + +const colors = [14]rl.Color{ rl.Color.orange, rl.Color.red, rl.Color.gold, rl.Color.lime, rl.Color.blue, rl.Color.violet, rl.Color.brown, rl.Color.light_gray, rl.Color.pink, rl.Color.yellow, rl.Color.green, rl.Color.sky_blue, rl.Color.purple, rl.Color.beige }; + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +pub fn main() !void { + // Initialization + //-------------------------------------------------------------------------------------- + rl.setConfigFlags(rl.ConfigFlags{ .msaa_4x_hint = true }); // NOTE: Try to enable MSAA 4X + + rl.initWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)"); + defer rl.closeWindow(); // Close window and OpenGL context + + rl.initAudioDevice(); // Initialize audio device + defer rl.closeAudioDevice(); // Close audio device (music streaming is automatically stopped) + + // Creates some circles for visual effect + var circles: [MAX_CIRCLES]CircleWave = undefined; + + for (&circles) |*circle| { + initCircle(circle); + } + + var music: rl.Music = try rl.loadMusicStream("resources/audio/mini1111.xm"); + defer rl.unloadMusicStream(music); // Unload music stream buffers from RAM + + music.looping = false; + var pitch: f32 = 1; + + rl.playMusicStream(music); + + var timePlayed: f32 = 0; + var pause: bool = false; + + rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!rl.windowShouldClose()) { // Detect window close button or ESC key + // Update + //---------------------------------------------------------------------------------- + rl.updateMusicStream(music); // Update music buffer with new stream data + + // Restart music playing (stop and play) + if (rl.isKeyPressed(rl.KeyboardKey.space)) { + rl.stopMusicStream(music); + rl.playMusicStream(music); + pause = false; + } + + // Pause/Resume music playing + if (rl.isKeyPressed(rl.KeyboardKey.p)) { + pause = !pause; + + if (pause) { + rl.pauseMusicStream(music); + } else { + rl.resumeMusicStream(music); + } + } + + if (rl.isKeyDown(rl.KeyboardKey.down)) { + pitch -= 0.01; + } else if (rl.isKeyDown(rl.KeyboardKey.up)) { + pitch += 0.01; + } + + rl.setMusicPitch(music, pitch); + + // Get timePlayed scaled to bar dimensions + timePlayed = rl.getMusicTimePlayed(music) / rl.getMusicTimeLength(music) * (screenWidth - 40); + + if (!pause) { + for (&circles) |*circle| { + circle.alpha += circle.speed; + circle.radius += circle.speed * 10.0; + + if (circle.alpha > 1.0) circle.speed *= -1; + + if (circle.alpha <= 0.0) { + initCircle(circle); + } + } + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + rl.beginDrawing(); + + rl.clearBackground(rl.Color.white); + + for (circles) |circle| { + rl.drawCircleV(circle.position, circle.radius, rl.fade(circle.color, circle.alpha)); + } + + // Draw time bar + rl.drawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, rl.Color.light_gray); + rl.drawRectangle(20, screenHeight - 20 - 12, @intFromFloat(timePlayed), 12, rl.Color.maroon); + rl.drawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, rl.Color.gray); + + // Draw help instructions + rl.drawRectangle(20, 20, 425, 145, rl.Color.white); + rl.drawRectangleLines(20, 20, 425, 145, rl.Color.gray); + rl.drawText("PRESS SPACE TO RESTART MUSIC", 40, 40, 20, rl.Color.black); + rl.drawText("PRESS P TO PAUSE/RESUME", 40, 70, 20, rl.Color.black); + rl.drawText("PRESS UP/DOWN TO CHANGE SPEED", 40, 100, 20, rl.Color.black); + rl.drawText(rl.textFormat("SPEED: %f", .{pitch}), 40, 130, 20, rl.Color.maroon); + + rl.endDrawing(); + //---------------------------------------------------------------------------------- + } +} + +fn initCircle(circle: *CircleWave) void { + circle.alpha = 0.0; + circle.radius = getRandomValuef32(10, 40); + circle.position.x = getRandomValuef32(@intFromFloat(circle.radius), @intFromFloat(screenWidth - circle.radius)); + circle.position.y = getRandomValuef32(@intFromFloat(circle.radius), @intFromFloat(screenHeight - circle.radius)); + circle.speed = getRandomValuef32(1, 100) / 2000.0; + circle.color = colors[@intCast(rl.getRandomValue(0, 13))]; +} + +fn getRandomValuef32(min: i32, max: i32) f32 { + return @as(f32, @floatFromInt(rl.getRandomValue(min, max))); +} diff --git a/resources/audio/mini1111.xm b/resources/audio/mini1111.xm new file mode 100644 index 0000000000000000000000000000000000000000..a185c1a2a2b7e514f3a9f5ba36492a79eb61e523 GIT binary patch literal 25676 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 literal 0 HcmV?d00001