Releases: samaBR85/CTRComposer
Release list
v1.1.4
Bug-fix release, and the last of a sweep. Everything here predates the v1.1.0 reorganisation —
these are engine bugs that shipped from the very first version.
Fixed: button waits that could hang the console 🔴
Four loops waited for a button to be released with no time limit:
while (HID_PAD) svcSleepThread(...); // info box, About
while (HID_PAD & BUTTON_SELECT) svcSleepThread(...); // menu, quick menuHID_PAD reads a raw hardware register. If it never comes back clear — a stuck pad, a shoulder
button resting against the case — the plugin spins forever with the game paused, which
presents as a dead console.
The engine already had the right helper, capped at ~2 seconds, and its comment even says "a
stuck pad can't hang". These four sites bypassed it. They now all use it.
Fixed: a translation could overflow the stack 🔴
T() resolves to a lang/<Name>.txt file on the SD card — text of a length the engine does not
control — and it was being written into fixed stack buffers with no bound. The worst case was
four translated strings concatenated into 96 bytes.
Fifteen calls now bound the write to the destination size. This mattered because the template
ships English-only and invites you to add translations; a long one would have corrupted the
stack and crashed somewhere unrelated, with nothing pointing back at the language file.
Fixed: {D-Pad} drew as literal text 🟢
The glyph tokeniser matches exactly {DP}. Nine places in the plugin write {DP}; the About
footer wrote {D-Pad}, so it rendered the braces as text while the bottom screen showed the
proper icon. Silent failure — no compiler warning, no runtime error, visible only on screen.
The same line was also the only footer string not wrapped in T(), so a translator could not
reach it. Both fixed, and the whole project was swept for other misspelled tokens — this was the
only one.
Warnings are on now
This project had never been compiled with -Wall -Wextra. Switching it on found the tree clean
apart from two deliberate cases, both now handled at the source, so the build is at zero
warnings. Leaving two permanent warnings visible would just train everyone to ignore them.
For anyone building on this engine
All four of these bugs — plus the frozen top screen fixed in v1.1.2 — are in every plugin that
inherited this engine, including forks that never took an update. CORRECOES-MOTOR.md in the repo
has each one with its symptom, cause, how to confirm it applies to your fork, the patch, and a
console test script.
Install
| File | Goes to |
|---|---|
default.3gx |
sd:/luma/plugins/default.3gx — the root, not a game folder |
CTRComposer-BlankTemplate.3gx |
sd:/luma/plugins/<TitleID>/ |
Luma3DS with the plugin loader enabled; press SELECT in game. Keep the 3D slider at zero.
The version on screen should read v1.1.4 — that is your proof the file on the card is this one.
Full Changelog: v1.1.2...v1.1.4
v1.1.2
Bug-fix release. If you are on v1.1.0 or earlier, take this one.
Fixed: the top screen froze when you left the plugin 🔴
Open a tool, leave it, and the top screen stayed stuck on the plugin's last frame — while the
bottom screen came back to the game and the game itself kept running. Reopening the menu layered
a new one over the frozen image, indefinitely. Easiest way to hit it: launch a tool from the
quick menu.
Cause. The overlay draws into the hidden framebuffer and then flips the LCD's
buffer-select register to show it:
REG32(LCD_TOP + LCD_SELECT) = sel ^ 1;Nothing ever put that register back. On the way out the LCD kept scanning our buffer, so the
top screen stayed frozen even though the game had resumed normally underneath.
That is also exactly why only the top screen was affected: the bottom screen draws straight into
the visible buffer, so restoring its pixels was enough. Only the top flips the register.
The plugin now records which buffer the game was showing when it takes the screen, and hands it
back before resuming.
Also fixed, same code path
- The quick menu got baked into the menu background. Coming from the quick menu, the engine
re-read the framebuffer microseconds after resuming the game — before the game had drawn
anything — and captured its own panel as "the game frame", then used it as the backdrop. The
menu ended up rendered on a photograph of itself. It now reuses the clean frame the quick menu
already saved. - Cursor parked on a section header. Launching a tool from the quick menu left the HOME
cursor on a non-selectable row. The folder shortcut already skipped separators; the tool
shortcut did not.
All three predate the v1.1.0 reorganisation — the logic is identical in v1.0.0. Reported and
confirmed fixed on hardware.
Clearer guide text
- The Plugin Guide now explains that leaving a tool with SELECT means the next SELECT drops
you back into it — that is what makes the Cheat Search loop work — and that B is how you
leave a tool for good. Nothing said this before, and it read as being stuck. - The RAM Dumper page said files go to "the plugin's own folder". The universal build has no
folder of its own; they land insd:/luma/plugins/dumps/.
Install
| File | Goes to |
|---|---|
default.3gx |
sd:/luma/plugins/default.3gx — the root, not a game folder |
CTRComposer-BlankTemplate.3gx |
sd:/luma/plugins/<TitleID>/ |
Luma3DS with the plugin loader enabled; press SELECT in game. Keep the 3D slider at zero.
Check the version on screen reads v1.1.2 — that is your proof the file on the card is this one.
Full Changelog: v1.1.0...v1.1.2
v1.1.0
Which file do I want?
default.3gx |
Memory tools in every game — Cheat Search, RAM Dumper, Hex Editor. Drop it at sd:/luma/plugins/default.3gx and press SELECT in any title. No code, no Title ID to look up. |
CTRComposer-BlankTemplate.3gx |
A demo of the template. The real product is the source — clone the repo, put your game's addresses in Sources/plugin/, and build your own plugin. |
Fixed: a crash on low memory 🔴
Startup allocated three buffers and only checked the first. If the second or third failed, the
plugin carried on and wrote 150 KB to a null pointer — an instant hang of the console, not a
graceful failure.
This only triggered under memory pressure, which is exactly what happens with a MemorySize: 2MiB
reservation. All three are now checked, and the menu simply refuses to open if any is missing —
the plugin goes inert instead of taking the game down with it.
Changed: the source is reorganised (this is why it's a minor bump)
Nothing about the running plugin changed — every refactoring step was verified byte-for-byte
identical. But if you build plugins from this template, the layout you work in is completely
different, and much better:
Sources/
main.c 250 lines — just the #include list (was 5,582)
plugin/ ← everything you edit, 8 files
engine/ ← the engine, 23 files, you inherit as-is
Before, making a plugin meant finding 7 scattered regions inside one 5,582-line file. Now it
is one folder: cheat ids, addresses, menu rows, icons, pickers, tracker data, guide text and
plugin identity each have their own named file.
This answers feedback from @biometrix76 (author of Gen6CTRPluginFramework) on the first
public plugin built with this engine — "foundational setup mashed into main.c", "hard to
navigate as a template". It was a fair hit, and the reorganisation is the answer.
Also in this release
- Guide text moved to where you edit it. The Plugin Guide pages and the guide credits page
were buried in the engine; they are content you're meant to rewrite, so they now live in
Sources/plugin/guide_text.inc.c. - One version number instead of two. The on-screen version and the compact menu tag are now
built fromPLUGIN_VER_MAJOR/MINOR/PATCHrather than typed separately — they can no longer
drift apart. - Comments trimmed. Development narrative removed; the real traps (the colour-macro ternary,
"never callhidInit()", "address 0 hangs the console") kept and sharpened. - README rewritten for the new structure, plus
MIGRACAO-PLUGINS-DERIVADOS.md— a migration
guide for plugins already built on the old layout. - Build tooling:
Tools/fingerprint.shcompares two builds by symbol name and size, so a
purely organisational change can be proven not to have altered the binary.
Install
Universal toolkit — sd:/luma/plugins/default.3gx
Loads into any title that has no plugin folder of its own. A per-game plugin always wins.
Template — sd:/luma/plugins/<TitleID>/CTRComposer-BlankTemplate.3gx
Ships with no game addresses; the example cheats write nothing until you enable them.
Luma3DS with the plugin loader enabled is required for both. Press SELECT in game.
Both artifacts are built by CI from this tag. Verified: the released
CTRComposer-BlankTemplate.3gxis byte-identical to a local build of the same commit.
Full Changelog: v1.0.0...v1.1.0
v1.0.0
Full Changelog: https://github.com/samaBR85/CTRComposer/commits/v1.0.0
Full Changelog: https://github.com/samaBR85/CTRComposer/commits/v1.0.0