Begin splitting game.zig

master
Louis Pearson 2022-02-01 01:08:31 -07:00
parent d0d47d850d
commit ae34313849
4 changed files with 326 additions and 287 deletions

59
src/component.zig Normal file
View File

@ -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 };

243
src/disk.zig Normal file
View File

@ -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);
}

View File

@ -7,59 +7,24 @@ const Circuit = @import("circuit.zig");
const Map = @import("map.zig"); const Map = @import("map.zig");
const Music = @import("music.zig"); const Music = @import("music.zig");
const State = @import("main.zig").State; const State = @import("main.zig").State;
const Disk = @import("disk.zig");
const Vec2 = util.Vec2; const Vec2 = util.Vec2;
const Vec2f = util.Vec2f; const Vec2f = util.Vec2f;
const AABB = util.AABB; const AABB = util.AABB;
const Anim = @import("anim.zig"); const Anim = @import("anim.zig");
// Components const comp = @import("component.zig");
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 },
pub fn inAir(this: @This()) bool { const Pos = comp.Pos;
return approxEqAbs(f32, this.lastCol[1], 0, 0.01); 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 { const Wire = struct {
nodes: std.BoundedArray(Pos, 32) = std.BoundedArray(Pos, 32).init(0), nodes: std.BoundedArray(Pos, 32) = std.BoundedArray(Pos, 32).init(0),
enabled: bool = false, enabled: bool = false,
@ -82,7 +47,7 @@ const Wire = struct {
} }
} }
}; };
const Physics = struct { gravity: Vec2f, friction: Vec2f };
const Player = struct { const Player = struct {
pos: Pos, pos: Pos,
control: Control, control: Control,
@ -91,7 +56,6 @@ const Player = struct {
kinematic: Kinematic, kinematic: Kinematic,
physics: Physics, physics: Physics,
}; };
// const World = ecs.World(Component);
const Particle = struct { const Particle = struct {
pos: Pos, pos: Pos,
@ -176,14 +140,14 @@ var circuit: Circuit = undefined;
var particles: ParticleSystem = undefined; 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: Player = undefined; pub var player: Player = undefined;
var music = Music.Procedural.init(.C3, &Music.Minor, 83); 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 }; var camera = Vec2{ 0, 0 };
const Coin = struct { pos: Pos, sprite: Sprite, anim: Anim, area: AABB }; const Coin = struct { pos: Pos, sprite: Sprite, anim: Anim, area: AABB };
var coins = std.BoundedArray(Coin, 20).init(0) catch unreachable; pub var coins = std.BoundedArray(Coin, 20).init(0) catch unreachable;
var score: u8 = 0; pub var score: u8 = 0;
var ScoreCoin = Sprite{ var ScoreCoin = Sprite{
.size = Map.tile_size, .size = Map.tile_size,
.index = 4, .index = 4,
@ -191,20 +155,18 @@ var ScoreCoin = Sprite{
}; };
var solids_mutable = assets.solid; var solids_mutable = assets.solid;
var conduit_mutable = assets.conduit; pub var conduit_mutable = assets.conduit;
var conduitLevels_mutable: [conduit_mutable.len]u8 = undefined; var conduitLevels_mutable: [conduit_mutable.len]u8 = undefined;
const anim_store = struct { pub const anim_store = struct {
const stand = Anim.frame(8); const stand = Anim.frame(8);
const walk = Anim.simple(4, &[_]usize{ 9, 10, 11, 12 }); const walk = Anim.simple(4, &[_]usize{ 9, 10, 11, 12 });
const jump = Anim.frame(13); const jump = Anim.frame(13);
const fall = Anim.frame(14); const fall = Anim.frame(14);
const wallSlide = Anim.frame(15); 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: { const playerAnim = pac: {
var animArr = std.BoundedArray(AnimData, 100).init(0) catch unreachable; var animArr = std.BoundedArray(AnimData, 100).init(0) catch unreachable;
animArr.append(&anim_store.stand) catch unreachable; animArr.append(&anim_store.stand) catch unreachable;
@ -269,7 +231,7 @@ pub fn start() void {
} }
// _ = w4.diskw("", 0); // _ = w4.diskw("", 0);
if (!load()) { if (!Disk.load()) {
for (assets.coins) |coin| { for (assets.coins) |coin| {
coins.append(.{ coins.append(.{
.pos = Pos.init(util.vec2ToVec2f(coin * tile_size)), .pos = Pos.init(util.vec2ToVec2f(coin * tile_size)),
@ -326,12 +288,12 @@ pub fn update(time: usize) State {
_ = coins.swapRemove(i); _ = coins.swapRemove(i);
} }
// We save here to prevent duplicate coins // 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)); const newCamera = @divTrunc(util.world2cell(player.pos.pos), @splat(2, @as(i32, 20))) * @splat(2, @as(i32, 20));
if (!@reduce(.And, newCamera == camera)) { if (!@reduce(.And, newCamera == camera)) {
save(); Disk.save();
} }
camera = newCamera; camera = newCamera;
@ -417,233 +379,6 @@ pub fn update(time: usize) State {
return .Game; 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 { const Interaction = struct {
pos: Vec2, pos: Vec2,
details: union(enum) { details: union(enum) {

View File

@ -15,7 +15,9 @@ pub fn start() void {
} }
pub fn update() State { 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; var i: i32 = 1;
w4.text("WIRED", Vec2{ 16, i * 16 }); w4.text("WIRED", Vec2{ 16, i * 16 });
i += 1; i += 1;