diff --git a/README.md b/README.md index 0126db1f241..3f2b9ae8051 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,11 @@ mkdir -p build && cd build ../tools/configure --target=sdlapp --type=N --lcdwidth=320 --lcdheight=240 --prefix=$HOME/.local make zig ``` + +Or with Nix: +```sh +nix develop +mkdir -p build && cd build +../tools/configure --target=sdlapp --type=N --lcdwidth=320 --lcdheight=240 --prefix=$HOME/.local +make zig +``` diff --git a/apps/main.c b/apps/main.c index 30175e7ec82..cacac48812c 100644 --- a/apps/main.c +++ b/apps/main.c @@ -155,6 +155,8 @@ /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */ +extern int hello(int x); + static void init(void); /* main(), and various functions called by main() and init() may be * be INIT_ATTR. These functions must not be called after the final call @@ -194,6 +196,8 @@ int main(void) usb_start_monitoring(); #endif +hello(2024); + #if !defined(DISABLE_ACTION_REMAP) && defined(CORE_KEYREMAP_FILE) if (file_exists(CORE_KEYREMAP_FILE)) { diff --git a/apps/plugins/helloworldzig.c b/apps/plugins/helloworldzig.c new file mode 100644 index 00000000000..29d1141ff3f --- /dev/null +++ b/apps/plugins/helloworldzig.c @@ -0,0 +1,44 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Björn Stenberg + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* welcome to the example rockbox plugin */ + +/* mandatory include for all plugins */ +#include "plugin.h" + +extern int32_t hello(void); + +/* this is the plugin entry point */ +enum plugin_status plugin_start(const void* parameter) +{ + /* if you don't use the parameter, you can do like + this to avoid the compiler warning about it */ + (void)parameter; + + /* "rb->" marks a plugin api call. Rockbox offers many of its built-in + * functions to plugins */ + /* now go ahead and have fun! */ + // rb->splash(HZ*2, "Hello world!"); + hello(); + + /* tell Rockbox that we have completed successfully */ + return PLUGIN_OK; +} diff --git a/build.zig b/build.zig index 161806a5e04..8b6330c8533 100644 --- a/build.zig +++ b/build.zig @@ -65,6 +65,18 @@ pub fn build(b: *std.Build) !void { // step when running `zig build`). b.installArtifact(exe); + const hello = b.addStaticLibrary(.{ + .name = "hello", + .root_source_file = b.path("src/hello_world.zig"), + .target = target, + .optimize = optimize, + }); + + b.installArtifact(hello); + defineCMacros(hello); + addIncludePaths(hello); + hello.linkLibC(); + // This *creates* a Run step in the build graph, to be executed when another // step is evaluated that depends on it. The next line below will establish // such a dependency. @@ -159,8 +171,6 @@ pub fn build(b: *std.Build) !void { defineCMacros(libfirmware); addIncludePaths(libfirmware); - libfirmware.linkSystemLibrary("usb"); - const libspeex_voice = b.addStaticLibrary(.{ .name = "speex-voice", .target = target, @@ -1567,6 +1577,9 @@ pub fn build(b: *std.Build) !void { defineCMacros(libpluginbitmaps); addPluginIncludePaths(libpluginbitmaps); + defineCMacros(lib); + addIncludePaths(lib); + const chopper = try build_plugin(b, .{ .name = "chopper", .target = target, @@ -2922,6 +2935,7 @@ pub fn build(b: *std.Build) !void { defineCMacros(exe); addIncludePaths(exe); + exe.linkLibrary(hello); exe.linkLibrary(libfirmware); exe.linkLibrary(libspeex_voice); exe.linkLibrary(librbcodec); @@ -2942,8 +2956,8 @@ fn build_tools(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.bu build_convbdf(b, target, optimize); build_codepages(b, target, optimize); build_voicefont(b, target, optimize); - build_usb_benchmark(b, target, optimize); - build_convttf(b, target, optimize); + // build_usb_benchmark(b, target, optimize); + // build_convttf(b, target, optimize); build_mk500boot(b, target, optimize); } diff --git a/build.zig.zon b/build.zig.zon index b20bc78be9f..5d884582445 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -10,7 +10,7 @@ // This is a [Semantic Version](https://semver.org/). // In a future version of Zig it will be used for package deduplication. - .version = "0.0.0", + .version = "0.1.0", // This field is optional. // This is currently advisory only; Zig does not yet do anything diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000000..9808aec0293 --- /dev/null +++ b/flake.lock @@ -0,0 +1,95 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1725634671, + "narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1718622336, + "narHash": "sha256-lywfxWRBn+lwdKaBy5x5uTkbCcEPUonCn6bK8OQPsw4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d0fc4188d246ab953653f00e9ce0cf51d10d5eda", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "zig2nix": "zig2nix" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "zig2nix": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1724289899, + "narHash": "sha256-DC24naOhfxa4eVQObq7puTpYmklzgtUJLD2+Im17Sbg=", + "owner": "Cloudef", + "repo": "zig2nix", + "rev": "7377653b6da83f907f5c3ed9299f12569c24bb13", + "type": "github" + }, + "original": { + "owner": "Cloudef", + "repo": "zig2nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000000..1018a9583b2 --- /dev/null +++ b/flake.nix @@ -0,0 +1,106 @@ +{ + description = "Rockbox Zig project flake"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + zig2nix.url = "github:Cloudef/zig2nix"; + }; + + outputs = { zig2nix, nixpkgs, ... }: let + flake-utils = zig2nix.inputs.flake-utils; + in (flake-utils.lib.eachDefaultSystem (system: let + pkgs = import nixpkgs { + inherit system; + }; + + inherit (pkgs) lib; + # Zig flake helper + # Check the flake.nix in zig2nix project for more options: + # + env = zig2nix.outputs.zig-env.${system} { zig = pkgs.zig; }; + system-triple = env.lib.zigTripleFromString system; + in with builtins; with env.lib; with env.pkgs.lib; rec { + # nix build .#target.{zig-target} + # e.g. nix build .#target.x86_64-linux-gnu + packages.target = genAttrs allTargetTriples (target: env.packageForTarget target ({ + src = cleanSource ./.; + + nativeBuildInputs = with env.pkgs; []; + buildInputs = with env.pkgsForTarget target; [ + pkgs.zig + pkgs.SDL_compat + pkgs.freetype + pkgs.gnumake + pkgs.pkg-config + pkgs.gcc + pkgs.zlib + ]; + + # Smaller binaries and avoids shipping glibc. + zigPreferMusl = false; + + # This disables LD_LIBRARY_PATH mangling, binary patching etc... + # The package won't be usable inside nix. + zigDisableWrap = false; + } // optionalAttrs (!pathExists ./build.zig.zon) { + pname = "rockbox-zig"; + version = "0.1.0"; + })); + + # nix build . + packages.default = packages.target.${system-triple}.override { + # Prefer nix friendly settings. + zigPreferMusl = false; + zigDisableWrap = false; + }; + + # For bundling with nix bundle for running outside of nix + # example: https://github.com/ralismark/nix-appimage + apps.bundle.target = genAttrs allTargetTriples (target: let + pkg = packages.target.${target}; + in { + type = "app"; + program = "${pkg}/bin/default"; + }); + + # default bundle + apps.bundle.default = apps.bundle.target.${system-triple}; + + # nix run . + apps.default = env.app [] "zig build run -- \"$@\""; + + # nix run .#build + apps.build = env.app [] "zig build \"$@\""; + + # nix run .#test + apps.test = env.app [] "zig build test -- \"$@\""; + + # nix run .#docs + apps.docs = env.app [] "zig build docs -- \"$@\""; + + # nix run .#deps + apps.deps = env.showExternalDeps; + + # nix run .#zon2json + apps.zon2json = env.app [env.zon2json] "zon2json \"$@\""; + + # nix run .#zon2json-lock + apps.zon2json-lock = env.app [env.zon2json-lock] "zon2json-lock \"$@\""; + + # nix run .#zon2nix + apps.zon2nix = env.app [env.zon2nix] "zon2nix \"$@\""; + + # nix develop + devShells.default = env.mkShell { + nativeBuildInputs = with env.pkgs; [ + pkgs.zig + pkgs.SDL_compat + pkgs.freetype + pkgs.gnumake + pkgs.pkg-config + pkgs.gcc + pkgs.zlib + ]; + }; + })); +} \ No newline at end of file diff --git a/src/hello_world.zig b/src/hello_world.zig new file mode 100644 index 00000000000..a93ef3126bf --- /dev/null +++ b/src/hello_world.zig @@ -0,0 +1,10 @@ +const std = @import("std"); +const rockbox = @import("./root.zig"); + +export fn hello(x: i32) i32 { + _ = rockbox.playback.audioNextTrack(); + _ = rockbox.playback.audioCurrentTrack(); + const status = rockbox.playback.audioStatus(); + std.debug.print("Hello, World! {} {}\n", .{ x, status }); + return 0; +} diff --git a/src/rockbox/browse.zig b/src/rockbox/browse.zig new file mode 100644 index 00000000000..ec725160557 --- /dev/null +++ b/src/rockbox/browse.zig @@ -0,0 +1,15 @@ +pub fn rockboxBrowse() void {} + +pub fn treeGetContext() void {} + +pub fn treeGetEntries() void {} + +pub fn treeGetEntryAt() void {} + +pub fn setCurrentFile() void {} + +pub fn setDirfilter() void {} + +pub fn onplayShowPlaylistMenu() void {} + +pub fn browseId3() void {} diff --git a/src/rockbox/dir.zig b/src/rockbox/dir.zig new file mode 100644 index 00000000000..2b7b54c0f98 --- /dev/null +++ b/src/rockbox/dir.zig @@ -0,0 +1,13 @@ +pub fn opendir() void {} + +pub fn closedir() void {} + +pub fn readdir() void {} + +pub fn mkdir() void {} + +pub fn rmdir() void {} + +pub fn dirExists() void {} + +pub fn dirGetInfo() void {} diff --git a/src/rockbox/file.zig b/src/rockbox/file.zig new file mode 100644 index 00000000000..2478a8c684f --- /dev/null +++ b/src/rockbox/file.zig @@ -0,0 +1,51 @@ +pub fn openUtf8() void {} + +pub fn open() void {} + +pub fn create() void {} + +pub fn close() void {} + +pub fn read() void {} + +pub fn write() void {} + +pub fn remove() void {} + +pub fn rename() void {} + +pub fn ftruncate() void {} + +pub fn filesize() void {} + +pub fn fdprintf() void {} + +pub fn readLine() void {} + +pub fn settingsParseline() void {} + +pub fn storageSleep() void {} + +pub fn spin() void {} + +pub fn spindown() void {} + +pub fn registerStorageIdleFunc() void {} + +pub fn unregisterStorageIdleFunc() void {} + +pub fn reloadDirectory() void {} + +pub fn createNumberedFilename() void {} + +pub fn fileExists() void {} + +pub fn stripExtension() void {} + +pub fn crc32() void {} + +pub fn crc32r() void {} + +pub fn filetypeGetAttr() void {} + +pub fn filetypeGetPlugin() void {} diff --git a/src/rockbox/lcd.zig b/src/rockbox/lcd.zig new file mode 100644 index 00000000000..55528c410cb --- /dev/null +++ b/src/rockbox/lcd.zig @@ -0,0 +1 @@ +pub fn splash() void {} diff --git a/src/rockbox/metadata.zig b/src/rockbox/metadata.zig new file mode 100644 index 00000000000..3ab844d5c75 --- /dev/null +++ b/src/rockbox/metadata.zig @@ -0,0 +1,5 @@ +pub fn getMetadata() void {} + +pub fn getCodecString() void {} + +pub fn countMp3Frames() void {} diff --git a/src/rockbox/playback.zig b/src/rockbox/playback.zig new file mode 100644 index 00000000000..2980d2ff571 --- /dev/null +++ b/src/rockbox/playback.zig @@ -0,0 +1,55 @@ +const c = @cImport( + @cInclude("metadata.h"), +); + +extern fn audio_pause() void; +extern fn audio_play(elapsed: u64, offset: u64) void; +extern fn audio_resume() void; +extern fn audio_next() void; +extern fn audio_prev() void; +extern fn audio_ff_rewind(newtime: i64) void; +extern fn audio_next_track() *c.mp3entry; +extern fn audio_status() i32; +extern fn audio_current_track() *c.mp3entry; + +pub fn audioPlay(elapsed: u64, offset: u64) void { + audio_play(elapsed, offset); +} + +pub fn audioPause() void { + audio_pause(); +} + +pub fn audioResume() void { + audio_resume(); +} + +pub fn audioNext() void { + audio_next(); +} + +pub fn audioPrev() void { + audio_prev(); +} + +pub fn audioFfRewind(newtime: i64) void { + audio_ff_rewind(newtime); +} + +pub fn audioNextTrack() *c.mp3entry { + return audio_next_track(); +} + +pub fn audioStatus() i32 { + return audio_status(); +} + +pub fn audioCurrentTrack() *c.mp3entry { + return audio_current_track(); +} + +pub fn audioFlushAndReloadTracks() void {} + +pub fn audioGetFilePos() void {} + +pub fn audioHardStop() void {} diff --git a/src/rockbox/playlist.zig b/src/rockbox/playlist.zig new file mode 100644 index 00000000000..2df03dc0fa1 --- /dev/null +++ b/src/rockbox/playlist.zig @@ -0,0 +1,37 @@ +pub fn getCurrent() void {} + +pub fn getResumeInfo() void {} + +pub fn getTrackInfo() void {} + +pub fn getFirstIndex() void {} + +pub fn getDisplayIndex() void {} + +pub fn entriesIterate() void {} + +pub fn amount() void {} + +pub fn _resume() void {} + +pub fn resumeTrack() void {} + +pub fn setModified() void {} + +pub fn start() void {} + +pub fn sync() void {} + +pub fn removeAllTracks() void {} + +pub fn create() void {} + +pub fn insertTrack() void {} + +pub fn insertDirectory() void {} + +pub fn insertPlaylist() void {} + +pub fn shuffle() void {} + +pub fn warnOnPlErase() void {} diff --git a/src/rockbox/settings.zig b/src/rockbox/settings.zig new file mode 100644 index 00000000000..34d258eb44e --- /dev/null +++ b/src/rockbox/settings.zig @@ -0,0 +1,19 @@ +pub fn getSettingsList() void {} + +pub fn findSetting() void {} + +pub fn settingsSave() void {} + +pub fn optionScreen() void {} + +pub fn setOption() void {} + +pub fn setBoolOptions() void {} + +pub fn setInt() void {} + +pub fn setInEx() void {} + +pub fn setBool() void {} + +pub fn setColor() void {} diff --git a/src/rockbox/sound.zig b/src/rockbox/sound.zig new file mode 100644 index 00000000000..d5ae341ad65 --- /dev/null +++ b/src/rockbox/sound.zig @@ -0,0 +1,95 @@ +pub fn adjustVolume() void {} + +pub fn soundeSet() void {} + +pub fn soundCurrent() void {} + +pub fn soundDefault() void {} + +pub fn soundMin() void {} + +pub fn soundMax() void {} + +pub fn soundUnit() void {} + +pub fn soundVal2phys() void {} + +pub fn soundGetPitch() void {} + +pub fn soundSetPitch() void {} + +pub fn pcmApplySettings() void {} + +pub fn pcmPlayData() void {} + +pub fn pcmPlayStop() void {} + +pub fn pcmSetFrequency() void {} + +pub fn pcmIsPlaying() void {} + +pub fn pcmPlayLock() void {} + +pub fn pcmPlayUnlock() void {} + +pub fn beepPlay() void {} + +pub fn pcmInitRecording() void {} + +pub fn pcmCloseRecording() void {} + +pub fn pcmRecordData() void {} + +pub fn pcmStopRecording() void {} + +pub fn pcmCalculateRecPeaks() void {} + +pub fn audioSetRecordingGain() void {} + +pub fn audioSetOutputSource() void {} + +pub fn setInputSource() void {} + +pub fn dspGetTimestretch() void {} + +pub fn dspSetTimestretch() void {} + +pub fn dspTimestretchEnable() void {} + +pub fn dspTimestretchAvailable() void {} + +pub fn dspConfigure() void {} + +pub fn dspGetConfig() void {} + +pub fn dspProcess() void {} + +pub fn mixerChannelStatus() void {} + +pub fn mixerChannelGetBuffer() void {} + +pub fn mixerChannelCalculatePeaks() void {} + +pub fn mixerChannelPlayData() void {} + +pub fn mixerChannelPlayPause() void {} + +pub fn mixerChannelStop() void {} + +pub fn mixerChannelSetAmplitude() void {} + +pub fn mixerChannelGetBytesWaiting() void {} + +pub fn mixerChannelSetBufferHook() void {} + +pub fn mixerSetFrequency() void {} + +pub fn mixerGetFrequency() void {} + +pub fn pcmbufFade() void {} + +pub fn pcmbufSetLowLatency() void {} + +pub fn systemSoundPlay() void {} + +pub fn keyclickClick() void {} diff --git a/src/rockbox/system.zig b/src/rockbox/system.zig new file mode 100644 index 00000000000..b976312564a --- /dev/null +++ b/src/rockbox/system.zig @@ -0,0 +1,69 @@ +pub fn rbversion() void {} + +pub fn sleep() void {} + +pub fn yield() void {} + +pub fn defaultEventHandleer() void {} + +pub fn defaultEventHandleerEx() void {} + +pub fn createThread() void {} + +pub fn threadSelf() void {} + +pub fn threadExit() void {} + +pub fn threadWait() void {} + +pub fn threadThaw() void {} + +pub fn threadSetPriority() void {} + +pub fn mutexInit() void {} + +pub fn mutexLock() void {} + +pub fn semaphoreInit() void {} + +pub fn semaphoreWait() void {} + +pub fn semaphoreRelease() void {} + +pub fn commitDcache() void {} + +pub fn commitDiscardDcache() void {} + +pub fn commitDiscardIdcache() void {} + +pub fn timerRegister() void {} + +pub fn timerUnregister() void {} + +pub fn timerSetPeriod() void {} + +pub fn queueInit() void {} + +pub fn queueDelete() void {} + +pub fn queuePost() void {} + +pub fn queueWaitWtmo() void {} + +pub fn queueEnableQueueSend() void {} + +pub fn queueEmpty() void {} + +pub fn queueWait() void {} + +pub fn queueSend() void {} + +pub fn queueReply() void {} + +pub fn queueRemoveFromHead() void {} + +pub fn addEvent() void {} + +pub fn removeEvent() void {} + +pub fn sendEvent() void {} diff --git a/src/rockbox/tagcache.zig b/src/rockbox/tagcache.zig new file mode 100644 index 00000000000..5ee28d286f7 --- /dev/null +++ b/src/rockbox/tagcache.zig @@ -0,0 +1,25 @@ +pub fn search() void {} + +pub fn searchSetUniqbuf() void {} + +pub fn searchAddFilter() void {} + +pub fn getNext() void {} + +pub fn retrieve() void {} + +pub fn searchFinish() void {} + +pub fn getNumeric() void {} + +pub fn getStat() void {} + +pub fn commitFinalize() void {} + +pub fn isInRam() void {} + +pub fn fillTags() void {} + +pub fn tagtreeSubentriesDoAction() void {} + +pub fn searchAlbumartFiles() void {} diff --git a/src/root.zig b/src/root.zig index ecfeade1a3a..f3493680861 100644 --- a/src/root.zig +++ b/src/root.zig @@ -1,6 +1,18 @@ const std = @import("std"); const testing = std.testing; +pub const browse = @import("rockbox/browse.zig"); +pub const dir = @import("rockbox/dir.zig"); +pub const file = @import("rockbox/file.zig"); +pub const lcd = @import("rockbox/lcd.zig"); +pub const metadata = @import("rockbox/metadata.zig"); +pub const playback = @import("rockbox/playback.zig"); +pub const playlist = @import("rockbox/playlist.zig"); +pub const settings = @import("rockbox/settings.zig"); +pub const sound = @import("rockbox/sound.zig"); +pub const system = @import("rockbox/system.zig"); +pub const tagcache = @import("rockbox/tagcache.zig"); + export fn add(a: i32, b: i32) i32 { return a + b; }