From 0c79bfe575a0e28dcadbc7e72a0c7aa8c17f5c8d Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Thu, 4 Aug 2022 13:11:20 -0600 Subject: [PATCH] Simplify world types --- src/extract.zig | 25 ++++++---- src/main.zig | 1 + src/rewrite.zig | 10 ++-- src/world.zig | 109 +++++++++++++++++++------------------------ tools/LDtkImport.zig | 36 +++++++------- 5 files changed, 85 insertions(+), 96 deletions(-) diff --git a/src/extract.zig b/src/extract.zig index 1533d62..7fc120e 100644 --- a/src/extract.zig +++ b/src/extract.zig @@ -32,9 +32,11 @@ pub fn extractLevel(opt: Options) !void { const level = opt.level; const tileset = opt.tileset; + const tiles = level.tiles orelse return error.NullTiles; + const width = level.width; - const height = @divExact(@intCast(u16, level.tiles.len), level.width); - const size = level.tiles.len; + const height = @divExact(@intCast(u16, tiles.len), level.width); + const size = tiles.len; map.map_size = .{ level.width, height }; circuit.map_size = .{ level.width, height }; @@ -45,14 +47,17 @@ pub fn extractLevel(opt: Options) !void { var circuit_map = try alloc.alloc(CircuitType, size); defer alloc.free(circuit_map); - for (level.tiles) |tile, i| { - if (tile.is_tile) { - auto_map[i] = false; - map.tiles[i] = tile.data.tile; - circuit_map[i] = .None; - } else { - auto_map[i] = tile.data.flags.solid; - circuit_map[i] = @intToEnum(CircuitType, tile.data.flags.circuit); + for (tiles) |data, i| { + switch (data) { + .tile => |tile| { + auto_map[i] = false; + map.tiles[i] = tile; + circuit_map[i] = .None; + }, + .flags => |flags| { + auto_map[i] = flags.solid; + circuit_map[i] = @intToEnum(CircuitType, flags.circuit); + }, } } diff --git a/src/main.zig b/src/main.zig index a5ef268..4945b5c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -42,6 +42,7 @@ export fn update() void { // error.OutOfBounds => showErr(@errorName(e)), error.EndOfStream => showErr(@errorName(e)), error.OutOfMemory => showErr(@errorName(e)), + error.NullTiles => showErr(@errorName(e)), }, } } diff --git a/src/rewrite.zig b/src/rewrite.zig index c177540..4343136 100644 --- a/src/rewrite.zig +++ b/src/rewrite.zig @@ -11,7 +11,7 @@ const util = @import("util.zig"); const Vec2 = w4.Vec2; -var fba_buf: [1024]u8 = undefined; +var fba_buf: [4096]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&fba_buf); var alloc = fba.allocator(); @@ -49,11 +49,9 @@ pub fn start() !void { }; const world_reader = stream.reader(); - const header = try world.LevelHeader.read(world_reader); - var tile_buf: [4096]world.TileStore = undefined; - try header.readTiles(world_reader, &tile_buf); - - const level = world.Level.init(header, &tile_buf); + 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, diff --git a/src/world.zig b/src/world.zig index c8d98bd..e41a284 100644 --- a/src/world.zig +++ b/src/world.zig @@ -16,75 +16,32 @@ pub const CircuitType = enum(u4) { Source = 9, }; -pub const TileData = union { +pub const TileData = union(enum) { tile: u7, flags: struct { solid: bool, circuit: u4, }, -}; -pub const TileStore = struct { - is_tile: bool, - data: TileData, - - pub fn toByte(store: TileStore) u8 { - if (store.is_tile) { - return 1 | (store.data.tile << 1); - } else { - return (@intCast(u7, @boolToInt(store.data.flags.solid)) << 1) | (@intCast(u7, store.data.flags.circuit) << 2); + pub fn toByte(data: TileData) u8 { + switch (data) { + .tile => |int| return 1 | (int << 1), + .flags => |flags| return (@intCast(u7, @boolToInt(flags.solid)) << 1) | (@intCast(u7, flags.circuit) << 2), } } - pub fn fromByte(byte: u8) TileStore { + pub fn fromByte(byte: u8) TileData { const is_tile = (1 & byte) > 0; if (is_tile) { const tile = @intCast(u7, (~@as(u7, 1) & byte) >> 1); - return TileStore{ - .is_tile = true, - .data = .{ .tile = tile }, - }; + return TileData{ .tile = tile }; } else { const is_solid = (0b0000_0010 & byte) > 0; const circuit = @intCast(u4, (0b0011_1100 & byte) >> 2); - return TileStore{ - .is_tile = false, - .data = .{ .flags = .{ - .solid = is_solid, - .circuit = circuit, - } }, - }; - } - } -}; - -pub const LevelHeader = struct { - world_x: u8, - world_y: u8, - width: u16, - size: u16, - - pub fn write(header: LevelHeader, writer: anytype) !void { - try writer.writeInt(u8, header.world_x, .Big); - try writer.writeInt(u8, header.world_y, .Big); - try writer.writeInt(u16, header.width, .Big); - try writer.writeInt(u16, header.size, .Big); - } - - pub fn read(reader: anytype) !LevelHeader { - return LevelHeader{ - .world_x = try reader.readInt(u8, .Big), - .world_y = try reader.readInt(u8, .Big), - .width = try reader.readInt(u16, .Big), - .size = try reader.readInt(u16, .Big), - }; - } - - pub fn readTiles(header: LevelHeader, reader: anytype, buf: []TileStore) !void { - std.debug.assert(buf.len > header.size); - var i: usize = 0; - while (i < header.size) : (i += 1) { - buf[i] = TileStore.fromByte(try reader.readByte()); + return TileData{ .flags = .{ + .solid = is_solid, + .circuit = circuit, + } }; } } }; @@ -93,16 +50,48 @@ pub const Level = struct { world_x: u8, world_y: u8, width: u16, - tiles: []TileStore, + size: u16, + tiles: ?[]TileData, - pub fn init(header: LevelHeader, buf: []TileStore) Level { + pub fn init(x: u8, y: u8, width: u16, buf: []TileData) Level { return Level{ - .world_x = header.world_x, - .world_y = header.world_y, - .width = header.width, - .tiles = buf[0..header.size], + .world_x = x, + .world_y = y, + .width = width, + .size = buf.len, + .tiles = buf, }; } + + pub fn write(level: Level, writer: anytype) !void { + var tiles = level.tiles orelse return error.NullTiles; + try writer.writeInt(u8, level.world_x, .Big); + try writer.writeInt(u8, level.world_y, .Big); + try writer.writeInt(u16, level.width, .Big); + try writer.writeInt(u16, level.size, .Big); + for (tiles) |tile| { + try writer.writeByte(tile.toByte()); + } + } + + pub fn read(reader: anytype) !Level { + return Level{ + .world_x = try reader.readInt(u8, .Big), + .world_y = try reader.readInt(u8, .Big), + .width = try reader.readInt(u16, .Big), + .size = try reader.readInt(u16, .Big), + .tiles = null, + }; + } + + pub fn readTiles(level: *Level, reader: anytype, buf: []TileData) !void { + std.debug.assert(buf.len >= level.size); + level.tiles = buf; + var i: usize = 0; + while (i < level.size) : (i += 1) { + buf[i] = TileData.fromByte(try reader.readByte()); + } + } }; // AutoTile algorithm datatypes diff --git a/tools/LDtkImport.zig b/tools/LDtkImport.zig index 1736fd6..f8365a3 100644 --- a/tools/LDtkImport.zig +++ b/tools/LDtkImport.zig @@ -51,7 +51,6 @@ fn make(step: *std.build.Step) !void { defer data.deinit(); const writer = data.writer(); - // TODO: Convert LDtk data into wired format const ldtk = try LDtk.parse(allocator, source); defer ldtk.deinit(allocator); @@ -96,43 +95,40 @@ fn make(step: *std.build.Step) !void { const width = @intCast(u16, circuit.__cWid); const size = @intCast(u16, width * circuit.__cHei); - try (world.LevelHeader{ + var level = world.Level{ .world_x = world_x, .world_y = world_y, .width = @intCast(u16, width), .size = @intCast(u16, size), - }).write(writer); + .tiles = null, + }; + level.tiles = try allocator.alloc(world.TileData, size); + defer allocator.free(level.tiles.?); - var tiles = try allocator.alloc(world.TileStore, size); - defer allocator.free(tiles); + const tiles = level.tiles.?; for (collision.autoLayerTiles) |autotile| { const x = @divExact(autotile.px[0], collision.__gridSize); const y = @divExact(autotile.px[1], collision.__gridSize); const i = @intCast(usize, x + y * width); - tiles[i] = world.TileStore{ - .is_tile = true, - .data = .{ .tile = @intCast(u7, autotile.t + 1) }, - }; + tiles[i] = world.TileData{ .tile = @intCast(u7, autotile.t + 1) }; } for (circuit.intGridCsv) |cir64, i| { const cir = @intCast(u4, cir64); const col = collision.intGridCsv[i]; if (col != 2) { - tiles[i] = world.TileStore{ - .is_tile = false, - .data = .{ .flags = .{ - .solid = col == 1, - .circuit = cir, - } }, - }; + tiles[i] = world.TileData{ .flags = .{ + .solid = col == 1, + .circuit = cir, + } }; } - if (col == 2) { - tiles[i].is_tile = true; - } - try writer.writeByte(tiles[i].toByte()); + // if (col == 2) { + // tiles[i].is_tile = true; + // } } + + try level.write(writer); } }