Succesfully load autotiles
parent
f944f754b1
commit
21f8ae7087
|
@ -12,9 +12,13 @@ pub fn build(b: *std.build.Builder) !void {
|
|||
.output_name = "mapldtk",
|
||||
});
|
||||
|
||||
const data_step = b.addOptions();
|
||||
data_step.addOptionFileSource("path", .{.generated = &ldtk.world_data });
|
||||
|
||||
const mode = b.standardReleaseOptions();
|
||||
const lib = b.addSharedLibrary("cart", "src/main.zig", .unversioned);
|
||||
lib.step.dependOn(&ldtk.step);
|
||||
lib.step.dependOn(&data_step.step);
|
||||
lib.addPackage(data_step.getPackage("world_data"));
|
||||
lib.addPackage(assets);
|
||||
lib.setBuildMode(mode);
|
||||
lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
const w4 = @import("wasm4.zig");
|
||||
const std = @import("std");
|
||||
const Map = @import("map.zig");
|
||||
const Circuit = @import("circuit.zig");
|
||||
|
||||
const world = @import("world.zig");
|
||||
const Level = world.Level;
|
||||
const Level = world.AutoTile;
|
||||
const AutoTile = world.AutoTile;
|
||||
const CircuitType = world.CircuitType;
|
||||
|
||||
pub const ExtractOptions = struct {
|
||||
pub const Options = struct {
|
||||
map: *Map,
|
||||
circuit: *Circuit,
|
||||
alloc: std.mem.Allocator,
|
||||
level: world.Level,
|
||||
tileset: world.AutoTileset,
|
||||
};
|
||||
|
||||
fn is_solid(tile: u7) bool {
|
||||
return tile != 0 and tile != 1;
|
||||
}
|
||||
|
||||
/// Extracts a compressed level into the map and circuit buffers
|
||||
pub fn extractLevel(alloc: std.mem.Allocator, level: Level, opt: ExtractOptions) void {
|
||||
pub fn extractLevel(opt: Options) !void {
|
||||
const map = opt.map;
|
||||
const circuit = opt.circuit;
|
||||
const alloc = opt.alloc;
|
||||
const level = opt.level;
|
||||
const tileset = opt.tileset;
|
||||
|
||||
const width = level.width;
|
||||
const height = @divExact(@intCast(u16, level.tiles.len), level.width);
|
||||
const size = level.tiles.len;
|
||||
|
||||
map.map_size = .{ level.width, height };
|
||||
circuit.map_size = .{ level.width, height };
|
||||
|
||||
|
@ -29,23 +43,29 @@ pub fn extractLevel(alloc: std.mem.Allocator, level: Level, opt: ExtractOptions)
|
|||
|
||||
for (level.tiles) |tile, i| {
|
||||
if (tile.is_tile) {
|
||||
solid_map[i] = is_solid(tile.data.tile);
|
||||
map.map[i] = tile.data.tile;
|
||||
// solid_map[i] = is_solid(tile.data.tile);
|
||||
map.tiles[i] = tile.data.tile;
|
||||
circuit_map[i] = .None;
|
||||
} else {
|
||||
solid_map = tile.data.flags.solid;
|
||||
solid_map[i] = tile.data.flags.solid;
|
||||
circuit_map[i] = @intToEnum(CircuitType, tile.data.flags.circuit);
|
||||
}
|
||||
}
|
||||
|
||||
var autotiles = try alloc.alloc(AutoTile, size);
|
||||
var autotiles = try alloc.alloc(?AutoTile, size);
|
||||
defer alloc.free(autotiles);
|
||||
|
||||
{
|
||||
var i: usize = 0;
|
||||
while (i < level.tiles.len) : (i += 1) {
|
||||
const x = @mod(i, width);
|
||||
const y = @divTrunc(a, width);
|
||||
const y = @divTrunc(i, width);
|
||||
const stride = width;
|
||||
|
||||
if (!solid_map[i]) {
|
||||
autotiles[i] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
const out_of_bounds = true;
|
||||
var north = false;
|
||||
|
@ -56,11 +76,11 @@ pub fn extractLevel(alloc: std.mem.Allocator, level: Level, opt: ExtractOptions)
|
|||
// Check horizontal neighbors
|
||||
if (x == 0) {
|
||||
west = out_of_bounds;
|
||||
}
|
||||
else if (x == width - 1) {
|
||||
east = solid_map[i + 1];
|
||||
} else if (x == width - 1) {
|
||||
west = solid_map[i - 1];
|
||||
east = out_of_bounds;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
west = solid_map[i - 1];
|
||||
east = solid_map[i + 1];
|
||||
}
|
||||
|
@ -68,13 +88,13 @@ pub fn extractLevel(alloc: std.mem.Allocator, level: Level, opt: ExtractOptions)
|
|||
// Check vertical neighbours
|
||||
if (y == 0) {
|
||||
north = out_of_bounds;
|
||||
}
|
||||
else if (y == height - 1) {
|
||||
south = solid_map[i + stride];
|
||||
} else if (y == height - 1) {
|
||||
north = solid_map[i - stride];
|
||||
south = out_of_bounds;
|
||||
}
|
||||
else {
|
||||
north = solid_map[i - width];
|
||||
south = solid_map[i + width];
|
||||
} else {
|
||||
north = solid_map[i - stride];
|
||||
south = solid_map[i + stride];
|
||||
}
|
||||
|
||||
autotiles[i] = AutoTile{
|
||||
|
@ -86,7 +106,11 @@ pub fn extractLevel(alloc: std.mem.Allocator, level: Level, opt: ExtractOptions)
|
|||
}
|
||||
}
|
||||
|
||||
for (autotiles) |autotile, i| {
|
||||
map.map[i] = tileset.lookup[autotile.to_u4()];
|
||||
for (autotiles) |autotile_opt, i| {
|
||||
if (autotile_opt) |autotile| {
|
||||
const li = autotile.to_u4();
|
||||
const tile = tileset.lookup[li];
|
||||
map.tiles[i] = tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,8 @@ export fn update() void {
|
|||
.Menu => menu.update(),
|
||||
.Game => game.update(time) catch |e| switch (e) {
|
||||
error.Overflow => showErr(@errorName(e)),
|
||||
error.OutOfBounds => showErr(@errorName(e)),
|
||||
// error.OutOfBounds => showErr(@errorName(e)),
|
||||
error.EndOfStream => showErr(@errorName(e)),
|
||||
},
|
||||
};
|
||||
if (state != newState) {
|
||||
|
@ -38,7 +39,9 @@ export fn update() void {
|
|||
.Menu => menu.start(),
|
||||
.Game => game.start() catch |e| switch (e) {
|
||||
error.Overflow => showErr(@errorName(e)),
|
||||
error.OutOfBounds => showErr(@errorName(e)),
|
||||
// error.OutOfBounds => showErr(@errorName(e)),
|
||||
error.EndOfStream => showErr(@errorName(e)),
|
||||
error.OutOfMemory => showErr(@errorName(e)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const world_data = @import("world_data");
|
||||
const Circuit = @import("map.zig");
|
||||
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;
|
||||
|
@ -22,22 +23,50 @@ var circuit: Circuit = undefined;
|
|||
|
||||
var level_size = Vec2{ 20, 20 };
|
||||
|
||||
pub fn start() void {
|
||||
pub fn start() !void {
|
||||
circuit = try Circuit.init(&circuit_buf, &circuit_lvl_buf, level_size);
|
||||
map = Map.init(&map_buf, level_size);
|
||||
|
||||
const extract_opt = world.ExtractOptions{
|
||||
var stream = std.io.FixedBufferStream([]const u8){
|
||||
.pos = 0,
|
||||
.buffer = world_data,
|
||||
};
|
||||
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);
|
||||
|
||||
try extract.extractLevel(.{
|
||||
.alloc = frame_alloc,
|
||||
.level = level,
|
||||
.map = &map,
|
||||
.circuit = &circuit,
|
||||
};
|
||||
|
||||
const world_reader = std.io.FixedBufferStream([]const u8).reader();
|
||||
const level = world_reader.readStruct(world.Level);
|
||||
|
||||
world.extractLevel(frame_alloc, level, extract_opt);
|
||||
.tileset = world.AutoTileset{ .lookup = .{
|
||||
35, // Island
|
||||
51, // North
|
||||
52, // West
|
||||
55, // West-North
|
||||
50, // East
|
||||
53, // East-North
|
||||
19, // East-West
|
||||
54, // East-West-North
|
||||
49, // South
|
||||
20, // South-North
|
||||
23, // South-West
|
||||
39, // South-West-North
|
||||
21, // South-East
|
||||
37, // South-East-North
|
||||
22, // South-East-West
|
||||
0, // South-East-West-North
|
||||
}},
|
||||
});
|
||||
}
|
||||
|
||||
pub fn update() State {
|
||||
pub fn update(time: usize) !State {
|
||||
_ = time;
|
||||
// Reset the frame allocator
|
||||
frame_fba.reset();
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ pub const TileStore = struct {
|
|||
pub fn fromByte(byte: u8) TileStore {
|
||||
const is_tile = (1 & byte) > 0;
|
||||
if (is_tile) {
|
||||
const tile = @intCast(u7, (~1 & byte) >> 1);
|
||||
const tile = @intCast(u7, (~@as(u7, 1) & byte) >> 1);
|
||||
return TileStore{
|
||||
.is_tile = is_tile,
|
||||
.data = .{ .tile = tile },
|
||||
|
@ -84,7 +84,7 @@ pub const LevelHeader = struct {
|
|||
std.debug.assert(buf.len > header.size);
|
||||
var i: usize = 0;
|
||||
while (i < header.size) : (i += 1) {
|
||||
buf[i] = TileStore.fromByte(reader.readByte());
|
||||
buf[i] = TileStore.fromByte(try reader.readByte());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -94,14 +94,23 @@ pub const Level = struct {
|
|||
world_y: u8,
|
||||
width: u16,
|
||||
tiles: []TileStore,
|
||||
|
||||
pub fn init(header: LevelHeader, buf: []TileStore) Level {
|
||||
return Level {
|
||||
.world_x = header.world_x,
|
||||
.world_y = header.world_y,
|
||||
.width = header.width,
|
||||
.tiles = buf[0..header.size],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// AutoTile algorithm datatypes
|
||||
pub const AutoTile = packed struct {
|
||||
North: bool,
|
||||
West: bool,
|
||||
South: bool,
|
||||
East: bool,
|
||||
South: bool,
|
||||
|
||||
pub fn to_u4(autotile: AutoTile) u4 {
|
||||
return @bitCast(u4, autotile);
|
||||
|
|
|
@ -12,6 +12,7 @@ step: std.build.Step,
|
|||
builder: *std.build.Builder,
|
||||
source_path: std.build.FileSource,
|
||||
output_name: []const u8,
|
||||
world_data: std.build.GeneratedFile,
|
||||
|
||||
pub fn create(b: *std.build.Builder, opt: struct {
|
||||
source_path: std.build.FileSource,
|
||||
|
@ -23,7 +24,9 @@ pub fn create(b: *std.build.Builder, opt: struct {
|
|||
.builder = b,
|
||||
.source_path = opt.source_path,
|
||||
.output_name = opt.output_name,
|
||||
.world_data = undefined,
|
||||
};
|
||||
result.*.world_data = std.build.GeneratedFile{ .step = &result.*.step };
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -136,4 +139,6 @@ fn make(step: *std.build.Step) !void {
|
|||
else => return e,
|
||||
};
|
||||
try cwd.writeFile(output, data.items);
|
||||
|
||||
this.world_data.path = output;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue