diff --git a/src/circuit.zig b/src/circuit.zig index 1c32225..88a2c18 100644 --- a/src/circuit.zig +++ b/src/circuit.zig @@ -240,6 +240,15 @@ pub fn toggle(this: *@This(), c: Cell) void { } } +pub fn clearMap(this: *@This()) void { + this.clear(); + std.mem.set(u8, this.map, 0); + for (this.doors.items) |*door| { + door.enabled = false; + } + this.bridges.reset(); +} + pub fn clear(this: *@This()) void { std.mem.set(u8, this.levels, 0); for (this.doors.items) |*door| { diff --git a/src/game.zig b/src/game.zig index 0a93ca6..d174255 100644 --- a/src/game.zig +++ b/src/game.zig @@ -148,6 +148,10 @@ var frame_fba_buf: [8192]u8 = undefined; var frame_fba = std.heap.FixedBufferAllocator.init(&frame_fba_buf); var frame_alloc = frame_fba.allocator(); +var db_fba_buf: [1024]u8 = undefined; +var db_fba = std.heap.FixedBufferAllocator.init(&db_fba_buf); +var db_alloc = db_fba.allocator(); + // Global vars var map: Map = undefined; var circuit: Circuit = undefined; @@ -158,8 +162,9 @@ pub var player: Player = undefined; var music = Music.Procedural.init(.C3, &Music.Minor, 83); pub var wires = std.BoundedArray(Wire, 10).init(0) catch unreachable; var camera = Vec2{ 0, 0 }; + +var db: world.Database = undefined; var level: world.Level = undefined; -var level_buf: []world.TileData = undefined; const Coin = struct { pos: Pos, sprite: Sprite, anim: Anim, area: AABB }; pub var coins = std.BoundedArray(Coin, 20).init(0) catch unreachable; @@ -196,6 +201,37 @@ const playerAnim = pac: { break :pac animArr.slice(); }; +fn loadLevel(lvl: usize) !void { + fba.reset(); + map.clear(); + circuit.clearMap(); + level = try db.levelLoad(alloc, lvl); + + try extract.extractLevel(.{ + .alloc = frame_alloc, + .level = level, + .map = &map, + .circuit = &circuit, + .tileset = world.Tiles.Walls, + .conduit = world.Tiles.Conduit, + .plug = world.Tiles.Plugs, + .switch_off = world.Tiles.SwitchesOff, + .switch_on = world.Tiles.SwitchesOn, + }); +} + +fn moveLevel(direction: enum { L, R, U, D }, lvl: usize) !void { + try loadLevel(lvl); + // var momentum = player.pos.pos - player.pos.last; + switch (direction) { + .L => player.pos.pos[0] = 156, + .R => player.pos.pos[0] = 4, + .U => player.pos.pos[1] = 156, + .D => player.pos.pos[1] = 4, + } + player.pos.last = player.pos.pos; +} + pub fn start() !void { particles = try ParticleSystem.init(); @@ -213,21 +249,9 @@ pub fn start() !void { map = Map.init(&map_buf, level_size); - var db = try world.Database.init(alloc); + db = try world.Database.init(db_alloc); - level = try db.levelLoad(alloc, 0); - - try extract.extractLevel(.{ - .alloc = frame_alloc, - .level = level, - .map = &map, - .circuit = &circuit, - .tileset = world.Tiles.Walls, - .conduit = world.Tiles.Conduit, - .plug = world.Tiles.Plugs, - .switch_off = world.Tiles.SwitchesOff, - .switch_on = world.Tiles.SwitchesOn, - }); + try loadLevel(0); const spawnArr = level.getSpawn() orelse return error.NoPlayerSpawn; const spawn = Vec2{ spawnArr[0], spawnArr[1] }; @@ -317,6 +341,7 @@ pub fn update(time: usize) !State { physicsProcess(1, &player.pos, &player.physics); try manipulationProcess(&player.pos, &player.control); controlProcess(time, &player.pos, &player.control, &player.physics, &player.kinematic); + if (player.pos.pos[0] > 160 - 4) try moveLevel(.R, 1); try kinematicProcess(1, &player.pos, &player.kinematic); controlAnimProcess(1, &player.sprite, &player.controlAnim, &player.control); try particles.update(); diff --git a/src/main.zig b/src/main.zig index ed183de..3e1b650 100644 --- a/src/main.zig +++ b/src/main.zig @@ -30,8 +30,10 @@ export fn update() void { .Game => game.update(time) catch |e| switch (e) { error.Overflow => showErr(@errorName(e)), error.OutOfBounds => showErr(@errorName(e)), - // error.EndOfStream => showErr(@errorName(e)), + error.EndOfStream => showErr(@errorName(e)), error.OutOfMemory => showErr(@errorName(e)), + error.InvalidLevel => showErr(@errorName(e)), + error.NullTiles => showErr(@errorName(e)), }, }; if (state != newState) { @@ -45,6 +47,7 @@ export fn update() void { error.OutOfMemory => showErr(@errorName(e)), error.NullTiles => showErr(@errorName(e)), error.NoPlayerSpawn => showErr(@errorName(e)), + error.InvalidLevel => showErr(@errorName(e)), }, } } diff --git a/src/map.zig b/src/map.zig index b7cc772..6ec7391 100644 --- a/src/map.zig +++ b/src/map.zig @@ -29,6 +29,10 @@ pub fn init(map: []u8, map_size: Vec2) @This() { return this; } +pub fn clear(this: *@This()) void { + std.mem.set(u8, this.tiles, 0); +} + pub fn reset(this: *@This(), initialState: []const u8) void { std.debug.assert(initialState.len == this.tiles.len); std.mem.copy(u8, this.tiles, initialState); diff --git a/src/rewrite.zig b/src/rewrite.zig deleted file mode 100644 index d0d82b7..0000000 --- a/src/rewrite.zig +++ /dev/null @@ -1,92 +0,0 @@ -const extract = @import("extract.zig"); -const world_data = @embedFile(@import("world_data").path); -const Circuit = @import("circuit.zig"); -const input = @import("input.zig"); -const Map = @import("map.zig"); -const State = @import("main.zig").State; -const std = @import("std"); -const w4 = @import("wasm4.zig"); -const world = @import("world.zig"); -const util = @import("util.zig"); - -const Vec2 = w4.Vec2; - -var fba_buf: [4096]u8 = undefined; -var fba = std.heap.FixedBufferAllocator.init(&fba_buf); -var alloc = fba.allocator(); - -var frame_fba_buf: [4096]u8 = undefined; -var frame_fba = std.heap.FixedBufferAllocator.init(&frame_fba_buf); -var frame_alloc = frame_fba.allocator(); - -var map_buf: [400]u8 = undefined; -var map: Map = undefined; - -var circuit_lvl_buf: [400]u8 = undefined; -var circuit_buf: [400]u8 = undefined; -var circuit: Circuit = undefined; - -var circuit_options: Circuit.Options = undefined; - -var level_size = Vec2{ 20, 20 }; - -pub fn start() !void { - circuit_options = .{ - .map = &circuit_buf, - .levels = &circuit_lvl_buf, - .map_size = level_size, - .bridges = try alloc.alloc(Circuit.BridgeState, 5), - .sources = try alloc.alloc(util.Cell, 5), - .doors = try alloc.alloc(Circuit.DoorState, 5), - }; - circuit = Circuit.init(circuit_options); - - map = Map.init(&map_buf, level_size); - - var stream = std.io.FixedBufferStream([]const u8){ - .pos = 0, - .buffer = world_data, - }; - const world_reader = stream.reader(); - - var level = try world.Level.read(world_reader); - var level_buf = try alloc.alloc(world.TileData, level.size); - try level.readTiles(world_reader, level_buf); - - try extract.extractLevel(.{ - .alloc = frame_alloc, - .level = level, - .map = &map, - .circuit = &circuit, - .tileset = world.AutoTileset.initOffsetFull(113), - .conduit = world.AutoTileset.initOffsetFull(97), - .plug = world.AutoTileset.initOffsetCardinal(17), - .switch_off = world.AutoTileset.initSwitches(&.{ - 29, // South-North - 25, // South-West-North - 27, // South-East-North - }, 2), - .switch_on = world.AutoTileset.initSwitches(&.{ - 30, // South-North - 26, // South-West-North - 28, // South-East-West - }, 2), - }); -} - -pub fn update(time: usize) !State { - _ = time; - // Reset the frame allocator - frame_fba.reset(); - - w4.DRAW_COLORS.* = 0x0004; - w4.rect(Vec2{ 0, 0 }, Vec2{ 160, 160 }); - w4.DRAW_COLORS.* = 0x0001; - - const camera = Vec2{ 0, 0 }; - - map.draw(camera); - circuit.draw(camera); - - return .Game; -} diff --git a/src/world.zig b/src/world.zig index 9ae6f28..ef272cc 100644 --- a/src/world.zig +++ b/src/world.zig @@ -484,6 +484,7 @@ pub const Database = struct { } pub fn levelInfo(db: *Database, level: usize) !Level { + if (level > db.level_info.len) return error.InvalidLevel; try db.cursor.seekTo(db.level_data_begin + db.level_info[level].offset); const reader = db.cursor.reader();