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