GasInfinity/zitrus
Pure zig 3DS homebrew SDK
14ab564b8683d6e7498ea455e47bd0dd08e4eb76
d5868fe99fd7c659071f83e92fe2ba7846022f16
1b1fc477d2506d979ec38356f41a976693de3f2e
4353b20ef2ac750e35c6d68e4eb2a07c2d7cf901
master
3DS homebrew sdk written entirely in zig.
NOTE Not even the language this project is written in is 1.0
You acknowledge that any amount of breaking changes may occur until the first stable (minor) release, a.k.a
0.1.0
. No ETA is given.
zig fetch --save git+https://github.com/GasInfinity/zitrus
Then add this to your build.zig
:
const zitrus = @import("zitrus");
const zitrus_dep = b.dependency("zitrus", .{});
const zitrus_mod = zitrus_dep.module("zitrus");
// zitrus contains code useful for tooling outside of a 3DS environment.
// You must use the same target as `zitrus_mod`
const exe_mod = b.createModule(.{
.root_source_file = b.path("src/your_main.zig"),
.target = zitrus.horizon_arm11, // this is currently deprecated as we will now have 'arm-3ds' in zig: https://github.com/ziglang/zig/pull/24938
.optimize = optimize,
});
exe_mod.addImport("zitrus", zitrus_mod);
const exe = zitrus.addExecutable(b, .{
.name = "homebrew.elf",
.root_module = exe_mod,
});
// You can skip installing the elf but it is recommended to keep it for debugging purposes
b.installArtifact(exe);
const homebrew_smdh = zitrus.addMakeSmdh(b, .{
.name = "homebrew.icn",
.settings = b.path("path-to-smdh-settings.ziggy"), // look at any demo for a quick example or the schema in tools/make-smdh/settings.ziggy-schema
.icon = b.path("path-to-icon.png/jpg/..."), // supported formats depends on zigimg image decoding.
});
// XXX: Blocked by upstream, cache isn't caching.
// See `addMakeRomFs` if you need something patchable unlike `@embedFile`.
// This step will convert your executable to 3dsx (the defacto homebrew executable format) to execute it in an emulator or real 3DS
const final_3dsx = zitrus.addMake3dsx(b, .{ .name = "homebrew.3dsx", .exe = exe, .smdh = homebrew_smdh });
b.getInstallStep().dependOn(&b.addInstallBinFile(final_3dsx, "homebrew.3dsx").step);
In your root file, you must also add this, as there's no way to implicitly tell zig to evaluate/import it automagically:
pub const panic = zitrus.horizon.panic;
comptime {
_ = zitrus;
}
Currently there are multiple examples in the demo/
directory. To build them, you must have zig 0.15.1
in your path and run zig build
.
mango contains samples of how to use the mango graphics api.
panic is a simple example that panics when opened to test panics and traces.
info is a simple app that currently shows the console region and model (will be updated to show more info over time).
bitmap is a port of the bitmap example in libctru's 3ds-examples.
flappy is a simple fully functional flappy bird clone written entirely with software blitting.
gpu is a playground for mango, bleeding edge features are tested there. Not really an example per-se.
โ ๏ธ Feature regressed temporarily due to dependency or upstream (usually when zig updates this can happen)
โ Blocked due to upstream. Impossible to do until something gets fixed or added, usually listed in https://github.com/GasInfinity/zitrus/issues/1
๐ข Fully implemented ๐ก Partially implemented ๐ด Implementation not started/missing critical things
๐ High priority ๐ชซ Low priority
๐ข Smdh creation (tools/Smdh)
๐ข Elf -> 3dsx conversion (tools/3dsx)
๐ข PICA200 shader assembler/disassembler (tools/Pica):
๐ก NCCH (tools/Ncch):
๐ด Everything not listed here
๐ก๐ชซ Dumping, a.k.a: 3dsx/exefs --> bin/elf, smdh -> config + icons, etc...
Zitrus is currently very work in progress, it's able to run basic homebrew but lots of things are missing (services, io, etc...)
๐ข srv:
๐ข err:f
๐ก APT:S/A/U
๐ก hid:SPRV/USER
๐ข ir:rst
๐ก fs:USER/LDR
๐ก cfg:u/s/i
๐ข gsp::Gpu
๐ก๐ชซ gsp::Lcd
๐ก ns:s
๐ข ns:p/c
๐ก csnd:SND
๐ก๐ชซ pm:app
๐ข pm:dbg
๐ด All other services not listed here
error
swkbd
๐ด Tests
๐ก C API
๐ก Docs
๐ก Device HOS implementation.
๐ก Queues
CommandBuffer
submission)PresentationEngine
support)๐ก Memory / Buffers
๐ก Pipelines
๐ก CommandPool
CommandBuffer
recycling๐ก CommandBuffer's
๐ก Images / ImageViews
Image
layers๐ก Image Sampling
๐ข Synchronization primitives / driver thread.
๐ก Presentation engine.
๐ด๐ชซ Device HAL
abstraction.
๐ด๐ชซ Device baremetal implementation (prerequsite: HAL
abstraction).
I wanted to learn arm and always wanted to develop 3DS homebrew, also I searched and I haven't found any kind of zig package that doesn't use libctru, so I just started reading a lot and doing things. Furthermore, using only zig has a lot of advantages:
zig
executable, that's it! (However, obviously it is recommended that you use devkitPRO's tools as I'm sure you'll need them. You want to use gdb, don't you?)Debug
and ReleaseSafe
modes. Zitrus currently uses the ErrDisp
port to report panics and returned errors. The only missing thing is reporting return traces with debugging symbols (Currently only addresses are logged)build.zig
is really small and makefiles are really arcane)