diff --git a/engine/audio/src/audio.zig b/engine/audio/src/audio.zig index bca7870..faace6a 100644 --- a/engine/audio/src/audio.zig +++ b/engine/audio/src/audio.zig @@ -4,13 +4,13 @@ const std = @import("std"); const memory = core.MemoryTracker; const soundEngine = @import("sound_engine.zig"); -pub const NeonSoundEngine = soundEngine.NeonSoundEngine; +pub const SoundEngine = soundEngine.SoundEngine; pub const sound_err = soundEngine.sound_err; pub const sound_errs = soundEngine.sound_errs; pub const sound_log = soundEngine.sound_log; pub const sound_logs = soundEngine.sound_logs; -pub var gSoundEngine: *NeonSoundEngine = undefined; +pub var gSoundEngine: *SoundEngine = undefined; pub var gSoundLoader: *soundEngine.SoundLoader = undefined; pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void { @@ -20,12 +20,13 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me return; } - gSoundEngine = core.createObject(NeonSoundEngine, .{ .can_tick = true }) catch unreachable; + gSoundEngine = core.createObject(SoundEngine, .{ .can_tick = true }) catch unreachable; gSoundLoader = allocator.create(soundEngine.SoundLoader) catch unreachable; gSoundLoader.* = soundEngine.SoundLoader.init(gSoundEngine); assets.getAssets().registerLoader(gSoundLoader) catch unreachable; + _ = try core.fs().installFileBytesMount("embedded:engineTick.wav", @constCast(&engineTickWav), true); // var name = core.MakeName("s_test"); // gSoundEngine.loadSound(&name, "content/sounds/engineTick.wav", .{}) catch unreachable; @@ -37,7 +38,16 @@ pub fn shutdown_module(allocator: std.mem.Allocator) void { gSoundEngine.shutdown(); } +pub const context = core.EngineObject(SoundEngine).get; + +pub fn loadBuiltinSounds() !void { + var name = core.MakeName("engine/s_tick"); + try context().loadSound(&name, "embedded:engineTick.wav", .{}); +} + pub const Module = core.ModuleDescription{ .name = "audio", .enabledByDefault = false, }; + +const engineTickWav align(8) = @embedFile("embedded/engineTick.wav").*; diff --git a/engine/audio/src/sound_engine.zig b/engine/audio/src/sound_engine.zig index ddde9b9..579ab70 100644 --- a/engine/audio/src/sound_engine.zig +++ b/engine/audio/src/sound_engine.zig @@ -29,9 +29,9 @@ pub fn sound_errs(comptime fmt: []const u8) void { pub const SoundLoader = struct { pub var LoaderInterfaceVTable: assets.AssetLoaderInterface = assets.AssetLoaderInterface.from("Sound", @This()); - engine: *NeonSoundEngine, + engine: *SoundEngine, - pub fn init(engine: *NeonSoundEngine) @This() { + pub fn init(engine: *SoundEngine) @This() { return @This(){ .engine = engine, }; @@ -64,11 +64,12 @@ fn ma_res(value: anytype) !void { } } // On init, SoundEngine will spawn a -pub const NeonSoundEngine = struct { +pub const SoundEngine = struct { pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "audio.SoundEngine"); engine: *ma.ma_engine, sounds: AutoHashMapUnmanaged(u32, *ma.ma_sound), + decoders: AutoHashMapUnmanaged(u32, *ma.ma_decoder), allocator: std.mem.Allocator, volume: f32 = 1.0, @@ -77,6 +78,7 @@ pub const NeonSoundEngine = struct { self.* = @This(){ .engine = allocator.create(ma.ma_engine) catch unreachable, .sounds = .{}, + .decoders = .{}, .allocator = allocator, }; @@ -101,17 +103,31 @@ pub const NeonSoundEngine = struct { const sound = try self.allocator.create(ma.ma_sound); errdefer self.allocator.destroy(sound); - const res = ma.ma_sound_init_from_file(self.engine, fileName.ptr, 0, null, null, sound); + const engineSoundBytes = try core.fs().loadFile(fileName); + const bytes = engineSoundBytes.bytes; + + // Create a decoder from the loaded bytes + const decoder = try self.allocator.create(ma.ma_decoder); + errdefer self.allocator.destroy(decoder); + + const res_decoder = ma.ma_decoder_init_memory(bytes.ptr, bytes.len, null, decoder); + if (res_decoder != ma.MA_SUCCESS) { + sound_err("failed to initialize decoder for sound: {s}", .{soundName.utf8()}); + return error.MiniAudioError; + } + + const res = ma.ma_sound_init_from_data_source(self.engine, decoder, 0, null, sound); if (res != ma.MA_SUCCESS) { sound_err("tried loading sound: {s} failed", .{soundName.utf8()}); return error.MiniAudioError; } try self.sounds.put(self.allocator, soundName.handle(), sound); + try self.decoders.put(self.allocator, soundName.handle(), decoder); ma.ma_sound_set_volume(sound, soundParams.volume); } - pub fn playSound(self: *@This(), soundName: core.Name) !void { + pub fn playSound(self: *@This(), soundName: *core.Name) !void { const maybeSound = self.sounds.get(soundName.handle()); if (maybeSound == null) @@ -142,6 +158,14 @@ pub const NeonSoundEngine = struct { self.allocator.destroy(sound.value_ptr.*); } self.sounds.deinit(self.allocator); + + var decoder_iter = self.decoders.iterator(); + while (decoder_iter.next()) |decoder| { + _ = ma.ma_decoder_uninit(decoder.value_ptr.*); + self.allocator.destroy(decoder.value_ptr.*); + } + self.decoders.deinit(self.allocator); + ma.ma_engine_uninit(self.engine); self.allocator.destroy(self.engine); self.allocator.destroy(self); diff --git a/engine/papyrus/src/papyrus.zig b/engine/papyrus/src/papyrus.zig index 323a530..d99beb3 100644 --- a/engine/papyrus/src/papyrus.zig +++ b/engine/papyrus/src/papyrus.zig @@ -422,6 +422,7 @@ pub const Context = struct { debugText: std.ArrayList([]u8), debugTextCount: u32 = 0, drawDebug: bool = false, + debugMousePick: bool = false, rootNodes: std.ArrayList(NodeHandle), const debugTextMax = 32; @@ -438,19 +439,21 @@ pub const Context = struct { pub fn tickDebug(self: *@This(), deltaTime: f64) !void { _ = deltaTime; try self.pushDebugText("mouse Position: {d}, {d}", .{ self.currentCursorPosition.x, self.currentCursorPosition.y }); - if (self.mousePick.selected_node) |node| { - const n = self.getRead(node); - const layout = self._displayLayout.items[node.index]; - try self.pushDebugText("found node: {d},{d} size={d}x{d} layoutpos={d},{d} layoutsize={d},{d}", .{ - node.index, - node.generation, - n.size.x, - n.size.y, - layout.pos.x, - layout.pos.y, - layout.size.x, - layout.size.y, - }); + if (self.debugMousePick) { + if (self.mousePick.selected_node) |node| { + const n = self.getRead(node); + const layout = self._displayLayout.items[node.index]; + try self.pushDebugText("found node: {d},{d} size={d}x{d} layoutpos={d},{d} layoutsize={d},{d}", .{ + node.index, + node.generation, + n.size.x, + n.size.y, + layout.pos.x, + layout.pos.y, + layout.size.x, + layout.size.y, + }); + } } } @@ -1192,6 +1195,10 @@ pub const Context = struct { try self.addDebugInfo(drawList); } + if (self.debugMousePick) { + try self.mousePick.addMousePickInfo(self, drawList); + } + for (0..drawList.items.len) |i| { switch (drawList.items[i].primitive) { .Text => |*text| { @@ -1211,8 +1218,6 @@ pub const Context = struct { const fontHandle = self.fontCache.defaultMonoFont.atlas.fontHandle; - try self.mousePick.addMousePickInfo(&self, drawList); - try drawList.append(.{ .node = .{}, .primitive = .{ diff --git a/projects/sampleGame/externGame/externGame.zig b/projects/sampleGame/externGame/externGame.zig index 07edb65..491b87f 100644 --- a/projects/sampleGame/externGame/externGame.zig +++ b/projects/sampleGame/externGame/externGame.zig @@ -53,6 +53,7 @@ pub const ExternGameObject = struct { fireTraceFilter: physics.IgnoreFixedBodiesFilter = .{}, particleDebugger: extras.ParticleDebugger.ParticleDebugger = undefined, + volume: f32 = 100, //lmao: bool = false, //lmao2: bool = true, // lib: bool = false, @@ -342,6 +343,15 @@ pub const ExternGameObject = struct { if (ig.checkbox("vectors test", &self.displayVectorsTest)) {} if (ig.checkbox("showdebug", &ui.context().screenContext.drawDebug)) {} + + if (ig.smallButton("click for fun")) { + // var soundname = core.MakeName("s_macintosh"); + // audio.context().playSound(&soundname) catch {}; + } + + if (ig.sliderFloat("sliderFloat", &self.volume, 0, 100, null, .{})) { + audio.context().setVolume(self.volume / 100); + } } ig.end(); @@ -379,6 +389,7 @@ const rend = backlog.rend; const ig = imgui.api; const sys = backlog.sys; const ui = backlog.ui; +const audio = backlog.audio; const platform = backlog.platform; const extras = @import("gameExtras"); const bsp = @import("bsp"); diff --git a/projects/sampleGame/main.zig b/projects/sampleGame/main.zig index aaaa446..7e34634 100644 --- a/projects/sampleGame/main.zig +++ b/projects/sampleGame/main.zig @@ -58,6 +58,11 @@ const assetReferences = [_]assets.AssetImportReference{ "a_fox_survey", .{ .path = "gltf-samples/Fox/glTF/Survey.ozz" }, ), + // assets.MakeImportRefOptions( + // "Sound", + // "s_macintosh", + // .{ .path = "sounds/MACINTOSHPLUS.wav" }, + // ), assets.MakeImportRefOptions( "Mesh", "m_fox", @@ -233,6 +238,8 @@ pub fn prepare(self: *@This()) !void { try extras.setup(); + try audio.loadBuiltinSounds(); + // try core.loadModule("externGame", true); try backlog.loadDynamicModules(); @@ -537,6 +544,7 @@ const assets = backlog.assets; const platform = backlog.platform; const core = backlog.core; const ig = backlog.imgui.api; +const audio = backlog.audio; const rend = backlog.rend; const script = core.script; const tracy = core.tracy;