···11+
22+33+# Rockbox Zig 🎵 ⚡
44+55+Rockbox Zig is an incremental enhancement of the [Rockbox](https://www.rockbox.org) firmware for portable audio players in the Zig programming language.
66+77+> [!NOTE]
88+**🐲 It is a work in progress and is not yet ready for use. 🏗️🚧**
99+1010+## 🚀 Quickstart
1111+1212+Run the following commands to build the project:
1313+1414+```sh
1515+. ./bin/activate-hermit
1616+mkdir -p build && \
1717+cd build && \
1818+../tools/configure && \
1919+make zig
2020+```
···11+# Hermit environment
22+33+This is a [Hermit](https://github.com/cashapp/hermit) bin directory.
44+55+The symlinks in this directory are managed by Hermit and will automatically
66+download and install Hermit itself as well as packages. These packages are
77+local to this environment.
+36
bin/activate-hermit
···11+#!/bin/bash
22+# This file must be used with "source bin/activate-hermit" from bash or zsh.
33+# You cannot run it directly
44+#
55+# THIS FILE IS GENERATED; DO NOT MODIFY
66+77+readonly YELLOW="$(tput setaf 3 2>/dev/null || echo '')"
88+readonly NO_COLOR="$(tput sgr0 2>/dev/null || echo '')"
99+1010+if [ "${BASH_SOURCE-}" = "$0" ]; then
1111+ echo "You must source this script: \$ source $0" >&2
1212+ exit 33
1313+fi
1414+1515+BIN_DIR="$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")"
1616+if "${BIN_DIR}/hermit" noop > /dev/null; then
1717+ eval "$("${BIN_DIR}/hermit" activate "${BIN_DIR}/..")"
1818+1919+ if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ]; then
2020+ hash -r 2>/dev/null
2121+ fi
2222+2323+ cat <<EOF
2424+ ${YELLOW}
2525+ __________ __ ___.
2626+ Open \______ \ ____ ____ | | _\_ |__ _______ ___
2727+ Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
2828+ Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
2929+ Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \\
3030+ \/ \/ \/ \/ \/
3131+ ${NO_COLOR}
3232+EOF
3333+ echo Zig $(zig version)
3434+ echo $(which zig)
3535+ echo "Hermit environment $("${HERMIT_ENV}"/bin/hermit env HERMIT_ENV) activated"
3636+fi
+43
bin/hermit
···11+#!/bin/bash
22+#
33+# THIS FILE IS GENERATED; DO NOT MODIFY
44+55+set -eo pipefail
66+77+export HERMIT_USER_HOME=~
88+99+if [ -z "${HERMIT_STATE_DIR}" ]; then
1010+ case "$(uname -s)" in
1111+ Darwin)
1212+ export HERMIT_STATE_DIR="${HERMIT_USER_HOME}/Library/Caches/hermit"
1313+ ;;
1414+ Linux)
1515+ export HERMIT_STATE_DIR="${XDG_CACHE_HOME:-${HERMIT_USER_HOME}/.cache}/hermit"
1616+ ;;
1717+ esac
1818+fi
1919+2020+export HERMIT_DIST_URL="${HERMIT_DIST_URL:-https://github.com/cashapp/hermit/releases/download/stable}"
2121+HERMIT_CHANNEL="$(basename "${HERMIT_DIST_URL}")"
2222+export HERMIT_CHANNEL
2323+export HERMIT_EXE=${HERMIT_EXE:-${HERMIT_STATE_DIR}/pkg/hermit@${HERMIT_CHANNEL}/hermit}
2424+2525+if [ ! -x "${HERMIT_EXE}" ]; then
2626+ echo "Bootstrapping ${HERMIT_EXE} from ${HERMIT_DIST_URL}" 1>&2
2727+ INSTALL_SCRIPT="$(mktemp)"
2828+ # This value must match that of the install script
2929+ INSTALL_SCRIPT_SHA256="180e997dd837f839a3072a5e2f558619b6d12555cd5452d3ab19d87720704e38"
3030+ if [ "${INSTALL_SCRIPT_SHA256}" = "BYPASS" ]; then
3131+ curl -fsSL "${HERMIT_DIST_URL}/install.sh" -o "${INSTALL_SCRIPT}"
3232+ else
3333+ # Install script is versioned by its sha256sum value
3434+ curl -fsSL "${HERMIT_DIST_URL}/install-${INSTALL_SCRIPT_SHA256}.sh" -o "${INSTALL_SCRIPT}"
3535+ # Verify install script's sha256sum
3636+ openssl dgst -sha256 "${INSTALL_SCRIPT}" | \
3737+ awk -v EXPECTED="$INSTALL_SCRIPT_SHA256" \
3838+ '$2!=EXPECTED {print "Install script sha256 " $2 " does not match " EXPECTED; exit 1}'
3939+ fi
4040+ /bin/bash "${INSTALL_SCRIPT}" 1>&2
4141+fi
4242+4343+exec "${HERMIT_EXE}" --level=fatal exec "$0" -- "$@"
···11+.{
22+ // This is the default name used by packages depending on this one. For
33+ // example, when a user runs `zig fetch --save <url>`, this field is used
44+ // as the key in the `dependencies` table. Although the user can choose a
55+ // different name, most users will stick with this provided value.
66+ //
77+ // It is redundant to include "zig" in this name because it is already
88+ // within the Zig package namespace.
99+ .name = "rockbox",
1010+1111+ // This is a [Semantic Version](https://semver.org/).
1212+ // In a future version of Zig it will be used for package deduplication.
1313+ .version = "0.0.0",
1414+1515+ // This field is optional.
1616+ // This is currently advisory only; Zig does not yet do anything
1717+ // with this value.
1818+ //.minimum_zig_version = "0.11.0",
1919+2020+ // This field is optional.
2121+ // Each dependency must either provide a `url` and `hash`, or a `path`.
2222+ // `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
2323+ // Once all dependencies are fetched, `zig build` no longer requires
2424+ // internet connectivity.
2525+ .dependencies = .{
2626+ // See `zig fetch --save <url>` for a command-line interface for adding dependencies.
2727+ //.example = .{
2828+ // // When updating this field to a new URL, be sure to delete the corresponding
2929+ // // `hash`, otherwise you are communicating that you expect to find the old hash at
3030+ // // the new URL.
3131+ // .url = "https://example.com/foo.tar.gz",
3232+ //
3333+ // // This is computed from the file contents of the directory of files that is
3434+ // // obtained after fetching `url` and applying the inclusion rules given by
3535+ // // `paths`.
3636+ // //
3737+ // // This field is the source of truth; packages do not come from a `url`; they
3838+ // // come from a `hash`. `url` is just one of many possible mirrors for how to
3939+ // // obtain a package matching this `hash`.
4040+ // //
4141+ // // Uses the [multihash](https://multiformats.io/multihash/) format.
4242+ // .hash = "...",
4343+ //
4444+ // // When this is provided, the package is found in a directory relative to the
4545+ // // build root. In this case the package's hash is irrelevant and therefore not
4646+ // // computed. This field and `url` are mutually exclusive.
4747+ // .path = "foo",
4848+4949+ // // When this is set to `true`, a package is declared to be lazily
5050+ // // fetched. This makes the dependency only get fetched if it is
5151+ // // actually used.
5252+ // .lazy = false,
5353+ //},
5454+ },
5555+5656+ // Specifies the set of files and directories that are included in this package.
5757+ // Only files and directories listed here are included in the `hash` that
5858+ // is computed for this package. Only files listed here will remain on disk
5959+ // when using the zig package manager. As a rule of thumb, one should list
6060+ // files required for compilation plus any license(s).
6161+ // Paths are relative to the build root. Use the empty string (`""`) to refer to
6262+ // the build root itself.
6363+ // A directory listed here means that all files within, recursively, are included.
6464+ .paths = .{
6565+ "build.zig",
6666+ "build.zig.zon",
6767+ "src",
6868+ // For example...
6969+ //"LICENSE",
7070+ //"README.md",
7171+ },
7272+}
···38383939#define SEEK_REWIND 3840 /* 80 ms @ 48 kHz */
40404141+#ifndef MIN
4242+#define MIN(a,b) ((a)<(b) ? (a):(b))
4343+#endif
4444+4145/* the opus pseudo stack pointer */
4246extern char *global_stack;
4347
+54
src/main.zig
···11+const std = @import("std");
22+33+pub fn main() !void {
44+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
55+ const allocator = gpa.allocator();
66+77+ var file = try std.fs.cwd().openFile("build/make.dep", .{});
88+ defer file.close();
99+1010+ var buffered = std.io.bufferedReader(file.reader());
1111+ var reader = buffered.reader();
1212+1313+ var arr = std.ArrayList(u8).init(allocator);
1414+ defer arr.deinit();
1515+1616+ var line_count: usize = 0;
1717+ var byte_count: usize = 0;
1818+ while (true) {
1919+ reader.streamUntilDelimiter(arr.writer(), '\n', null) catch |err| switch (err) {
2020+ error.EndOfStream => break,
2121+ else => return err,
2222+ };
2323+ line_count += 1;
2424+ byte_count += arr.items.len;
2525+2626+ //if (std.mem.containsAtLeast(u8, arr.items, 1, ".c \\")) {
2727+ // std.debug.print("{s}\n", .{arr.items});
2828+ //}
2929+3030+ arr.clearRetainingCapacity();
3131+ }
3232+ std.debug.print("{d} lines, {d} bytes\n", .{ line_count, byte_count });
3333+3434+ // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
3535+ std.debug.print("All your {s} are belong to us.\n", .{"codebase"});
3636+3737+ // stdout is for the actual output of your application, for example if you
3838+ // are implementing gzip, then only the compressed bytes should be sent to
3939+ // stdout, not any debugging messages.
4040+ const stdout_file = std.io.getStdOut().writer();
4141+ var bw = std.io.bufferedWriter(stdout_file);
4242+ const stdout = bw.writer();
4343+4444+ try stdout.print("Run `zig build test` to run the tests.\n", .{});
4545+4646+ try bw.flush(); // don't forget to flush!
4747+}
4848+4949+test "simple test" {
5050+ var list = std.ArrayList(i32).init(std.testing.allocator);
5151+ defer list.deinit(); // try commenting this out and see if zig detects the memory leak!
5252+ try list.append(42);
5353+ try std.testing.expectEqual(@as(i32, 42), list.pop());
5454+}