diff --git a/src/component.zig b/src/component.zig new file mode 100644 index 0000000..6874478 --- /dev/null +++ b/src/component.zig @@ -0,0 +1,59 @@ +const std = @import("std"); +const w4 = @import("wasm4.zig"); +const util = @import("util.zig"); +const Vec2 = util.Vec2; +const Vec2f = util.Vec2f; +const AABB = util.AABB; +const Anim = @import("anim.zig"); + +const approxEqAbs = std.math.approxEqAbs; +const AnimData = []const Anim.Ops; + +// Components +pub const Pos = struct { + pos: Vec2f, + last: Vec2f, + pinned: bool = false, + pub fn init(pos: Vec2f) @This() { + return @This(){ .pos = pos, .last = pos }; + } + pub fn initVel(pos: Vec2f, vel: Vec2f) @This() { + return @This(){ .pos = pos, .last = pos - vel }; + } +}; +pub const Control = struct { + controller: enum { player }, + state: enum { stand, walk, jump, fall, wallSlide }, + facing: enum { left, right, up, down } = .right, + grabbing: ?struct { id: usize, which: usize } = null, +}; +pub const Sprite = struct { + offset: Vec2 = Vec2{ 0, 0 }, + size: w4.Vec2, + index: usize, + flags: w4.BlitFlags, +}; +pub const StaticAnim = Anim; +pub const ControlAnim = struct { anims: []AnimData, state: Anim }; +pub const Kinematic = struct { + col: AABB, + move: Vec2f = Vec2f{ 0, 0 }, + lastCol: Vec2f = Vec2f{ 0, 0 }, + + pub fn inAir(this: @This()) bool { + return approxEqAbs(f32, this.lastCol[1], 0, 0.01); + } + + pub fn onFloor(this: @This()) bool { + return approxEqAbs(f32, this.move[1], 0, 0.01) and this.lastCol[1] > 0; + } + + pub fn isFalling(this: @This()) bool { + return this.move[1] > 0 and approxEqAbs(f32, this.lastCol[1], 0, 0.01); + } + + pub fn onWall(this: @This()) bool { + return this.isFalling() and !approxEqAbs(f32, this.lastCol[0], 0, 0.01); + } +}; +pub const Physics = struct { gravity: Vec2f, friction: Vec2f }; diff --git a/src/disk.zig b/src/disk.zig new file mode 100644 index 0000000..e1f6b84 --- /dev/null +++ b/src/disk.zig @@ -0,0 +1,243 @@ +const assets = @import("assets"); +const std = @import("std"); +const util = @import("util.zig"); +const w4 = @import("wasm4.zig"); +const game = @import("game.zig"); +const comp = @import("component.zig"); +const Anim = @import("anim.zig"); + +const Pos = comp.Pos; +const Vec2 = util.Vec2; + +const SaveObj = enum(u4) { + Player, + Coin, + WireBeginPinned, + WireBeginLoose, + WireEndPinned, + WireEndLoose, +}; + +fn cell2u8(cell: util.Cell) [2]u8 { + return [_]u8{ @intCast(u8, cell[0]), @intCast(u8, cell[1]) }; +} + +fn vec2u16(vec2: util.Vec2) [2]u16 { + return [_]u16{ @intCast(u16, vec2[0]), @intCast(u16, vec2[1]) }; +} + +fn write_diff(writer: anytype, stride: usize, initial: []const u8, mapBuf: []const u8) !u8 { + var written: u8 = 0; + for (initial) |init_tile, i| { + if (mapBuf[i] != init_tile) { + const x = @intCast(u8, i % @intCast(usize, stride)); + const y = @intCast(u8, @divTrunc(i, @intCast(usize, stride))); + const temp = [3]u8{ x, y, mapBuf[i] }; + try writer.writeAll(&temp); + written += 1; + } + } + return written; +} + +fn load_diff(mapBuf: []u8, stride: usize, diff: []const u8) void { + var i: usize = 0; + while (i < diff.len) : (i += 3) { + const x = diff[i]; + const y = diff[i + 1]; + const tile = diff[i + 2]; + const a = x + y * stride; + mapBuf[a] = tile; + // this.set_cell(Cell{ x, y }, tile); + } +} + +pub fn reset() void { + // TODO: implement reset + // This function should reset the game world without clearing the scores list, + // so a player can see how well they've done with the game in the past. +} + +pub fn load() bool { + var load_buf: [1024]u8 = undefined; + const read = w4.diskr(&load_buf, 1024); + w4.tracef("%d bytes read", read); + + // if (true) return false; + if (read <= 0) return false; + // for (load_buf[0 .. read - 1]) |byte| w4.tracef("%d", byte); + + var stream = std.io.fixedBufferStream(load_buf[0..read]); + var reader = stream.reader(); + + var header: [5]u8 = undefined; + _ = reader.read(&header) catch w4.tracef("couldn't load header"); + w4.tracef("%s", &header); + if (!std.mem.eql(u8, "wired", &header)) return false; // w4.tracef("did not load, incorrect header bytes"); + + game.score = reader.readByte() catch return false; + + const obj_len = reader.readByte() catch return false; + // const map_len = reader.readByte() catch return false; + const conduit_len = reader.readByte() catch return false; + + var i: usize = 0; + while (i < obj_len) : (i += 1) { + const b = reader.readByte() catch return false; + const obj = @intToEnum(SaveObj, @truncate(u4, b)); + const id = @truncate(u4, b >> 4); + const x = reader.readIntBig(u16) catch return false; + const y = reader.readIntBig(u16) catch return false; + var pos = Pos.init(util.vec2ToVec2f(Vec2{ x, y })); + switch (obj) { + .Player => { + w4.tracef("player at %d, %d", x, y); + game.player.pos = pos; + // player.pos.pos += Vec2f{ 4, 6 }; + }, + .Coin => { + game.coins.append(.{ + .pos = pos, + .sprite = .{ .offset = .{ 0, 0 }, .size = .{ 8, 8 }, .index = 4, .flags = .{ .bpp = .b2 } }, + .anim = Anim{ .anim = &game.anim_store.coin }, + .area = .{ .pos = .{ 0, 0 }, .size = .{ 8, 8 } }, + }) catch unreachable; + }, + .WireBeginPinned => { + var begin = game.wires.slice()[id].begin(); + begin.* = pos; + begin.pinned = true; + game.wires.slice()[id].straighten(); + }, + .WireBeginLoose => { + var begin = game.wires.slice()[id].begin(); + begin.* = pos; + begin.pinned = false; + game.wires.slice()[id].straighten(); + }, + .WireEndPinned => { + var end = game.wires.slice()[id].end(); + end.* = pos; + end.pinned = true; + game.wires.slice()[id].straighten(); + }, + .WireEndLoose => { + var end = game.wires.slice()[id].end(); + end.* = pos; + end.pinned = false; + game.wires.slice()[id].straighten(); + }, + } + } + + // Load map + var buf: [256]u8 = undefined; + // const len = reader.readByte() catch return; + // const bytes_map = reader.read(buf[0 .. map_len * 3]) catch return false; + // w4.tracef("loading %d map diffs... %d bytes", map_len, bytes_map); + // load_diff(&solids_mutable, assets.solid_size[0], buf[0..bytes_map]); + + // Load conduit + // const conduit_len = reader.readByte() catch return; + const bytes_conduit = reader.read(buf[0 .. conduit_len * 3]) catch return false; + w4.tracef("loading %d conduit diffs... %d bytes", conduit_len, bytes_conduit); + for (buf[0..bytes_conduit]) |byte| w4.tracef("%d", byte); + load_diff(&game.conduit_mutable, assets.conduit_size[0], buf[0..bytes_conduit]); + + return true; +} + +pub fn save() void { + var save_buf: [1024]u8 = undefined; + var save_stream = std.io.fixedBufferStream(&save_buf); + var save_writer = save_stream.writer(); + save_writer.writeAll("wired") catch return w4.tracef("Couldn't write header"); + save_writer.writeByte(game.score) catch return w4.tracef("Couldn't save score"); + w4.tracef("score %d written", game.score); + + // Write temporary length values + const lengths_start = save_stream.getPos() catch return w4.tracef("Couldn't get pos"); + save_writer.writeByte(0) catch return w4.tracef("Couldn't write obj length"); + // save_writer.writeByte(0) catch return w4.tracef("Couldn't write map length"); + save_writer.writeByte(0) catch return w4.tracef("Couldn't write conduit length"); + + // Write player + const playerPos = vec2u16(util.vec2fToVec2(game.player.pos.pos)); + save_writer.writeByte(@enumToInt(SaveObj.Player)) catch return w4.tracef("Player"); + save_writer.writeIntBig(u16, playerPos[0]) catch return; + save_writer.writeIntBig(u16, playerPos[1]) catch return; + // save_writer.writeAll(&[_]u8{ @enumToInt(SaveObj.Player), @intCast(u8, player + var obj_len: u8 = 1; + + for (game.coins.slice()) |coin, i| { + obj_len += 1; + const id = @intCast(u8, @truncate(u4, i)) << 4; + // const cell = util.world2cell(coin.pos.pos); + save_writer.writeByte(@enumToInt(SaveObj.Coin) | id) catch return w4.tracef("Couldn't save coin"); + const pos = vec2u16(util.vec2fToVec2(coin.pos.pos)); + save_writer.writeIntBig(u16, pos[0]) catch return; + save_writer.writeIntBig(u16, pos[1]) catch return; + // save_writer.writeInt(&) catch return; + } + + // Write wires + for (game.wires.slice()) |*wire, i| { + const id = @intCast(u8, @truncate(u4, i)) << 4; + const begin = wire.begin(); + const end = wire.end(); + obj_len += 1; + if (begin.pinned) { + // const cell = util.world2cell(begin.pos); + save_writer.writeByte(@enumToInt(SaveObj.WireBeginPinned) | id) catch return w4.tracef("Couldn't save wire"); + // const pos = cell2u16(cell); + const pos = vec2u16(util.vec2fToVec2(begin.pos)); + save_writer.writeIntBig(u16, pos[0]) catch return; + save_writer.writeIntBig(u16, pos[1]) catch return; + // save_writer.writeAll(&cell2u8(cell)) catch return; + } else { + // const cell = util.world2cell(begin.pos); + save_writer.writeByte(@enumToInt(SaveObj.WireBeginLoose) | id) catch return w4.tracef("Couldn't save wire"); + // const pos = cell2u16(cell); + const pos = vec2u16(util.vec2fToVec2(begin.pos)); + save_writer.writeIntBig(u16, pos[0]) catch return; + save_writer.writeIntBig(u16, pos[1]) catch return; + // save_writer.writeAll(&cell2u8(cell)) catch return; + } + obj_len += 1; + if (end.pinned) { + // const cell = util.world2cell(end.pos); + save_writer.writeByte(@enumToInt(SaveObj.WireEndPinned) | id) catch return w4.tracef("Couldn't save wire"); + // const pos = cell2u16(cell); + const pos = vec2u16(util.vec2fToVec2(end.pos)); + save_writer.writeIntBig(u16, pos[0]) catch return; + save_writer.writeIntBig(u16, pos[1]) catch return; + // save_writer.writeAll(&cell2u8(cell)) catch return; + } else { + // const cell = util.world2cell(end.pos); + save_writer.writeByte(@enumToInt(SaveObj.WireEndLoose) | id) catch return w4.tracef("Couldn't save wire"); + // const pos = cell2u16(cell); + const pos = vec2u16(util.vec2fToVec2(end.pos)); + save_writer.writeIntBig(u16, pos[0]) catch return; + save_writer.writeIntBig(u16, pos[1]) catch return; + // save_writer.writeAll(&cell2u8(cell)) catch return; + } + } + + // Write map + // const map_len = write_diff(save_writer, assets.solid_size[0], &assets.solid, &solids_mutable) catch return w4.tracef("Couldn't save map diff"); + + // Write conduit + const conduit_len = write_diff(save_writer, assets.conduit_size[0], &assets.conduit, &game.conduit_mutable) catch return w4.tracef("Couldn't save map diff"); + + const endPos = save_stream.getPos() catch return; + save_stream.seekTo(lengths_start) catch w4.tracef("Couldn't seek"); + save_writer.writeByte(obj_len) catch return w4.tracef("Couldn't write obj length"); + // save_writer.writeByte(map_len) catch return w4.tracef("Couldn't write map length"); + save_writer.writeByte(conduit_len) catch return w4.tracef("Couldn't write conduit length"); + + save_stream.seekTo(endPos) catch return; + const save_slice = save_stream.getWritten(); + const written = w4.diskw(save_slice.ptr, save_slice.len); + w4.tracef("%d bytes written", written); + for (save_buf[0..written]) |byte| w4.tracef("%d", byte); +} diff --git a/src/game.zig b/src/game.zig index 49e097d..fa4d32e 100644 --- a/src/game.zig +++ b/src/game.zig @@ -7,59 +7,24 @@ const Circuit = @import("circuit.zig"); const Map = @import("map.zig"); const Music = @import("music.zig"); const State = @import("main.zig").State; +const Disk = @import("disk.zig"); const Vec2 = util.Vec2; const Vec2f = util.Vec2f; const AABB = util.AABB; const Anim = @import("anim.zig"); -// Components -const Pos = struct { - pos: Vec2f, - last: Vec2f, - pinned: bool = false, - pub fn init(pos: Vec2f) @This() { - return @This(){ .pos = pos, .last = pos }; - } - pub fn initVel(pos: Vec2f, vel: Vec2f) @This() { - return @This(){ .pos = pos, .last = pos - vel }; - } -}; -const Control = struct { - controller: enum { player }, - state: enum { stand, walk, jump, fall, wallSlide }, - facing: enum { left, right, up, down } = .right, - grabbing: ?struct { id: usize, which: usize } = null, -}; -const Sprite = struct { - offset: Vec2 = Vec2{ 0, 0 }, - size: w4.Vec2, - index: usize, - flags: w4.BlitFlags, -}; -const StaticAnim = Anim; -const ControlAnim = struct { anims: []AnimData, state: Anim }; -const Kinematic = struct { - col: AABB, - move: Vec2f = Vec2f{ 0, 0 }, - lastCol: Vec2f = Vec2f{ 0, 0 }, +const comp = @import("component.zig"); - pub fn inAir(this: @This()) bool { - return approxEqAbs(f32, this.lastCol[1], 0, 0.01); - } +const Pos = comp.Pos; +const Control = comp.Control; +const Sprite = comp.Sprite; +const ControlAnim = comp.ControlAnim; +const StaticAnim = comp.StaticAnim; +const Kinematic = comp.Kinematic; +const Physics = comp.Physics; +const AnimData = []const Anim.Ops; - pub fn onFloor(this: @This()) bool { - return approxEqAbs(f32, this.move[1], 0, 0.01) and this.lastCol[1] > 0; - } - - pub fn isFalling(this: @This()) bool { - return this.move[1] > 0 and approxEqAbs(f32, this.lastCol[1], 0, 0.01); - } - - pub fn onWall(this: @This()) bool { - return this.isFalling() and !approxEqAbs(f32, this.lastCol[0], 0, 0.01); - } -}; const Wire = struct { nodes: std.BoundedArray(Pos, 32) = std.BoundedArray(Pos, 32).init(0), enabled: bool = false, @@ -82,7 +47,7 @@ const Wire = struct { } } }; -const Physics = struct { gravity: Vec2f, friction: Vec2f }; + const Player = struct { pos: Pos, control: Control, @@ -91,7 +56,6 @@ const Player = struct { kinematic: Kinematic, physics: Physics, }; -// const World = ecs.World(Component); const Particle = struct { pos: Pos, @@ -176,14 +140,14 @@ var circuit: Circuit = undefined; var particles: ParticleSystem = undefined; var prng = std.rand.DefaultPrng.init(0); var random = prng.random(); -var player: Player = undefined; +pub var player: Player = undefined; var music = Music.Procedural.init(.C3, &Music.Minor, 83); -var wires = std.BoundedArray(Wire, 10).init(0) catch unreachable; +pub var wires = std.BoundedArray(Wire, 10).init(0) catch unreachable; var camera = Vec2{ 0, 0 }; const Coin = struct { pos: Pos, sprite: Sprite, anim: Anim, area: AABB }; -var coins = std.BoundedArray(Coin, 20).init(0) catch unreachable; -var score: u8 = 0; +pub var coins = std.BoundedArray(Coin, 20).init(0) catch unreachable; +pub var score: u8 = 0; var ScoreCoin = Sprite{ .size = Map.tile_size, .index = 4, @@ -191,20 +155,18 @@ var ScoreCoin = Sprite{ }; var solids_mutable = assets.solid; -var conduit_mutable = assets.conduit; +pub var conduit_mutable = assets.conduit; var conduitLevels_mutable: [conduit_mutable.len]u8 = undefined; -const anim_store = struct { +pub const anim_store = struct { const stand = Anim.frame(8); const walk = Anim.simple(4, &[_]usize{ 9, 10, 11, 12 }); const jump = Anim.frame(13); const fall = Anim.frame(14); const wallSlide = Anim.frame(15); - const coin = Anim.simple(15, &[_]usize{ 4, 5, 6 }); + pub const coin = Anim.simple(15, &[_]usize{ 4, 5, 6 }); }; -const AnimData = []const Anim.Ops; - const playerAnim = pac: { var animArr = std.BoundedArray(AnimData, 100).init(0) catch unreachable; animArr.append(&anim_store.stand) catch unreachable; @@ -269,7 +231,7 @@ pub fn start() void { } // _ = w4.diskw("", 0); - if (!load()) { + if (!Disk.load()) { for (assets.coins) |coin| { coins.append(.{ .pos = Pos.init(util.vec2ToVec2f(coin * tile_size)), @@ -326,12 +288,12 @@ pub fn update(time: usize) State { _ = coins.swapRemove(i); } // We save here to prevent duplicate coins - if (shouldSave) save(); + if (shouldSave) Disk.save(); } const newCamera = @divTrunc(util.world2cell(player.pos.pos), @splat(2, @as(i32, 20))) * @splat(2, @as(i32, 20)); if (!@reduce(.And, newCamera == camera)) { - save(); + Disk.save(); } camera = newCamera; @@ -417,233 +379,6 @@ pub fn update(time: usize) State { return .Game; } -fn write_diff(writer: anytype, stride: usize, initial: []const u8, mapBuf: []const u8) !u8 { - var written: u8 = 0; - for (initial) |init_tile, i| { - if (mapBuf[i] != init_tile) { - const x = @intCast(u8, i % @intCast(usize, stride)); - const y = @intCast(u8, @divTrunc(i, @intCast(usize, stride))); - const temp = [3]u8{ x, y, mapBuf[i] }; - try writer.writeAll(&temp); - written += 1; - } - } - return written; -} - -pub fn load_diff(mapBuf: []u8, stride: usize, diff: []const u8) void { - var i: usize = 0; - while (i < diff.len) : (i += 3) { - const x = diff[i]; - const y = diff[i + 1]; - const tile = diff[i + 2]; - const a = x + y * stride; - mapBuf[a] = tile; - // this.set_cell(Cell{ x, y }, tile); - } -} - -fn load() bool { - var load_buf: [1024]u8 = undefined; - const read = w4.diskr(&load_buf, 1024); - w4.tracef("%d bytes read", read); - - // if (true) return false; - if (read <= 0) return false; - // for (load_buf[0 .. read - 1]) |byte| w4.tracef("%d", byte); - - var stream = std.io.fixedBufferStream(load_buf[0..read]); - var reader = stream.reader(); - - var header: [5]u8 = undefined; - _ = reader.read(&header) catch w4.tracef("couldn't load header"); - w4.tracef("%s", &header); - if (!std.mem.eql(u8, "wired", &header)) return false; // w4.tracef("did not load, incorrect header bytes"); - - score = reader.readByte() catch return false; - - const obj_len = reader.readByte() catch return false; - // const map_len = reader.readByte() catch return false; - const conduit_len = reader.readByte() catch return false; - - var i: usize = 0; - while (i < obj_len) : (i += 1) { - const b = reader.readByte() catch return false; - const obj = @intToEnum(SaveObj, @truncate(u4, b)); - const id = @truncate(u4, b >> 4); - const x = reader.readIntBig(u16) catch return false; - const y = reader.readIntBig(u16) catch return false; - var pos = Pos.init(util.vec2ToVec2f(Vec2{ x, y })); - switch (obj) { - .Player => { - w4.tracef("player at %d, %d", x, y); - player.pos = pos; - // player.pos.pos += Vec2f{ 4, 6 }; - }, - .Coin => { - coins.append(.{ - .pos = pos, - .sprite = .{ .offset = .{ 0, 0 }, .size = .{ 8, 8 }, .index = 4, .flags = .{ .bpp = .b2 } }, - .anim = Anim{ .anim = &anim_store.coin }, - .area = .{ .pos = .{ 0, 0 }, .size = .{ 8, 8 } }, - }) catch unreachable; - }, - .WireBeginPinned => { - var begin = wires.slice()[id].begin(); - begin.* = pos; - begin.pinned = true; - wires.slice()[id].straighten(); - }, - .WireBeginLoose => { - var begin = wires.slice()[id].begin(); - begin.* = pos; - begin.pinned = false; - wires.slice()[id].straighten(); - }, - .WireEndPinned => { - var end = wires.slice()[id].end(); - end.* = pos; - end.pinned = true; - wires.slice()[id].straighten(); - }, - .WireEndLoose => { - var end = wires.slice()[id].end(); - end.* = pos; - end.pinned = false; - wires.slice()[id].straighten(); - }, - } - } - - // Load map - var buf: [256]u8 = undefined; - // const len = reader.readByte() catch return; - // const bytes_map = reader.read(buf[0 .. map_len * 3]) catch return false; - // w4.tracef("loading %d map diffs... %d bytes", map_len, bytes_map); - // load_diff(&solids_mutable, assets.solid_size[0], buf[0..bytes_map]); - - // Load conduit - // const conduit_len = reader.readByte() catch return; - const bytes_conduit = reader.read(buf[0 .. conduit_len * 3]) catch return false; - w4.tracef("loading %d conduit diffs... %d bytes", conduit_len, bytes_conduit); - for (buf[0..bytes_conduit]) |byte| w4.tracef("%d", byte); - load_diff(&conduit_mutable, assets.conduit_size[0], buf[0..bytes_conduit]); - - return true; -} - -const SaveObj = enum(u4) { - Player, - Coin, - WireBeginPinned, - WireBeginLoose, - WireEndPinned, - WireEndLoose, -}; - -fn cell2u8(cell: util.Cell) [2]u8 { - return [_]u8{ @intCast(u8, cell[0]), @intCast(u8, cell[1]) }; -} - -fn vec2u16(vec2: util.Vec2) [2]u16 { - return [_]u16{ @intCast(u16, vec2[0]), @intCast(u16, vec2[1]) }; -} - -fn save() void { - var save_buf: [1024]u8 = undefined; - var save_stream = std.io.fixedBufferStream(&save_buf); - var save_writer = save_stream.writer(); - save_writer.writeAll("wired") catch return w4.tracef("Couldn't write header"); - save_writer.writeByte(score) catch return w4.tracef("Couldn't save score"); - w4.tracef("score %d written", score); - - // Write temporary length values - const lengths_start = save_stream.getPos() catch return w4.tracef("Couldn't get pos"); - save_writer.writeByte(0) catch return w4.tracef("Couldn't write obj length"); - // save_writer.writeByte(0) catch return w4.tracef("Couldn't write map length"); - save_writer.writeByte(0) catch return w4.tracef("Couldn't write conduit length"); - - // Write player - const playerPos = vec2u16(util.vec2fToVec2(player.pos.pos)); - save_writer.writeByte(@enumToInt(SaveObj.Player)) catch return w4.tracef("Player"); - save_writer.writeIntBig(u16, playerPos[0]) catch return; - save_writer.writeIntBig(u16, playerPos[1]) catch return; - // save_writer.writeAll(&[_]u8{ @enumToInt(SaveObj.Player), @intCast(u8, player - var obj_len: u8 = 1; - - for (coins.slice()) |coin, i| { - obj_len += 1; - const id = @intCast(u8, @truncate(u4, i)) << 4; - // const cell = util.world2cell(coin.pos.pos); - save_writer.writeByte(@enumToInt(SaveObj.Coin) | id) catch return w4.tracef("Couldn't save coin"); - const pos = vec2u16(util.vec2fToVec2(coin.pos.pos)); - save_writer.writeIntBig(u16, pos[0]) catch return; - save_writer.writeIntBig(u16, pos[1]) catch return; - // save_writer.writeInt(&) catch return; - } - - // Write wires - for (wires.slice()) |*wire, i| { - const id = @intCast(u8, @truncate(u4, i)) << 4; - const begin = wire.begin(); - const end = wire.end(); - obj_len += 1; - if (begin.pinned) { - // const cell = util.world2cell(begin.pos); - save_writer.writeByte(@enumToInt(SaveObj.WireBeginPinned) | id) catch return w4.tracef("Couldn't save wire"); - // const pos = cell2u16(cell); - const pos = vec2u16(util.vec2fToVec2(begin.pos)); - save_writer.writeIntBig(u16, pos[0]) catch return; - save_writer.writeIntBig(u16, pos[1]) catch return; - // save_writer.writeAll(&cell2u8(cell)) catch return; - } else { - // const cell = util.world2cell(begin.pos); - save_writer.writeByte(@enumToInt(SaveObj.WireBeginLoose) | id) catch return w4.tracef("Couldn't save wire"); - // const pos = cell2u16(cell); - const pos = vec2u16(util.vec2fToVec2(begin.pos)); - save_writer.writeIntBig(u16, pos[0]) catch return; - save_writer.writeIntBig(u16, pos[1]) catch return; - // save_writer.writeAll(&cell2u8(cell)) catch return; - } - obj_len += 1; - if (end.pinned) { - // const cell = util.world2cell(end.pos); - save_writer.writeByte(@enumToInt(SaveObj.WireEndPinned) | id) catch return w4.tracef("Couldn't save wire"); - // const pos = cell2u16(cell); - const pos = vec2u16(util.vec2fToVec2(end.pos)); - save_writer.writeIntBig(u16, pos[0]) catch return; - save_writer.writeIntBig(u16, pos[1]) catch return; - // save_writer.writeAll(&cell2u8(cell)) catch return; - } else { - // const cell = util.world2cell(end.pos); - save_writer.writeByte(@enumToInt(SaveObj.WireEndLoose) | id) catch return w4.tracef("Couldn't save wire"); - // const pos = cell2u16(cell); - const pos = vec2u16(util.vec2fToVec2(end.pos)); - save_writer.writeIntBig(u16, pos[0]) catch return; - save_writer.writeIntBig(u16, pos[1]) catch return; - // save_writer.writeAll(&cell2u8(cell)) catch return; - } - } - - // Write map - // const map_len = write_diff(save_writer, assets.solid_size[0], &assets.solid, &solids_mutable) catch return w4.tracef("Couldn't save map diff"); - - // Write conduit - const conduit_len = write_diff(save_writer, assets.conduit_size[0], &assets.conduit, &conduit_mutable) catch return w4.tracef("Couldn't save map diff"); - - const endPos = save_stream.getPos() catch return; - save_stream.seekTo(lengths_start) catch w4.tracef("Couldn't seek"); - save_writer.writeByte(obj_len) catch return w4.tracef("Couldn't write obj length"); - // save_writer.writeByte(map_len) catch return w4.tracef("Couldn't write map length"); - save_writer.writeByte(conduit_len) catch return w4.tracef("Couldn't write conduit length"); - - save_stream.seekTo(endPos) catch return; - const save_slice = save_stream.getWritten(); - const written = w4.diskw(save_slice.ptr, save_slice.len); - w4.tracef("%d bytes written", written); - for (save_buf[0..written]) |byte| w4.tracef("%d", byte); -} - const Interaction = struct { pos: Vec2, details: union(enum) { diff --git a/src/menu.zig b/src/menu.zig index 3f2faa2..70316c8 100644 --- a/src/menu.zig +++ b/src/menu.zig @@ -15,7 +15,9 @@ pub fn start() void { } pub fn update() State { - w4.DRAW_COLORS.* = 0x0002; + w4.DRAW_COLORS.* = 0x0004; + w4.rect(Vec2{ 0, 0 }, Vec2{ 160, 160 }); + w4.DRAW_COLORS.* = 0x0001; var i: i32 = 1; w4.text("WIRED", Vec2{ 16, i * 16 }); i += 1;