Skip to content

Commit

Permalink
Intro and fix (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperAuguste authored May 13, 2024
1 parent 37ef588 commit 11f0a4a
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 33 deletions.
41 changes: 22 additions & 19 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ pub const py_badge: MicroZig.Target = .{
.hal = null,
};

pub const sycl_badge = MicroZig.Target{
.preferred_format = .elf,
.chip = atsam.chips.atsamd51j19.chip,
.hal = .{
.root_source_file = .{ .cwd_relative = "src/hal.zig" },
},
.board = .{
.name = "SYCL Badge Rev A",
.root_source_file = .{ .cwd_relative = "src/board.zig" },
},
.linker_script = .{ .cwd_relative = "src/badge/samd51j19a_self.ld" },
};
fn sycl_badge_microzig_target(d: *Build.Dependency) MicroZig.Target {
return .{
.preferred_format = .elf,
.chip = atsam.chips.atsamd51j19.chip,
.hal = .{
.root_source_file = d.path("src/hal.zig"),
},
.board = .{
.name = "SYCL Badge Rev A",
.root_source_file = d.path("src/board.zig"),
},
.linker_script = d.path("src/badge/samd51j19a_self.ld"),
};
}

pub fn build(b: *Build) void {
const mz = MicroZig.init(b, .{});
Expand Down Expand Up @@ -71,7 +73,7 @@ pub fn build(b: *Build) void {

const badge = mz.add_firmware(b, .{
.name = "badge",
.target = sycl_badge,
.target = sycl_badge_microzig_target(&dep),
.optimize = .ReleaseSmall,
.root_source_file = .{ .path = "src/badge.zig" },
});
Expand All @@ -92,7 +94,7 @@ pub fn build(b: *Build) void {
}) |name| {
const mvp = mz.add_firmware(b, .{
.name = std.fmt.comptimePrint("badge.demo.{s}", .{name}),
.target = sycl_badge,
.target = sycl_badge_microzig_target(&dep),
.optimize = optimize,
.root_source_file = .{ .path = std.fmt.comptimePrint("src/badge/demos/{s}.zig", .{name}) },
});
Expand Down Expand Up @@ -152,6 +154,7 @@ pub const Cart = struct {
// watch_run.addArgs(&.{ "serve", b.graph.zig_exe, "--input-dir", b.pathFromRoot(std.fs.path.dirname(options.root_source_file) orelse ""), "--cart", b.pathFromRoot("zig-out/bin/feature_test.wasm") });
watch_run.addArgs(&.{ "serve", b.graph.zig_exe });
if (opt.watch_dirs) |dirs| {
if (dirs.len == 0) @panic("watch input directories should either be empty or null");
for (dirs) |dir| {
watch_run.addArgs(&.{ "--input-dir", dir });
}
Expand Down Expand Up @@ -199,7 +202,7 @@ pub fn add_cart(
wasm.root_module.addImport("cart-api", d.module("cart-api"));

const sycl_badge_target =
b.resolveTargetQuery(sycl_badge.chip.cpu.target);
b.resolveTargetQuery(sycl_badge_microzig_target(d).chip.cpu.target);

const cart_lib = b.addStaticLibrary(.{
.name = "cart",
Expand All @@ -212,7 +215,7 @@ pub fn add_cart(
.use_lld = true,
});
cart_lib.root_module.addImport("cart-api", d.module("cart-api"));
cart_lib.linker_script = .{ .path = "src/cart.ld" };
cart_lib.linker_script = d.path("src/cart.ld");

const fw_options = b.addOptions();
fw_options.addOption(bool, "have_cart", true);
Expand All @@ -221,10 +224,10 @@ pub fn add_cart(

const fw = mz.add_firmware(d.builder, .{
.name = options.name,
.target = sycl_badge,
.target = sycl_badge_microzig_target(d),
.optimize = options.optimize,
.root_source_file = .{ .path = "src/main.zig" },
.linker_script = .{ .path = "src/cart.ld" },
.root_source_file = d.path("src/main.zig"),
.linker_script = d.path("src/cart.ld"),
});
fw.artifact.linkLibrary(cart_lib);
fw.artifact.step.dependOn(&fw_options.step);
Expand Down
6 changes: 5 additions & 1 deletion docs/introduction/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Introduction

This guide will help you get up and running with the badge and fittingly help introduce you to other attendees.
This is a small example that shows how to use the badge as an actual badge with a little game as a bonus.

## What's Inside

See `src/hello.zig` and tweak the the values to your liking.

## Running

Expand Down
2 changes: 1 addition & 1 deletion docs/introduction/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
const feature_test_cart = badge.add_cart(dep, b, .{
.name = "hello",
.optimize = .ReleaseSmall,
.root_source_file = .{ .path = "hello.zig" },
.root_source_file = .{ .path = "src/hello.zig" },
});
const watch_run_step = feature_test_cart.install_with_watcher(dep, b, .{});

Expand Down
10 changes: 0 additions & 10 deletions docs/introduction/hello.zig

This file was deleted.

164 changes: 164 additions & 0 deletions docs/introduction/src/hello.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
const std = @import("std");
const cart = @import("cart-api");

export fn start() void {}

var scene: enum { intro, game } = .intro;

export fn update() void {
switch (scene) {
.intro => scene_intro(),
.game => scene_game(),
}
}

const lines = &[_][]const u8{
"Auguste Rame",
"~AOE4 Player",

"",

"aurame",
"SuperAuguste",

"",

"SYCL24",
"Press START",
};
const spacing = (cart.font_height * 4 / 3);

var ticks: u8 = 0;

fn scene_intro() void {
set_background();

@memset(cart.neopixels, .{
.r = 0,
.g = 0,
.b = 0,
});

if (ticks / 128 == 0) {
// Make the neopixel 24-bit color LEDs a nice Zig orange
@memset(cart.neopixels, .{
.r = 247,
.g = 164,
.b = 29,
});
}

const y_start = (cart.screen_height - (cart.font_height + spacing * (lines.len - 1))) / 2;

// Write it out!
for (lines, 0..) |line, i| {
cart.text(.{
.text_color = .{ .r = 31, .g = 63, .b = 31 },
.str = line,
.x = @intCast((cart.screen_width - cart.font_width * line.len) / 2),
.y = @intCast(y_start + spacing * i),
});
}

if (ticks == 0) cart.red_led.* = !cart.red_led.*;
if (cart.controls.start) scene = .game;

ticks +%= 4;
}

const Player = enum(u8) { x = 0, o = 1, none = std.math.maxInt(u8) };

var selected_x: u8 = 0;
var selected_y: u8 = 0;
var control_cooldown: bool = false;
var turn: Player = .x;
var state: [3][3]Player = @bitCast([1]Player{.none} ** 9);

fn scene_game() void {
set_background();

const title = "TIC-TAC-TOE";
cart.text(.{
.text_color = .{ .r = 31, .g = 63, .b = 31 },
.str = title,
.x = @intCast((cart.screen_width - cart.font_width * title.len) / 2),
.y = 10,
});

const instructions = "D-PAD + SELECT";
cart.text(.{
.text_color = .{ .r = 31, .g = 63, .b = 31 },
.str = instructions,
.x = @intCast((cart.screen_width - cart.font_width * instructions.len) / 2),
.y = cart.screen_height - cart.font_height - 10,
});

for (0..3) |y| {
for (0..3) |x| {
cart.rect(.{
.stroke_color = .{ .r = 31, .g = 63, .b = 31 },
.fill_color = if (x == selected_x and y == selected_y) .{ .r = 31 / 2, .g = 63 / 2, .b = 31 / 2 } else null,
.x = @intCast(cart.screen_width / 2 + x * 19 - 10 * 3),
.y = @intCast(cart.screen_height / 2 + y * 19 - 10 * 3),
.width = 20,
.height = 20,
});

cart.text(.{
.text_color = .{ .r = 31, .g = 63, .b = 31 },
.str = switch (state[y][x]) {
.x => "X",
.o => "O",
.none => "",
},
.x = @intCast(cart.screen_width / 2 + x * 19 - 10 * 3 + 7),
.y = @intCast(cart.screen_height / 2 + y * 19 - 10 * 3 + 7),
});
}
}

if (!control_cooldown) {
if (cart.controls.left) selected_x -|= 1;
if (cart.controls.right and selected_x != 2) selected_x += 1;
if (cart.controls.up) selected_y -|= 1;
if (cart.controls.down and selected_y != 2) selected_y += 1;
if (cart.controls.select and state[selected_y][selected_x] == .none) {
state[selected_y][selected_x] = turn;
turn = switch (turn) {
.x => .o,
.o => .x,
else => unreachable,
};

if (check_win()) {
turn = .x;
@memset(@as(*[9]Player, @ptrCast(&state)), .none);
scene = .intro;
selected_x = 0;
selected_y = 0;
}
}
}

control_cooldown = false;
if (cart.controls.left or cart.controls.right or cart.controls.up or cart.controls.down or cart.controls.select) control_cooldown = true;
}

fn set_background() void {
const ratio = (4095 - @as(f32, @floatFromInt(cart.light_level.*))) / 4095 * 0.2;

@memset(cart.framebuffer, cart.DisplayColor{
.r = @intFromFloat(ratio * 31),
.g = @intFromFloat(ratio * 63),
.b = @intFromFloat(ratio * 31),
});
}

fn check_win() bool {
for (0..3) |i| {
if (state[i][0] != .none and state[i][0] == state[i][1] and state[i][1] == state[i][2]) return true;
if (state[0][i] != .none and state[0][i] == state[1][i] and state[1][i] == state[2][i]) return true;
}

return (state[0][0] != .none and state[0][0] == state[1][1] and state[1][1] == state[2][2]) or (state[0][2] != .none and state[0][2] == state[1][1] and state[1][1] == state[2][0]);
}
4 changes: 2 additions & 2 deletions samples/feature_test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ fn read_stored_number() u64 {

fn write_stored_number(number: u64) void {
var page: [cart.flash_page_size]u8 = undefined;
// @as(*u64, @alignCast(@ptrCast(page[0..8]))).* = number;
std.mem.bytesAsSlice(u64, &page)[0] = number;
cart.write_flash_page(0, page);
}
Expand All @@ -39,7 +38,8 @@ export fn update() void {
var inputs_buf: [128]u8 = undefined;
var fbs = std.io.fixedBufferStream(&inputs_buf);

fbs.writer().print("{d}\n", .{read_stored_number()}) catch unreachable;
// ENABLE AT YOUR OWN RISK
// fbs.writer().print("{d}\n", .{read_stored_number()}) catch unreachable;

inline for (std.meta.fields(cart.Controls)) |control| {
if (comptime !std.mem.eql(u8, control.name, "padding")) {
Expand Down
4 changes: 4 additions & 0 deletions src/cart/api.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const builtin = @import("builtin");
pub const screen_width: u32 = 160;
pub const screen_height: u32 = 128;

pub const font_width: u32 = 8;
pub const font_height: u32 = 8;

// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Memory Addresses │
Expand Down Expand Up @@ -63,6 +66,7 @@ pub const Controls = packed struct(u9) {
};

pub const controls: *const Controls = @ptrFromInt(base + 0x04);
/// 0-4095
pub const light_level: *const u12 = @ptrFromInt(base + 0x06);
/// 5 24-bit color LEDs
pub const neopixels: *[5]NeopixelColor = @ptrFromInt(base + 0x08);
Expand Down

0 comments on commit 11f0a4a

Please sign in to comment.