Add music, fiddle with stack size
parent
199c206a6d
commit
aebd05de18
|
@ -60,7 +60,7 @@ pub fn build(b: *std.build.Builder) !void {
|
||||||
lib.initial_memory = 65536;
|
lib.initial_memory = 65536;
|
||||||
lib.max_memory = 65536;
|
lib.max_memory = 65536;
|
||||||
if (try version_supports_stack_first(zig_version)) {
|
if (try version_supports_stack_first(zig_version)) {
|
||||||
lib.stack_size = 14752;
|
lib.stack_size = 24752;
|
||||||
} else {
|
} else {
|
||||||
// `--stack-first` option have been reenabled on wasm targets with https://github.com/ziglang/zig/pull/10572
|
// `--stack-first` option have been reenabled on wasm targets with https://github.com/ziglang/zig/pull/10572
|
||||||
std.log.warn("Update to Zig >=0.9.1 (or >=0.10.0-dev.258 for nightly) to detect stack overflows at runtime.", .{});
|
std.log.warn("Update to Zig >=0.9.1 (or >=0.10.0-dev.258 for nightly) to detect stack overflows at runtime.", .{});
|
||||||
|
|
38
src/main.zig
38
src/main.zig
|
@ -6,6 +6,7 @@ const input = @import("input.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
const Circuit = @import("circuit.zig");
|
const Circuit = @import("circuit.zig");
|
||||||
const Map = @import("map.zig");
|
const Map = @import("map.zig");
|
||||||
|
const Music = @import("music.zig");
|
||||||
|
|
||||||
const Vec2 = util.Vec2;
|
const Vec2 = util.Vec2;
|
||||||
const Vec2f = util.Vec2f;
|
const Vec2f = util.Vec2f;
|
||||||
|
@ -147,7 +148,7 @@ fn randRangeF(min: f32, max: f32) f32 {
|
||||||
|
|
||||||
// Global vars
|
// Global vars
|
||||||
const KB = 1024;
|
const KB = 1024;
|
||||||
var heap: [16 * KB]u8 = undefined;
|
var heap: [10 * KB]u8 = undefined;
|
||||||
var fba = std.heap.FixedBufferAllocator.init(&heap);
|
var fba = std.heap.FixedBufferAllocator.init(&heap);
|
||||||
var world: World = World.init(fba.allocator());
|
var world: World = World.init(fba.allocator());
|
||||||
var map: Map = undefined;
|
var map: Map = undefined;
|
||||||
|
@ -156,6 +157,7 @@ var particles: ParticleSystem = undefined;
|
||||||
var prng = std.rand.DefaultPrng.init(0);
|
var prng = std.rand.DefaultPrng.init(0);
|
||||||
var random = prng.random();
|
var random = prng.random();
|
||||||
var player: ?usize = null;
|
var player: ?usize = null;
|
||||||
|
var music = Music.Procedural.init(.C3, &Music.Minor, 83);
|
||||||
|
|
||||||
const anim_store = struct {
|
const anim_store = struct {
|
||||||
const stand = Anim.frame(0);
|
const stand = Anim.frame(0);
|
||||||
|
@ -177,6 +179,8 @@ const playerAnim = pac: {
|
||||||
break :pac animArr.slice();
|
break :pac animArr.slice();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const WireQuery = World.Query.require(&.{.wire});
|
||||||
|
|
||||||
fn showErr(msg: []const u8) noreturn {
|
fn showErr(msg: []const u8) noreturn {
|
||||||
w4.traceNoF(msg);
|
w4.traceNoF(msg);
|
||||||
unreachable;
|
unreachable;
|
||||||
|
@ -235,8 +239,7 @@ export fn update() void {
|
||||||
// Doing this before clearing the screen since the stack
|
// Doing this before clearing the screen since the stack
|
||||||
// reaches the screen during this block
|
// reaches the screen during this block
|
||||||
circuit.clear();
|
circuit.clear();
|
||||||
const q = World.Query.require(&.{.wire});
|
var wireIter = world.iter(WireQuery);
|
||||||
var wireIter = world.iter(q);
|
|
||||||
while (wireIter.next()) |wireID| {
|
while (wireIter.next()) |wireID| {
|
||||||
const e = world.get(wireID);
|
const e = world.get(wireID);
|
||||||
const nodes = e.wire.?.nodes.constSlice();
|
const nodes = e.wire.?.nodes.constSlice();
|
||||||
|
@ -259,8 +262,6 @@ export fn update() void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w4.DRAW_COLORS.* = 0x0004;
|
|
||||||
w4.rect(.{ 0, 0 }, .{ 160, 160 });
|
|
||||||
|
|
||||||
world.process(1, &.{.pos}, velocityProcess);
|
world.process(1, &.{.pos}, velocityProcess);
|
||||||
world.process(1, &.{ .pos, .physics }, physicsProcess);
|
world.process(1, &.{ .pos, .physics }, physicsProcess);
|
||||||
|
@ -271,8 +272,12 @@ export fn update() void {
|
||||||
world.process(1, &.{ .pos, .kinematic }, kinematicProcess);
|
world.process(1, &.{ .pos, .kinematic }, kinematicProcess);
|
||||||
world.process(1, &.{ .sprite, .staticAnim }, staticAnimProcess);
|
world.process(1, &.{ .sprite, .staticAnim }, staticAnimProcess);
|
||||||
world.process(1, &.{ .sprite, .controlAnim, .control }, controlAnimProcess);
|
world.process(1, &.{ .sprite, .controlAnim, .control }, controlAnimProcess);
|
||||||
world.process(1, &.{ .pos, .sprite }, drawProcess);
|
particles.update();
|
||||||
|
|
||||||
|
// Drawing
|
||||||
|
w4.DRAW_COLORS.* = 0x0004;
|
||||||
|
w4.rect(.{ 0, 0 }, .{ 160, 160 });
|
||||||
|
world.process(1, &.{ .pos, .sprite }, drawProcess);
|
||||||
map.draw();
|
map.draw();
|
||||||
|
|
||||||
for (circuit.cells) |cell, i| {
|
for (circuit.cells) |cell, i| {
|
||||||
|
@ -287,7 +292,6 @@ export fn update() void {
|
||||||
|
|
||||||
world.process(1, &.{.wire}, wireDrawProcess);
|
world.process(1, &.{.wire}, wireDrawProcess);
|
||||||
|
|
||||||
particles.update();
|
|
||||||
particles.draw();
|
particles.draw();
|
||||||
|
|
||||||
if (player) |p| {
|
if (player) |p| {
|
||||||
|
@ -298,7 +302,10 @@ export fn update() void {
|
||||||
circuit.isEnabled(pos + util.Dir.left) or
|
circuit.isEnabled(pos + util.Dir.left) or
|
||||||
circuit.isEnabled(pos + util.Dir.right);
|
circuit.isEnabled(pos + util.Dir.right);
|
||||||
if (shouldHum) {
|
if (shouldHum) {
|
||||||
w4.tone(.{ .start = 60 }, .{ .release = 255, .sustain = 0 }, 1, .{ .channel = .pulse1, .mode = .p50 });
|
// w4.tone(.{ .start = 60 }, .{ .release = 255, .sustain = 0 }, 1, .{ .channel = .pulse1, .mode = .p50 });
|
||||||
|
music.newIntensity = .active;
|
||||||
|
} else {
|
||||||
|
music.newIntensity = .calm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +319,8 @@ export fn update() void {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details.active) {
|
if (details.active) {
|
||||||
w4.tone(.{ .start = 60 }, .{ .release = 255, .sustain = 0 }, 10, .{ .channel = .pulse1, .mode = .p50 });
|
// w4.tone(.{ .start = 60 }, .{ .release = 255, .sustain = 0 }, 10, .{ .channel = .pulse1, .mode = .p50 });
|
||||||
|
music.newIntensity = .danger;
|
||||||
w4.DRAW_COLORS.* = 0x0020;
|
w4.DRAW_COLORS.* = 0x0020;
|
||||||
} else {
|
} else {
|
||||||
w4.DRAW_COLORS.* = 0x0030;
|
w4.DRAW_COLORS.* = 0x0030;
|
||||||
|
@ -325,6 +333,15 @@ export fn update() void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Music
|
||||||
|
const musicCommand = music.getNext(1);
|
||||||
|
if (musicCommand.freq) |freq| {
|
||||||
|
w4.tone(.{ .start = freq }, .{ .sustain = 2, .release = 2 }, 10, .{ .channel = .pulse2, .mode = .p50 });
|
||||||
|
}
|
||||||
|
if (musicCommand.drum) |drum| {
|
||||||
|
w4.tone(drum.freq, drum.duration, 10, .{ .channel = .triangle });
|
||||||
|
}
|
||||||
|
|
||||||
indicator = null;
|
indicator = null;
|
||||||
input.update();
|
input.update();
|
||||||
time += 1;
|
time += 1;
|
||||||
|
@ -396,8 +413,7 @@ fn wireManipulationProcess(_: f32, pos: *Pos, control: *Control) void {
|
||||||
} else {
|
} else {
|
||||||
const interactDistance = 4;
|
const interactDistance = 4;
|
||||||
var minDistance: f32 = interactDistance;
|
var minDistance: f32 = interactDistance;
|
||||||
const q = World.Query.require(&.{.wire});
|
var wireIter = world.iter(WireQuery);
|
||||||
var wireIter = world.iter(q);
|
|
||||||
var interactWireID: ?usize = null;
|
var interactWireID: ?usize = null;
|
||||||
var which: usize = 0;
|
var which: usize = 0;
|
||||||
while (wireIter.next()) |entityID| {
|
while (wireIter.next()) |entityID| {
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
const w4 = @import("wasm4.zig");
|
||||||
|
|
||||||
|
const midiNote = [_]u16{
|
||||||
|
8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15,
|
||||||
|
15, 16, 17, 18, 19, 21, 22, 23, 24, 26, 28,
|
||||||
|
29, 31, 33, 35, 37, 39, 41, 44, 46, 49, 52,
|
||||||
|
55, 58, 62, 65, 69, 73, 78, 82, 87, 92, 98,
|
||||||
|
104, 110, 117, 123, 131, 139, 147, 156, 165, 175, 185,
|
||||||
|
196, 208, 220, 233, 247, 262, 277, 294, 311, 330, 349,
|
||||||
|
370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659,
|
||||||
|
698, 740, 784, 831, 880, 932, 988, 1047, 1109, 1175, 1245,
|
||||||
|
1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349,
|
||||||
|
2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951, 4186, 4435,
|
||||||
|
4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902, 8372,
|
||||||
|
8870, 9397, 9956, 10548, 11175, 11840, 12544,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Note = enum(usize) { C3 = 57, C4 = 69 };
|
||||||
|
|
||||||
|
// Defines steps along a musical scale
|
||||||
|
pub const Major = [8]usize{ 0, 2, 4, 5, 7, 9, 11, 12 };
|
||||||
|
pub const Minor = [8]usize{ 0, 2, 3, 5, 7, 8, 11, 12 };
|
||||||
|
|
||||||
|
pub const MusicCommand = struct {
|
||||||
|
freq: ?u16 = null,
|
||||||
|
drum: ?struct { freq: w4.ToneFrequency, duration: w4.ToneDuration } = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Intensity = enum(u8) {
|
||||||
|
calm = 0,
|
||||||
|
active = 1,
|
||||||
|
danger = 2,
|
||||||
|
pub fn atLeast(lhs: @This(), rhs: @This()) bool {
|
||||||
|
return @enumToInt(lhs) >= @enumToInt(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Procedural = struct {
|
||||||
|
tick: usize,
|
||||||
|
note: usize,
|
||||||
|
beat: usize,
|
||||||
|
beatsPerBar: usize,
|
||||||
|
seed: usize,
|
||||||
|
root: usize,
|
||||||
|
scale: []const usize,
|
||||||
|
|
||||||
|
intensity: Intensity = .calm,
|
||||||
|
newIntensity: ?Intensity = null,
|
||||||
|
|
||||||
|
pub fn init(root: Note, scale: []const usize, seed: usize) @This() {
|
||||||
|
return @This(){
|
||||||
|
.tick = 0,
|
||||||
|
.beat = 15,
|
||||||
|
.beatsPerBar = 6,
|
||||||
|
.seed = seed,
|
||||||
|
.root = @enumToInt(root),
|
||||||
|
.scale = scale,
|
||||||
|
.note = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getNext(this: *@This(), dt: u32) MusicCommand {
|
||||||
|
var cmd = MusicCommand{};
|
||||||
|
const beatProgress = this.tick % this.beat;
|
||||||
|
const beatTotal = @divTrunc(this.tick, this.beat);
|
||||||
|
const beat = beatTotal % this.beatsPerBar;
|
||||||
|
const bar = @divTrunc(beat, this.beatsPerBar);
|
||||||
|
this.tick += dt;
|
||||||
|
if (beat == 0) this.intensity = this.newIntensity orelse this.intensity;
|
||||||
|
if (this.intensity.atLeast(.active) and bar % 2 == 0 and beatProgress == 0) {
|
||||||
|
cmd.freq = midiNote[this.root + this.scale[((this.seed * this.note) % 313) % 8]];
|
||||||
|
this.note += 1;
|
||||||
|
}
|
||||||
|
if (this.intensity.atLeast(.calm) and beat == 0) cmd.drum = .{
|
||||||
|
.freq = .{ .start = 100, .end = 1 },
|
||||||
|
.duration = .{ .sustain = 1, .release = 4 },
|
||||||
|
};
|
||||||
|
if (this.intensity.atLeast(.danger) and beat % 3 == 1) cmd.drum = .{
|
||||||
|
.freq = .{ .start = 1761 },
|
||||||
|
.duration = .{ .release = 6 },
|
||||||
|
};
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue