Remove sprites.png, improve music

master
Louis Pearson 2022-01-21 20:37:50 -07:00
parent aebd05de18
commit 7dcc08c557
10 changed files with 76 additions and 43 deletions

View File

@ -1,3 +1,2 @@
pub usingnamespace @import("tiles.zig"); pub usingnamespace @import("tiles.zig");
pub usingnamespace @import("sprites.zig");
pub usingnamespace @import("maps/map.zig"); pub usingnamespace @import("maps/map.zig");

View File

@ -1,4 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.5" tiledversion="1.7.2" name="wired" tilewidth="8" tileheight="8" tilecount="256" columns="16"> <tileset version="1.5" tiledversion="1.7.2" name="wired" tilewidth="8" tileheight="8" tilecount="256" columns="16">
<editorsettings>
<export target="wired.json" format="json"/>
</editorsettings>
<image source="../tiles.png" width="128" height="128"/> <image source="../tiles.png" width="128" height="128"/>
</tileset> </tileset>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

After

Width:  |  Height:  |  Size: 790 B

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env bash
w4 png2src --template assets/assets-template --zig assets/tiles.png -o assets/tiles.zig w4 png2src --template assets/assets-template --zig assets/tiles.png -o assets/tiles.zig
w4 png2src --template assets/assets-template --zig assets/sprites.png -o assets/sprites.zig
zig run map2src.zig -- assets/maps/map.zig assets/maps/test.json zig run map2src.zig -- assets/maps/map.zig assets/maps/test.json

View File

@ -218,7 +218,9 @@ const Queue = struct {
}; };
const w4 = @import("wasm4.zig"); const w4 = @import("wasm4.zig");
pub fn fill(this: *@This(), rootRaw: Cell) void { // Returns number of cells filled
pub fn fill(this: *@This(), rootRaw: Cell) usize {
var count: usize = 0;
const root = rootRaw - this.offset; const root = rootRaw - this.offset;
var visited = std.StaticBitSet(MAXCELLS).initEmpty(); var visited = std.StaticBitSet(MAXCELLS).initEmpty();
var q = Queue.init(); var q = Queue.init();
@ -229,6 +231,7 @@ pub fn fill(this: *@This(), rootRaw: Cell) void {
if (visited.isSet(index)) continue; if (visited.isSet(index)) continue;
visited.set(index); visited.set(index);
this.enable(cell); this.enable(cell);
count += 1;
for (get_inputs(tile)) |conductor, i| { for (get_inputs(tile)) |conductor, i| {
if (!conductor) continue; if (!conductor) continue;
const s = @intToEnum(Side, i); const s = @intToEnum(Side, i);
@ -248,6 +251,7 @@ pub fn fill(this: *@This(), rootRaw: Cell) void {
} }
} }
} }
return count;
} }
pub fn clear(this: *@This()) void { pub fn clear(this: *@This()) void {

View File

@ -160,11 +160,11 @@ var player: ?usize = null;
var music = Music.Procedural.init(.C3, &Music.Minor, 83); 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(8);
const walk = Anim.simple(4, &[_]usize{ 1, 2, 3, 4 }); const walk = Anim.simple(4, &[_]usize{ 9, 10, 11, 12 });
const jump = Anim.frame(5); const jump = Anim.frame(13);
const fall = Anim.frame(6); const fall = Anim.frame(14);
const wallSlide = Anim.frame(7); const wallSlide = Anim.frame(15);
}; };
const AnimData = []const Anim.Ops; const AnimData = []const Anim.Ops;
@ -201,7 +201,7 @@ export fn start() void {
player = world.create(.{ player = world.create(.{
.pos = Pos.init(util.vec2ToVec2f((assets.spawn - mapPos) * Map.tile_size) + Vec2f{ 4, 8 }), .pos = Pos.init(util.vec2ToVec2f((assets.spawn - mapPos) * Map.tile_size) + Vec2f{ 4, 8 }),
.control = .{ .controller = .player, .state = .stand }, .control = .{ .controller = .player, .state = .stand },
.sprite = .{ .offset = .{ -4, -8 }, .size = .{ 8, 8 }, .index = 0, .flags = .{ .bpp = .b1 } }, .sprite = .{ .offset = .{ -4, -8 }, .size = .{ 8, 8 }, .index = 8, .flags = .{ .bpp = .b2 } },
.physics = .{ .friction = Vec2f{ 0.15, 0.1 }, .gravity = Vec2f{ 0, 0.25 } }, .physics = .{ .friction = Vec2f{ 0.15, 0.1 }, .gravity = Vec2f{ 0, 0.25 } },
.controlAnim = ControlAnim{ .controlAnim = ControlAnim{
.anims = playerAnim, .anims = playerAnim,
@ -248,8 +248,16 @@ export fn update() void {
circuit.bridge(.{ cellBegin, cellEnd }, wireID); circuit.bridge(.{ cellBegin, cellEnd }, wireID);
} }
var count: usize = 0;
for (assets.sources) |source| { for (assets.sources) |source| {
circuit.fill(source); count += circuit.fill(source);
}
if (count < 30) {
music.newIntensity = .calm;
} else if (count < 60) {
music.newIntensity = .active;
} else {
music.newIntensity = .danger;
} }
var wireComponents = world.components.items(.wire); var wireComponents = world.components.items(.wire);
var enabledWires = circuit.enabledBridges(); var enabledWires = circuit.enabledBridges();
@ -302,10 +310,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; // music.newIntensity = .active;
} else { } else {
music.newIntensity = .calm; // music.newIntensity = .calm;
} }
} }
@ -320,7 +328,7 @@ 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; // music.newIntensity = .danger;
w4.DRAW_COLORS.* = 0x0020; w4.DRAW_COLORS.* = 0x0020;
} else { } else {
w4.DRAW_COLORS.* = 0x0030; w4.DRAW_COLORS.* = 0x0030;
@ -335,11 +343,8 @@ export fn update() void {
// Music // Music
const musicCommand = music.getNext(1); const musicCommand = music.getNext(1);
if (musicCommand.freq) |freq| { for (musicCommand.constSlice()) |sfx| {
w4.tone(.{ .start = freq }, .{ .sustain = 2, .release = 2 }, 10, .{ .channel = .pulse2, .mode = .p50 }); w4.tone(sfx.freq, sfx.duration, sfx.volume, sfx.flags);
}
if (musicCommand.drum) |drum| {
w4.tone(drum.freq, drum.duration, 10, .{ .channel = .triangle });
} }
indicator = null; indicator = null;
@ -540,8 +545,9 @@ fn drawProcess(_: f32, pos: *Pos, sprite: *Sprite) void {
w4.DRAW_COLORS.* = 0x0010; w4.DRAW_COLORS.* = 0x0010;
const fpos = pos.pos + sprite.offset; const fpos = pos.pos + sprite.offset;
const ipos = w4.Vec2{ @floatToInt(i32, fpos[0]), @floatToInt(i32, fpos[1]) }; const ipos = w4.Vec2{ @floatToInt(i32, fpos[0]), @floatToInt(i32, fpos[1]) };
const t = w4.Vec2{ @intCast(i32, (sprite.index * 8) % 128), @intCast(i32, (sprite.index * 8) / 128) }; const index = sprite.index;
w4.blitSub(&assets.sprites, ipos, sprite.size, t, 128, sprite.flags); const t = w4.Vec2{ @intCast(i32, (index * 8) % 128), @intCast(i32, (index * 8) / 128) };
w4.blitSub(&assets.tiles, ipos, sprite.size, t, 128, sprite.flags);
} }
fn staticAnimProcess(_: f32, sprite: *Sprite, anim: *StaticAnim) void { fn staticAnimProcess(_: f32, sprite: *Sprite, anim: *StaticAnim) void {
@ -556,6 +562,7 @@ fn controlAnimProcess(_: f32, sprite: *Sprite, anim: *ControlAnim, control: *Con
.fall => 3, .fall => 3,
.wallSlide => 4, .wallSlide => 4,
}; };
if (a != 0) music.walking = true else music.walking = false;
sprite.flags.flip_x = (control.facing == .left); sprite.flags.flip_x = (control.facing == .left);
anim.state.play(anim.anims[a]); anim.state.play(anim.anims[a]);
anim.state.update(&sprite.index); anim.state.update(&sprite.index);

View File

@ -1,3 +1,4 @@
const std = @import("std");
const w4 = @import("wasm4.zig"); const w4 = @import("wasm4.zig");
const midiNote = [_]u16{ const midiNote = [_]u16{
@ -21,11 +22,15 @@ pub const Note = enum(usize) { C3 = 57, C4 = 69 };
pub const Major = [8]usize{ 0, 2, 4, 5, 7, 9, 11, 12 }; 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 Minor = [8]usize{ 0, 2, 3, 5, 7, 8, 11, 12 };
pub const MusicCommand = struct { pub const Sfx = struct {
freq: ?u16 = null, freq: w4.ToneFrequency,
drum: ?struct { freq: w4.ToneFrequency, duration: w4.ToneDuration } = null, duration: w4.ToneDuration,
volume: u8,
flags: w4.ToneFlags,
}; };
pub const MusicCommand = std.BoundedArray(Sfx, 4);
pub const Intensity = enum(u8) { pub const Intensity = enum(u8) {
calm = 0, calm = 0,
active = 1, active = 1,
@ -44,6 +49,7 @@ pub const Procedural = struct {
root: usize, root: usize,
scale: []const usize, scale: []const usize,
walking: bool = false,
intensity: Intensity = .calm, intensity: Intensity = .calm,
newIntensity: ?Intensity = null, newIntensity: ?Intensity = null,
@ -59,26 +65,47 @@ pub const Procedural = struct {
}; };
} }
fn nextNote(this: @This(), t: usize) u16 {
return midiNote[this.root + this.scale[((this.seed * t) % 313) % 8]];
}
pub fn getNext(this: *@This(), dt: u32) MusicCommand { pub fn getNext(this: *@This(), dt: u32) MusicCommand {
var cmd = MusicCommand{}; var cmd = MusicCommand.init(0) catch unreachable;
const beatProgress = this.tick % this.beat; const beatProgress = this.tick % this.beat;
const beatTotal = @divTrunc(this.tick, this.beat); const beatTotal = @divTrunc(this.tick, this.beat);
const beat = beatTotal % this.beatsPerBar; const beat = beatTotal % this.beatsPerBar;
const bar = @divTrunc(beat, this.beatsPerBar); const bar = @divTrunc(beatTotal, this.beatsPerBar);
this.tick += dt; this.tick += dt;
if (beat == 0) this.intensity = this.newIntensity orelse this.intensity; if (beat == 0) this.intensity = this.newIntensity orelse this.intensity;
if (this.intensity.atLeast(.active) and bar % 2 == 0 and beatProgress == 0) { const playNote = beat % 2 == 0 and bar % 4 < 2;
cmd.freq = midiNote[this.root + this.scale[((this.seed * this.note) % 313) % 8]]; if (this.intensity.atLeast(.active) and playNote and beatProgress == 0) {
// const notelen = @intCast(u8, this.beat * this.beatsPerBar);
cmd.append(Sfx{
.freq = .{ .start = this.nextNote(this.note) },
.duration = .{ .sustain = 5, .release = 5 },
.volume = 10,
.flags = .{ .channel = .pulse2, .mode = .p25 },
}) catch unreachable;
this.note += 1; this.note += 1;
} }
if (this.intensity.atLeast(.calm) and beat == 0) cmd.drum = .{ if (this.intensity.atLeast(.calm) and beat == 0 and beatProgress == 0) cmd.append(.{
.freq = .{ .start = 100, .end = 1 }, .freq = .{ .start = 220, .end = 110 },
.duration = .{ .sustain = 1, .release = 4 }, .duration = .{ .release = 3 },
}; .volume = 20,
if (this.intensity.atLeast(.danger) and beat % 3 == 1) cmd.drum = .{ .flags = .{ .channel = .triangle },
.freq = .{ .start = 1761 }, }) catch unreachable;
.duration = .{ .release = 6 }, if (this.intensity.atLeast(.active) and beat == this.beatsPerBar / 2 and beatProgress == 0) cmd.append(.{
}; .freq = .{ .start = 110, .end = 55 },
.duration = .{ .release = 3 },
.volume = 20,
.flags = .{ .channel = .triangle },
}) catch unreachable;
if (this.walking and beat % 3 == 1 and beatProgress == 7) cmd.append(.{
.freq = .{ .start = 1761, .end = 1 },
.duration = .{ .release = 5 },
.volume = 5,
.flags = .{ .channel = .noise },
}) catch unreachable;
return cmd; return cmd;
} }
}; };