-
Notifications
You must be signed in to change notification settings - Fork 0
Building From Source
- devkitARM + libctru (via devkitPro)
-
3gxtool 1.3 —
thepixellizeross-win/3gxtool(pacman package). Writes the3GX$0002container Luma3DS expects; the older3GX$0001tool is rejected by current Luma builds.
⚠️ Spaces in the path break the build. The devkitPro toolchain fails (make[1]: /d/My Project: Is a directory) if any parent folder name contains a space. Keep the project on a space-free path.
Build through the devkitPro msys2 shell (not git-bash, not a plain Windows terminal):
/c/devkitPro/msys2/usr/bin/bash.exe -lc 'cd <project-no-spaces> && make'The output is OcarinaCTRComposer.3gx (or whatever TARGET the Makefile sets).
Copy the built .3gx to the SD card, one plugin file per Title-ID folder:
sdmc:/luma/plugins/0004000000033500/OcarinaCTRComposer.3gx
0004000000033500 is the USA Title ID for Ocarina of Time 3D. Enable the plugin loader in
Rosalina (L + Down + SELECT → Plugin Loader → Enabled), launch the game, press SELECT.
These aren't build-system quirks — they're 3DS-plugin-specific traps that cost real debugging time if you hit them blind:
-
__service_ptr— the 3dsx crt0 declares this; a raw.3gxdoesn't get it automatically, sosrvGetServiceHandlefails to link without avoid *__service_ptr = NULL;somewhere in the plugin. -
ThreadVars on the worker thread — a thread made with a raw
svcCreateThreadhas no libctruThreadVarsblock, so the firstmalloc/printf/hid/fs callsvcBreaks in__syscall_getreent. Seed the thread-local storage manually at the very start of the thread function (magic0x21545624at TLS+0, reent pointer at TLS+8,fs_magic = 0at TLS+0x10) before any newlib/hid/fs call. Give the thread ≥16KB of stack. -
Never call
hidInit(). On New 3DS it internally callsirrstInit(), andir:rstconflicts with the running game — it freezes the game and locks the HOME button. Touch input uses a manualhid:USERshared-memory init instead (see the CTRComposer engine brief for the exact IPC calls). -
Font mapping — when mapping the shared system font via APT IPC, the
svcMapMemoryBlocktarget address argument must be0; passing the address APT returned fails silently (no error, just garbage/blank text). -
ZL/ZR are unreachable from a pure
.3gxon New 3DS — they live behindir:rst, which games without Circle Pad Pro support don't have in their exheader ACL, and a plugin can't patch the exheader. Use L/R combos for extra hotkeys instead.
For the full build brief (LCD registers, framebuffer format, the pause syscall, the whole reusable engine), see the game-agnostic CTRComposer repo.