diff --git a/assets/Wired.tsx b/assets/Wired.tsx new file mode 100644 index 0000000..7b20f94 --- /dev/null +++ b/assets/Wired.tsx @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/maps/test.json b/assets/maps/test.json new file mode 100644 index 0000000..6a54067 --- /dev/null +++ b/assets/maps/test.json @@ -0,0 +1,32 @@ +{ "compressionlevel":-1, + "height":20, + "infinite":false, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 19, 19, 18, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 50, 19, 52, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 50, 19, 52, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 50, 19, 52, 1, 1, 1, 1, 51, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 50, 19, 52, 1, 1, 1, 1, 1, 1, 1, 1, 51, 1, 2, 1, 37, 1, 54, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 33, 19, 19, 19, 66, 54, 1, 1, 1, 1, 1, 1, 1, 50, 19, 52, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 51, 1, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":20, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.7.2", + "tileheight":8, + "tilesets":[ + { + "firstgid":1, + "source":"wired.tsx" + }], + "tilewidth":8, + "type":"map", + "version":"1.6", + "width":20 +} \ No newline at end of file diff --git a/assets/maps/test.tmx b/assets/maps/test.tmx new file mode 100644 index 0000000..bed699a --- /dev/null +++ b/assets/maps/test.tmx @@ -0,0 +1,31 @@ + + + + + + + + +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,1,1, +1,39,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,37,1, +1,39,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,37,1, +1,39,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,37,1, +1,39,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,37,1, +1,39,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,37,1, +1,39,1,1,1,1,1,1,1,1,1,50,19,19,18,1,1,1,37,1, +1,39,1,1,1,1,1,50,19,52,1,1,1,1,20,1,1,1,37,1, +1,39,1,1,1,1,1,1,1,1,1,1,1,1,20,1,1,1,37,1, +1,39,1,50,19,52,1,1,1,1,1,1,1,1,20,1,1,1,37,1, +1,39,1,1,1,1,1,1,1,1,1,1,1,1,20,1,1,1,37,1, +1,39,1,1,1,1,1,50,19,52,1,1,1,1,51,1,1,1,37,1, +1,39,1,1,1,1,1,1,1,1,1,1,1,1,20,1,1,1,37,1, +1,39,1,50,19,52,1,1,1,1,1,1,1,1,51,1,2,1,37,1, +54,55,1,1,1,1,1,1,1,1,1,1,1,1,33,19,19,19,66,54, +1,1,1,1,1,1,1,50,19,52,1,1,1,1,1,1,1,1,20,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,51,1, +22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + + + diff --git a/assets/maps/wired.tsx b/assets/maps/wired.tsx new file mode 100644 index 0000000..d0a3bb4 --- /dev/null +++ b/assets/maps/wired.tsx @@ -0,0 +1,4 @@ + + + + diff --git a/map.zig b/map.zig new file mode 100644 index 0000000..2c442cb --- /dev/null +++ b/map.zig @@ -0,0 +1 @@ +pub const map: [400]u8 = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 19, 19, 18, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 50, 19, 52, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 50, 19, 52, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 50, 19, 52, 1, 1, 1, 1, 51, 1, 1, 1, 37, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 37, 1, 1, 39, 1, 50, 19, 52, 1, 1, 1, 1, 1, 1, 1, 1, 51, 1, 2, 1, 37, 1, 54, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 33, 19, 19, 19, 66, 54, 1, 1, 1, 1, 1, 1, 1, 50, 19, 52, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 51, 1, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; diff --git a/map2src.zig b/map2src.zig new file mode 100644 index 0000000..be80b71 --- /dev/null +++ b/map2src.zig @@ -0,0 +1,65 @@ +const std = @import("std"); + +const Layer = struct { + data: []u64, + height: u64, + id: u64, + name: []const u8, + opacity: u64, + @"type": enum { tilelayer }, + visible: bool, + width: u64, + x: i64, + y: i64, +}; + +const MapType = struct { + compressionlevel: i64 = -1, + height: u64 = 0, + infinite: bool = false, + layers: []Layer, + nextlayerid: u64 = 0, + nextobjectid: u64 = 0, + orientation: enum { orthogonal } = .orthogonal, + renderorder: enum { @"right-down" } = .@"right-down", + tiledversion: []const u8 = "", + tileheight: u64 = 0, + tilesets: []struct { firstgid: u64, source: []const u8 }, + tilewidth: u64 = 0, + @"type": enum { map } = .map, + version: []const u8 = "", + width: u64 = 0, +}; + +const KB = 1024; +var heap: [64 * KB]u8 = undefined; +var fba = std.heap.FixedBufferAllocator.init(&heap); +var alloc = fba.allocator(); + +pub fn main() anyerror!void { + const cwd = std.fs.cwd(); + var output = try cwd.createFile("map.zig", .{}); + defer output.close(); + + var argsIter = std.process.args(); + const progName = (try argsIter.next(alloc)) orelse ""; + defer alloc.free(progName); + std.log.info("{s}", .{progName}); + + while (try argsIter.next(alloc)) |arg| { + defer alloc.free(arg); + std.log.info("{s}", .{arg}); + var filebuffer: [64 * KB]u8 = undefined; + var filecontents = try cwd.readFile(arg, &filebuffer); + + @setEvalBranchQuota(10000); + var tokenstream = std.json.TokenStream.init(filecontents); + const options = std.json.ParseOptions{ .allocator = fba.allocator() }; + const map = try std.json.parse(MapType, &tokenstream, options); + defer std.json.parseFree(MapType, map, options); + + var outbuffer: [64 * KB]u8 = undefined; + var outcontent = try std.fmt.bufPrint(&outbuffer, "pub const map: [{}]u8 = {any};\n", .{ map.layers[0].data.len, map.layers[0].data }); + _ = try output.writeAll(outcontent); + } +} diff --git a/src/main.zig b/src/main.zig index 8e5a213..a07abea 100644 --- a/src/main.zig +++ b/src/main.zig @@ -48,8 +48,12 @@ const Anim = struct { // Components const Pos = Vec2f; -const Control = struct { controller: enum { player }, state: enum { stand, walk, jump, fall } }; -const Sprite = usize; +const Control = struct { + controller: enum { player }, + state: enum { stand, walk, jump, fall }, + facing: enum { left, right } = .right, +}; +const Sprite = struct { index: usize, flags: w4.BlitFlags }; const StaticAnim = Anim; const ControlAnim = struct { anims: []AnimData, state: Anim }; const Component = struct { @@ -89,7 +93,7 @@ export fn start() void { _ = world.create(.{ .pos = .{ 76, 76 }, .control = .{ .controller = .player, .state = .stand }, - .sprite = 0, + .sprite = .{ .index = 0, .flags = .{ .bpp = .b1 } }, .controlAnim = ControlAnim{ .anims = playerAnim, .state = Anim{ .anim = &.{} }, @@ -116,19 +120,20 @@ export fn update() void { fn drawProcess(_: f32, pos: *Pos, sprite: *Sprite) void { w4.DRAW_COLORS.* = 0x0030; - const tx = (sprite.* * 8) % 128; - const ty = (sprite.* * 8) / 128; - w4.externs.blitSub(&assets.sprites, @floatToInt(i32, pos.*[0]), @floatToInt(i32, pos.*[1]), 8, 8, tx, ty, 128, assets.sprites_flags); + const ipos = w4.Vec2{ @floatToInt(i32, pos.*[0]), @floatToInt(i32, pos.*[1]) }; + const t = w4.Vec2{ @intCast(i32, (sprite.index * 8) % 128), @intCast(i32, (sprite.index * 8) / 128) }; + w4.blitSub(&assets.sprites, ipos, .{ 8, 8 }, t, 128, sprite.flags); } fn staticAnimProcess(_: f32, sprite: *Sprite, anim: *StaticAnim) void { - anim.update(sprite); + anim.update(&sprite.index); } fn controlAnimProcess(_: f32, sprite: *Sprite, anim: *ControlAnim, control: *Control) void { const a: usize = if (control.state == .stand) 0 else 1; + sprite.flags.flip_x = (control.facing == .left); anim.state.play(anim.anims[a]); - anim.state.update(sprite); + anim.state.update(&sprite.index); } fn controlProcess(_: f32, pos: *Pos, control: *Control) void { @@ -140,6 +145,10 @@ fn controlProcess(_: f32, pos: *Pos, control: *Control) void { if (delta[0] != 0 or delta[1] != 0) { control.state = .walk; pos.* += delta; + if (pos.*[0] < 0) pos.*[0] = 0; + if (pos.*[0] > 152) pos.*[0] = 152; + if (delta[0] > 0) control.facing = .right; + if (delta[0] < 0) control.facing = .left; } else { control.state = .stand; } diff --git a/src/wasm4.zig b/src/wasm4.zig index 2bc015b..ad7d852 100644 --- a/src/wasm4.zig +++ b/src/wasm4.zig @@ -200,13 +200,13 @@ pub const externs = struct { /// Copies pixels to the framebuffer. pub fn blit(sprite: []const u8, pos: Vec2, size: Vec2, flags: BlitFlags) void { - if (sprite.len * 8 != size[x] * size[y]) unreachable; + if (sprite.len * 8 < size[x] * size[y]) unreachable; externs.blit(sprite.ptr, pos[x], pos[y], size[x], size[y], @bitCast(u32, flags)); } /// Copies a subregion within a larger sprite atlas to the framebuffer. pub fn blitSub(sprite: []const u8, pos: Vec2, size: Vec2, src: Vec2, strie: i32, flags: BlitFlags) void { - if (sprite.len * 8 >= size[x] * size[y]) trace("Sprite not large enough {}", .{sprite.len}); + if (sprite.len * 8 < size[x] * size[y]) unreachable; externs.blitSub(sprite.ptr, pos[x], pos[y], size[x], size[y], @intCast(u32, src[x]), @intCast(u32, src[y]), strie, @bitCast(u32, flags)); }