Import multiple levels
parent
3fcd7e0942
commit
f5691e45f1
|
@ -26,6 +26,7 @@ fn is_solid(tile: u7) bool {
|
||||||
|
|
||||||
/// Extracts a compressed level into the map and circuit buffers
|
/// Extracts a compressed level into the map and circuit buffers
|
||||||
pub fn extractLevel(opt: Options) !void {
|
pub fn extractLevel(opt: Options) !void {
|
||||||
|
w4.tracef("extract begin");
|
||||||
const map = opt.map;
|
const map = opt.map;
|
||||||
const circuit = opt.circuit;
|
const circuit = opt.circuit;
|
||||||
const alloc = opt.alloc;
|
const alloc = opt.alloc;
|
||||||
|
@ -35,18 +36,21 @@ pub fn extractLevel(opt: Options) !void {
|
||||||
const tiles = level.tiles orelse return error.NullTiles;
|
const tiles = level.tiles orelse return error.NullTiles;
|
||||||
|
|
||||||
const width = level.width;
|
const width = level.width;
|
||||||
|
w4.tracef("div exact %d, %d", tiles.len, level.width);
|
||||||
const height = @divExact(@intCast(u16, tiles.len), level.width);
|
const height = @divExact(@intCast(u16, tiles.len), level.width);
|
||||||
const size = tiles.len;
|
const size = tiles.len;
|
||||||
|
|
||||||
map.map_size = .{ level.width, height };
|
map.map_size = .{ level.width, height };
|
||||||
circuit.map_size = .{ level.width, height };
|
circuit.map_size = .{ level.width, height };
|
||||||
|
|
||||||
|
w4.tracef("%d", @src().line);
|
||||||
var auto_map = try alloc.alloc(bool, size);
|
var auto_map = try alloc.alloc(bool, size);
|
||||||
defer alloc.free(auto_map);
|
defer alloc.free(auto_map);
|
||||||
|
|
||||||
var circuit_map = try alloc.alloc(CircuitType, size);
|
var circuit_map = try alloc.alloc(CircuitType, size);
|
||||||
defer alloc.free(circuit_map);
|
defer alloc.free(circuit_map);
|
||||||
|
|
||||||
|
w4.tracef("reading tiles");
|
||||||
for (tiles) |data, i| {
|
for (tiles) |data, i| {
|
||||||
switch (data) {
|
switch (data) {
|
||||||
.tile => |tile| {
|
.tile => |tile| {
|
||||||
|
@ -64,6 +68,7 @@ pub fn extractLevel(opt: Options) !void {
|
||||||
var autotiles = try alloc.alloc(?AutoTile, size);
|
var autotiles = try alloc.alloc(?AutoTile, size);
|
||||||
defer alloc.free(autotiles);
|
defer alloc.free(autotiles);
|
||||||
|
|
||||||
|
w4.tracef("autotile walls");
|
||||||
// Auto generate walls
|
// Auto generate walls
|
||||||
{
|
{
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
|
@ -123,6 +128,7 @@ pub fn extractLevel(opt: Options) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w4.tracef("autotile circuit");
|
||||||
// Auto generate circuit
|
// Auto generate circuit
|
||||||
// Re-use autotiles to save memory
|
// Re-use autotiles to save memory
|
||||||
{
|
{
|
||||||
|
@ -195,4 +201,5 @@ pub fn extractLevel(opt: Options) !void {
|
||||||
circuit.map[i] = tile;
|
circuit.map[i] = tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
w4.tracef("extract end");
|
||||||
}
|
}
|
||||||
|
|
30
src/game.zig
30
src/game.zig
|
@ -140,7 +140,7 @@ fn randRangeF(min: f32, max: f32) f32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocators
|
// Allocators
|
||||||
var fba_buf: [4096]u8 = undefined;
|
var fba_buf: [8192]u8 = undefined;
|
||||||
var fba = std.heap.FixedBufferAllocator.init(&fba_buf);
|
var fba = std.heap.FixedBufferAllocator.init(&fba_buf);
|
||||||
var alloc = fba.allocator();
|
var alloc = fba.allocator();
|
||||||
|
|
||||||
|
@ -217,11 +217,34 @@ pub fn start() !void {
|
||||||
.pos = 0,
|
.pos = 0,
|
||||||
.buffer = world_data,
|
.buffer = world_data,
|
||||||
};
|
};
|
||||||
|
w4.tracef("[world]: size=%d", world_data.len);
|
||||||
const world_reader = stream.reader();
|
const world_reader = stream.reader();
|
||||||
|
|
||||||
|
var levels = try world.read(alloc, world_reader);
|
||||||
|
var level_data_offset = try stream.getPos();
|
||||||
|
w4.tracef("header_size=%d", level_data_offset);
|
||||||
|
|
||||||
|
try stream.seekTo(level_data_offset + levels[1].offset);
|
||||||
|
w4.tracef("seek_to=%d", try stream.getPos());
|
||||||
|
|
||||||
|
for (levels) |lvl, i| {
|
||||||
|
w4.tracef("[%d]: offset=%d, x=%d, y=%d", i, lvl.offset, @intCast(isize, lvl.x), @intCast(isize, lvl.y));
|
||||||
|
}
|
||||||
|
|
||||||
level = try world.Level.read(world_reader);
|
level = try world.Level.read(world_reader);
|
||||||
|
w4.tracef("level_read_end=%d", try stream.getPos());
|
||||||
|
// w4.tracef(
|
||||||
|
// "[level 0]: x=%d, y=%d, width=%d, size=%d, entity_count=%d, seek_head=%d",
|
||||||
|
// level.world_x,
|
||||||
|
// level.world_y,
|
||||||
|
// level.width,
|
||||||
|
// level.size,
|
||||||
|
// level.entity_count,
|
||||||
|
// );
|
||||||
|
|
||||||
level_buf = try alloc.alloc(world.TileData, level.size);
|
level_buf = try alloc.alloc(world.TileData, level.size);
|
||||||
try level.readTiles(world_reader, level_buf);
|
try level.readTiles(world_reader, level_buf);
|
||||||
|
w4.tracef("level_read_end=%d", try stream.getPos());
|
||||||
|
|
||||||
try extract.extractLevel(.{
|
try extract.extractLevel(.{
|
||||||
.alloc = frame_alloc,
|
.alloc = frame_alloc,
|
||||||
|
@ -235,10 +258,13 @@ pub fn start() !void {
|
||||||
.switch_on = world.Tiles.SwitchesOn,
|
.switch_on = world.Tiles.SwitchesOn,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
w4.tracef("entity_count=%d", level.entity_count);
|
||||||
|
w4.tracef("entity_size=%d", level.entity_count * world.Entity.calculateSize());
|
||||||
var entity_buf = try alloc.alloc(world.Entity, level.entity_count);
|
var entity_buf = try alloc.alloc(world.Entity, level.entity_count);
|
||||||
try level.readEntities(world_reader, entity_buf);
|
try level.readEntities(world_reader, entity_buf);
|
||||||
|
w4.tracef("entity_read_end=%d", try stream.getPos());
|
||||||
|
|
||||||
const spawnArr = level.getSpawn().?;
|
const spawnArr = level.getSpawn() orelse return error.NoPlayerSpawn;
|
||||||
const spawn = Vec2{ spawnArr[0], spawnArr[1] };
|
const spawn = Vec2{ spawnArr[0], spawnArr[1] };
|
||||||
|
|
||||||
camera = @divTrunc(spawn, @splat(2, @as(i32, 20))) * @splat(2, @as(i32, 20));
|
camera = @divTrunc(spawn, @splat(2, @as(i32, 20))) * @splat(2, @as(i32, 20));
|
||||||
|
|
110
src/world.zig
110
src/world.zig
|
@ -139,8 +139,8 @@ pub const TileData = union(enum) {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Level = struct {
|
pub const Level = struct {
|
||||||
world_x: u8,
|
world_x: i8,
|
||||||
world_y: u8,
|
world_y: i8,
|
||||||
width: u16,
|
width: u16,
|
||||||
size: u16,
|
size: u16,
|
||||||
entity_count: u16,
|
entity_count: u16,
|
||||||
|
@ -159,11 +159,23 @@ pub const Level = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn calculateSize(level: Level) !usize {
|
||||||
|
const tiles = level.tiles orelse return error.NullTiles;
|
||||||
|
const entities = level.entities orelse return error.NullEntities;
|
||||||
|
return @sizeOf(i8) + // world_x
|
||||||
|
@sizeOf(i8) + // world_y
|
||||||
|
@sizeOf(u16) + // width
|
||||||
|
@sizeOf(u16) + // size
|
||||||
|
@sizeOf(u16) + // entity_count
|
||||||
|
tiles.len + //
|
||||||
|
entities.len * 5;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(level: Level, writer: anytype) !void {
|
pub fn write(level: Level, writer: anytype) !void {
|
||||||
var tiles = level.tiles orelse return error.NullTiles;
|
var tiles = level.tiles orelse return error.NullTiles;
|
||||||
var entities = level.entities orelse return error.NullEntities;
|
var entities = level.entities orelse return error.NullEntities;
|
||||||
try writer.writeInt(u8, level.world_x, .Little);
|
try writer.writeInt(i8, level.world_x, .Little);
|
||||||
try writer.writeInt(u8, level.world_y, .Little);
|
try writer.writeInt(i8, level.world_y, .Little);
|
||||||
try writer.writeInt(u16, level.width, .Little);
|
try writer.writeInt(u16, level.width, .Little);
|
||||||
try writer.writeInt(u16, level.size, .Little);
|
try writer.writeInt(u16, level.size, .Little);
|
||||||
try writer.writeInt(u16, level.entity_count, .Little);
|
try writer.writeInt(u16, level.entity_count, .Little);
|
||||||
|
@ -179,8 +191,8 @@ pub const Level = struct {
|
||||||
|
|
||||||
pub fn read(reader: anytype) !Level {
|
pub fn read(reader: anytype) !Level {
|
||||||
return Level{
|
return Level{
|
||||||
.world_x = try reader.readInt(u8, .Little),
|
.world_x = try reader.readInt(i8, .Little),
|
||||||
.world_y = try reader.readInt(u8, .Little),
|
.world_y = try reader.readInt(i8, .Little),
|
||||||
.width = try reader.readInt(u16, .Little),
|
.width = try reader.readInt(u16, .Little),
|
||||||
.size = try reader.readInt(u16, .Little),
|
.size = try reader.readInt(u16, .Little),
|
||||||
.entity_count = try reader.readInt(u16, .Little),
|
.entity_count = try reader.readInt(u16, .Little),
|
||||||
|
@ -374,6 +386,12 @@ pub const Entity = struct {
|
||||||
x: i16,
|
x: i16,
|
||||||
y: i16,
|
y: i16,
|
||||||
|
|
||||||
|
pub fn calculateSize() usize {
|
||||||
|
return @sizeOf(u8) + // kind
|
||||||
|
@sizeOf(i16) + // x
|
||||||
|
@sizeOf(i16); // y
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(entity: Entity, writer: anytype) !void {
|
pub fn write(entity: Entity, writer: anytype) !void {
|
||||||
try writer.writeInt(u8, @enumToInt(entity.kind), .Little);
|
try writer.writeInt(u8, @enumToInt(entity.kind), .Little);
|
||||||
try writer.writeInt(i16, entity.x, .Little);
|
try writer.writeInt(i16, entity.x, .Little);
|
||||||
|
@ -396,35 +414,65 @@ pub const Entity = struct {
|
||||||
// | node data... |
|
// | node data... |
|
||||||
// | level data... |
|
// | level data... |
|
||||||
|
|
||||||
const LevelHeader = struct { x: u8, y: u8, offset: u16 };
|
pub const LevelHeader = struct {
|
||||||
|
x: i8,
|
||||||
|
y: i8,
|
||||||
|
offset: u16,
|
||||||
|
|
||||||
|
pub fn write(header: LevelHeader, writer: anytype) !void {
|
||||||
|
try writer.writeInt(i8, header.x, .Little);
|
||||||
|
try writer.writeInt(i8, header.y, .Little);
|
||||||
|
try writer.writeInt(u16, header.offset, .Little);
|
||||||
|
}
|
||||||
|
|
||||||
pub const World = struct {
|
pub fn read(reader: anytype) !LevelHeader {
|
||||||
/// All levels in the game. If two rooms are next to each other, they
|
return LevelHeader{
|
||||||
/// are assumed to be neighbors. Leaving the screen will load in the next
|
.x = try reader.readInt(i8, .Little),
|
||||||
/// level in that direction. The player is placed at the same position
|
.y = try reader.readInt(i8, .Little),
|
||||||
/// vertically, but on the opposite side of the screen horizontally. Vice versa
|
.offset = try reader.readInt(u16, .Little),
|
||||||
/// for vertically moving between screens. The player will retain their momentum.
|
};
|
||||||
///
|
}
|
||||||
/// When a wire crosses a screen boundary, it will coil up at the player's feet
|
|
||||||
/// automatically. If one side of the wire is pinned, the wire will be let go of.
|
|
||||||
///
|
|
||||||
/// Alternatively, the wire will be pinned outside of the level. If it isn't pinned,
|
|
||||||
/// I will need to freeze it and move it in a snake like fashion. Or just leave the
|
|
||||||
/// other level loaded.
|
|
||||||
levels: []Level,
|
|
||||||
/// An abstract representation of all circuits in game.
|
|
||||||
abstract_circuit: []CircuitNode,
|
|
||||||
|
|
||||||
// pub fn write(world: Entity, writer: anytype) !void {
|
|
||||||
// try writer.writeInt(u16, circuit_nodes.len, .Little);
|
|
||||||
// try writer.writeInt(u16, levels.len, .Little);
|
|
||||||
// for (circuit_nodes) |node| {
|
|
||||||
// try node.write_header(writer);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn write(level_headers: []LevelHeader, writer: anytype) !void {
|
||||||
|
// Write number of levels
|
||||||
|
try writer.writeInt(u16, @intCast(u16, level_headers.len), .Little);
|
||||||
|
|
||||||
|
// Write headers
|
||||||
|
for (level_headers) |lvl_header| {
|
||||||
|
try lvl_header.write(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(alloc: std.mem.Allocator, reader: anytype) ![]LevelHeader {
|
||||||
|
// read number of levels
|
||||||
|
const level_count = try reader.readInt(u16, .Little);
|
||||||
|
|
||||||
|
var level_headers = try alloc.alloc(LevelHeader, level_count);
|
||||||
|
// read headers
|
||||||
|
for (level_headers) |_, i| {
|
||||||
|
level_headers[i] = try LevelHeader.read(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return level_headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All levels in the game. If two rooms are next to each other, they
|
||||||
|
// are assumed to be neighbors. Leaving the screen will load in the next
|
||||||
|
// level in that direction. The player is placed at the same position
|
||||||
|
// vertically, but on the opposite side of the screen horizontally. Vice versa
|
||||||
|
// for vertically moving between screens. The player will retain their momentum.
|
||||||
|
//
|
||||||
|
// When a wire crosses a screen boundary, it will coil up at the player's feet
|
||||||
|
// automatically. If one side of the wire is pinned, the wire will be let go of.
|
||||||
|
//
|
||||||
|
// Alternatively, the wire will be pinned outside of the level. If it isn't pinned,
|
||||||
|
// I will need to freeze it and move it in a snake like fashion. Or just leave the
|
||||||
|
// other level loaded.
|
||||||
|
// levels: []Level,
|
||||||
|
// An abstract representation of all circuits in game.
|
||||||
|
// abstract_circuit: []CircuitNode,
|
||||||
|
|
||||||
const NodeID = u16;
|
const NodeID = u16;
|
||||||
|
|
||||||
pub const CircuitNode = struct {
|
pub const CircuitNode = struct {
|
||||||
|
|
|
@ -46,19 +46,16 @@ fn make(step: *std.build.Step) !void {
|
||||||
const source = try source_file.readToEndAlloc(allocator, 10 * MB);
|
const source = try source_file.readToEndAlloc(allocator, 10 * MB);
|
||||||
defer allocator.free(source);
|
defer allocator.free(source);
|
||||||
|
|
||||||
// Create output array to write to
|
|
||||||
var data = std.ArrayList(u8).init(allocator);
|
|
||||||
defer data.deinit();
|
|
||||||
const writer = data.writer();
|
|
||||||
|
|
||||||
var ldtk_parser = try LDtk.parse(allocator, source);
|
var ldtk_parser = try LDtk.parse(allocator, source);
|
||||||
defer ldtk_parser.deinit();
|
defer ldtk_parser.deinit();
|
||||||
|
|
||||||
const ldtk = ldtk_parser.root;
|
const ldtk = ldtk_parser.root;
|
||||||
|
|
||||||
if (ldtk.levels.len > 0) {
|
// Store levels
|
||||||
const level = ldtk.levels[0];
|
var levels = std.ArrayList(world.Level).init(allocator);
|
||||||
|
defer levels.deinit();
|
||||||
|
|
||||||
|
for (ldtk.levels) |level| {
|
||||||
var entity_array = std.ArrayList(world.Entity).init(allocator);
|
var entity_array = std.ArrayList(world.Entity).init(allocator);
|
||||||
defer entity_array.deinit();
|
defer entity_array.deinit();
|
||||||
|
|
||||||
|
@ -68,13 +65,88 @@ fn make(step: *std.build.Step) !void {
|
||||||
.level = level,
|
.level = level,
|
||||||
.entity_array = &entity_array,
|
.entity_array = &entity_array,
|
||||||
});
|
});
|
||||||
defer allocator.free(parsed_level.tiles.?);
|
|
||||||
|
|
||||||
// Save the level!
|
try levels.append(parsed_level);
|
||||||
try parsed_level.write(writer);
|
}
|
||||||
|
defer for (levels.items) |level| {
|
||||||
|
allocator.free(level.tiles.?);
|
||||||
|
allocator.free(level.entities.?);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the offset of each level and store it in the headers.
|
||||||
|
// Offset is relative to the beginning of level.data
|
||||||
|
var level_headers = std.ArrayList(world.LevelHeader).init(allocator);
|
||||||
|
defer level_headers.deinit();
|
||||||
|
|
||||||
|
for (levels.items) |level, i| {
|
||||||
|
if (level_headers.items.len == 0) {
|
||||||
|
try level_headers.append(.{
|
||||||
|
.x = level.world_x,
|
||||||
|
.y = level.world_y,
|
||||||
|
.offset = 0,
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const last_offset = level_headers.items[i - 1].offset;
|
||||||
|
const last_size = try levels.items[i - 1].calculateSize();
|
||||||
|
const offset = @intCast(u16, last_offset + last_size);
|
||||||
|
try level_headers.append(.{
|
||||||
|
.x = level.world_x,
|
||||||
|
.y = level.world_y,
|
||||||
|
.offset = offset,
|
||||||
|
});
|
||||||
|
std.log.warn("[{}] x={} y={}; {} + {} = {}", .{ i, level.world_x, level.world_y, last_offset, last_size, offset });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open output file and write data
|
// Create array to write data to
|
||||||
|
var data = std.ArrayList(u8).init(allocator);
|
||||||
|
defer data.deinit();
|
||||||
|
const writer = data.writer();
|
||||||
|
|
||||||
|
try world.write(level_headers.items, writer);
|
||||||
|
|
||||||
|
// Write levels
|
||||||
|
for (levels.items) |level| {
|
||||||
|
std.log.warn("{} + {} + {} + {} + {} + {} + {}", .{
|
||||||
|
@sizeOf(i8),
|
||||||
|
@sizeOf(i8),
|
||||||
|
@sizeOf(u16),
|
||||||
|
@sizeOf(u16),
|
||||||
|
@sizeOf(u16),
|
||||||
|
level.tiles.?.len,
|
||||||
|
level.entities.?.len * world.Entity.calculateSize(),
|
||||||
|
});
|
||||||
|
|
||||||
|
std.log.warn("x={} y={} w={} s={} ec={} t={} e={}", .{
|
||||||
|
level.world_x,
|
||||||
|
level.world_y,
|
||||||
|
level.width,
|
||||||
|
level.size,
|
||||||
|
level.entity_count,
|
||||||
|
level.tiles.?.len,
|
||||||
|
level.entities.?.len,
|
||||||
|
});
|
||||||
|
try level.write(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var stream = std.io.FixedBufferStream([]const u8){
|
||||||
|
.pos = 0,
|
||||||
|
.buffer = data.items,
|
||||||
|
};
|
||||||
|
const world_reader = stream.reader();
|
||||||
|
var lvls = try world.read(allocator, world_reader);
|
||||||
|
var level_data_offset = try stream.getPos();
|
||||||
|
std.log.warn("level_data_offset {}", .{level_data_offset});
|
||||||
|
|
||||||
|
try stream.seekTo(level_data_offset + lvls[1].offset);
|
||||||
|
std.log.warn("seek to 1 {}", .{try stream.getPos()});
|
||||||
|
|
||||||
|
var level = try world.Level.read(world_reader);
|
||||||
|
std.log.warn("level x={}, y={}", .{ level.world_x, level.world_y });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open output file and write data into it
|
||||||
cwd.makePath(this.builder.getInstallPath(.lib, "")) catch |e| switch (e) {
|
cwd.makePath(this.builder.getInstallPath(.lib, "")) catch |e| switch (e) {
|
||||||
error.PathAlreadyExists => {},
|
error.PathAlreadyExists => {},
|
||||||
else => return e,
|
else => return e,
|
||||||
|
@ -84,7 +156,7 @@ fn make(step: *std.build.Step) !void {
|
||||||
this.world_data.path = output;
|
this.world_data.path = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns parsed layers of the
|
/// Returns parsed level. User owns level.tiles
|
||||||
fn parseLevel(opt: struct {
|
fn parseLevel(opt: struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
ldtk: LDtk.Root,
|
ldtk: LDtk.Root,
|
||||||
|
@ -98,8 +170,8 @@ fn parseLevel(opt: struct {
|
||||||
|
|
||||||
const layers = level.layerInstances orelse return error.NoLayers;
|
const layers = level.layerInstances orelse return error.NoLayers;
|
||||||
|
|
||||||
const world_x: u8 = @intCast(u8, @divExact(level.worldX, (ldtk.worldGridWidth orelse 160)));
|
const world_x: i8 = @intCast(i8, @divExact(level.worldX, (ldtk.worldGridWidth orelse 160)));
|
||||||
const world_y: u8 = @intCast(u8, @divExact(level.worldY, (ldtk.worldGridHeight orelse 160)));
|
const world_y: i8 = @intCast(i8, @divExact(level.worldY, (ldtk.worldGridHeight orelse 160)));
|
||||||
|
|
||||||
var circuit_layer: ?LDtk.LayerInstance = null;
|
var circuit_layer: ?LDtk.LayerInstance = null;
|
||||||
var collision_layer: ?LDtk.LayerInstance = null;
|
var collision_layer: ?LDtk.LayerInstance = null;
|
||||||
|
@ -202,12 +274,9 @@ fn parseLevel(opt: struct {
|
||||||
.width = @intCast(u16, width),
|
.width = @intCast(u16, width),
|
||||||
.size = @intCast(u16, size),
|
.size = @intCast(u16, size),
|
||||||
.entity_count = @intCast(u16, entity_array.items.len),
|
.entity_count = @intCast(u16, entity_array.items.len),
|
||||||
.tiles = null,
|
.tiles = try allocator.alloc(world.TileData, size),
|
||||||
.entities = entity_array.items,
|
.entities = try allocator.dupe(world.Entity, entity_array.items),
|
||||||
};
|
};
|
||||||
parsed_level.tiles = try allocator.alloc(world.TileData, size);
|
|
||||||
// NOTE:
|
|
||||||
// defer allocator.free(level.tiles.?);
|
|
||||||
|
|
||||||
const tiles = parsed_level.tiles.?;
|
const tiles = parsed_level.tiles.?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue