Write world data on build
parent
2aa246f1bd
commit
f944f754b1
|
@ -1,5 +1,7 @@
|
||||||
//! Data types used for storing world info
|
//! Data types used for storing world info
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
// Tile Storage Types
|
// Tile Storage Types
|
||||||
pub const CircuitType = enum(u4) {
|
pub const CircuitType = enum(u4) {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -14,24 +16,77 @@ pub const CircuitType = enum(u4) {
|
||||||
Source = 9,
|
Source = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const TileData = packed union {
|
pub const TileData = union {
|
||||||
tile: u7,
|
tile: u7,
|
||||||
flags: packed struct {
|
flags: struct {
|
||||||
solid: bool,
|
solid: bool,
|
||||||
circuit: u4,
|
circuit: u4,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const TileStore = packed struct {
|
pub const TileStore = struct {
|
||||||
is_tile: bool,
|
is_tile: bool,
|
||||||
data: TileData,
|
data: TileData,
|
||||||
|
|
||||||
|
pub fn toByte(store: TileStore) u8 {
|
||||||
|
if (store.is_tile) {
|
||||||
|
return 1 | (store.data.tile << 1);
|
||||||
|
} else {
|
||||||
|
return 0 | (@intCast(u2, @boolToInt(store.data.flags.solid)) << 1) | (store.data.flags.circuit << 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fromByte(byte: u8) TileStore {
|
||||||
|
const is_tile = (1 & byte) > 0;
|
||||||
|
if (is_tile) {
|
||||||
|
const tile = @intCast(u7, (~1 & byte) >> 1);
|
||||||
|
return TileStore{
|
||||||
|
.is_tile = is_tile,
|
||||||
|
.data = .{ .tile = tile },
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const is_solid = (0b0000_0010 & byte) > 0;
|
||||||
|
const circuit = @intCast(u4, (0b0011_1100 & byte) >> 2);
|
||||||
|
return TileStore{
|
||||||
|
.is_tile = is_tile,
|
||||||
|
.data = .{ .flags = .{
|
||||||
|
.solid = is_solid,
|
||||||
|
.circuit = circuit,
|
||||||
|
} },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const LevelHeader = struct {
|
pub const LevelHeader = struct {
|
||||||
world_x: u8,
|
world_x: u8,
|
||||||
world_y: u8,
|
world_y: u8,
|
||||||
width: u16,
|
width: u16,
|
||||||
size: 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(reader.readByte());
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Level = struct {
|
pub const Level = struct {
|
||||||
|
|
|
@ -47,7 +47,6 @@ fn make(step: *std.build.Step) !void {
|
||||||
var data = std.ArrayList(u8).init(allocator);
|
var data = std.ArrayList(u8).init(allocator);
|
||||||
defer data.deinit();
|
defer data.deinit();
|
||||||
const writer = data.writer();
|
const writer = data.writer();
|
||||||
_ = writer;
|
|
||||||
|
|
||||||
// TODO: Convert LDtk data into wired format
|
// TODO: Convert LDtk data into wired format
|
||||||
const ldtk = try LDtk.parse(allocator, source);
|
const ldtk = try LDtk.parse(allocator, source);
|
||||||
|
@ -56,58 +55,78 @@ fn make(step: *std.build.Step) !void {
|
||||||
if (ldtk.levels.len > 0) {
|
if (ldtk.levels.len > 0) {
|
||||||
const level0 = ldtk.levels[0];
|
const level0 = ldtk.levels[0];
|
||||||
if (level0.layerInstances) |layers| {
|
if (level0.layerInstances) |layers| {
|
||||||
var circuit: []const u8 = "null";
|
const world_x: u8 = @intCast(u8, @divExact(level0.worldX, (ldtk.worldGridWidth orelse 160)));
|
||||||
var collision: []const u8 = "null";
|
const world_y: u8 = @intCast(u8, @divExact(level0.worldY, (ldtk.worldGridHeight orelse 160)));
|
||||||
|
|
||||||
|
var circuit_layer: ?LDtk.LayerInstance = null;
|
||||||
|
var collision_layer: ?LDtk.LayerInstance = null;
|
||||||
for (layers) |layer| {
|
for (layers) |layer| {
|
||||||
if (std.mem.eql(u8, layer.__identifier, "Entities")) {
|
if (std.mem.eql(u8, layer.__identifier, "Entities")) {
|
||||||
std.debug.assert(layer.__type == .Entities);
|
std.debug.assert(layer.__type == .Entities);
|
||||||
for (layer.entityInstances) |entity| {
|
for (layer.entityInstances) |entity| {
|
||||||
std.log.warn("{s}", .{entity.__identifier});
|
std.log.warn("{s}", .{entity.__identifier});
|
||||||
}
|
}
|
||||||
}
|
} else if (std.mem.eql(u8, layer.__identifier, "Circuit")) {
|
||||||
else if (std.mem.eql(u8, layer.__identifier, "Circuit")) {
|
|
||||||
std.debug.assert(layer.__type == .IntGrid);
|
std.debug.assert(layer.__type == .IntGrid);
|
||||||
|
|
||||||
var grid_str = try allocator.alloc(u8, @intCast(usize, layer.__cWid * layer.__cHei + layer.__cHei));
|
circuit_layer = layer;
|
||||||
defer allocator.free(grid_str);
|
} else if (std.mem.eql(u8, layer.__identifier, "Collision")) {
|
||||||
var i: usize = 0;
|
|
||||||
var o: usize = 0;
|
|
||||||
for (layer.intGridCsv) |int| {
|
|
||||||
grid_str[i + o] = std.fmt.digitToChar(@intCast(u8, int), .lower);
|
|
||||||
if (grid_str[i] == '0') grid_str[i] = ' ';
|
|
||||||
i += 1;
|
|
||||||
if (@mod(i, @intCast(usize, layer.__cWid)) == 0) {
|
|
||||||
grid_str[i + o] = '\n';
|
|
||||||
o += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
circuit = grid_str;
|
|
||||||
}
|
|
||||||
else if (std.mem.eql(u8, layer.__identifier, "Collision")) {
|
|
||||||
std.debug.assert(layer.__type == .IntGrid);
|
std.debug.assert(layer.__type == .IntGrid);
|
||||||
|
|
||||||
var grid_str = try allocator.alloc(u8, @intCast(usize, layer.__cWid * layer.__cHei + layer.__cHei));
|
collision_layer = layer;
|
||||||
var i: usize = 0;
|
|
||||||
var o: usize = 0;
|
|
||||||
for (layer.intGridCsv) |int| {
|
|
||||||
grid_str[i + o] = std.fmt.digitToChar(@intCast(u8, int), .lower);
|
|
||||||
if (grid_str[i] == '0') grid_str[i] = ' ';
|
|
||||||
i += 1;
|
|
||||||
if (@mod(i, @intCast(usize, layer.__cWid)) == 0) {
|
|
||||||
grid_str[i + o] = '\n';
|
|
||||||
o += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
collision = grid_str;
|
|
||||||
} else {
|
} else {
|
||||||
std.log.warn("{s}: {}", .{ layer.__identifier, layer.__type });
|
std.log.warn("{s}: {}", .{ layer.__identifier, layer.__type });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.log.warn("Circuit IntGrid:\n{s}\nCollision IntGrid:\n{s}", .{ circuit, collision});
|
|
||||||
allocator.free(circuit);
|
if (circuit_layer == null) return error.MissingCircuitLayer;
|
||||||
allocator.free(collision);
|
if (collision_layer == null) return error.MissingCollisionLayer;
|
||||||
|
|
||||||
|
std.log.warn("Layers found", .{});
|
||||||
|
|
||||||
|
const circuit = circuit_layer.?;
|
||||||
|
const collision = collision_layer.?;
|
||||||
|
|
||||||
|
std.debug.assert(circuit.__cWid == collision.__cWid);
|
||||||
|
std.debug.assert(circuit.__cHei == collision.__cHei);
|
||||||
|
|
||||||
|
const width = @intCast(u16, circuit.__cWid);
|
||||||
|
const size = @intCast(u16, width * circuit.__cHei);
|
||||||
|
|
||||||
|
try (world.LevelHeader{
|
||||||
|
.world_x = world_x,
|
||||||
|
.world_y = world_y,
|
||||||
|
.width = @intCast(u16, width),
|
||||||
|
.size = @intCast(u16, size),
|
||||||
|
}).write(writer);
|
||||||
|
|
||||||
|
var tiles = try allocator.alloc(world.TileStore, size);
|
||||||
|
defer allocator.free(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) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (circuit.intGridCsv) |cir64, i| {
|
||||||
|
const cir = @intCast(u4, cir64);
|
||||||
|
const col = collision.intGridCsv[i];
|
||||||
|
tiles[i] = world.TileStore{
|
||||||
|
.is_tile = false,
|
||||||
|
.data = .{
|
||||||
|
.flags = .{
|
||||||
|
.solid = col == 1,
|
||||||
|
.circuit = cir,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
try writer.writeByte(tiles[i].toByte());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue