Bug Report
What's the issue you encountered?
When using ANSI escape sequences to position the cursor in wide console mode on the New 2DS XL (e.g. \x1b[5;20H), the row and col values appear to be interpreted in the wrong order. That is, text intended for row 5, column 20 appears at row 20, column 5 instead.
This breaks expected ANSI behavior, which uses the format ESC [ <row> ; <col> H.
After investigating the console.c implementation, it seems that the call to consolePosition() uses consolePosition(args[0], args[1]), which incorrectly assigns:
cursorX = row;
cursorY = col;
However, cursorX should be the column, and cursorY should be the row — this causes all cursor placement via ANSI codes to be reversed. Swapping the arguments to consolePosition(args[1], args[0]) fixes the issue and restores expected ANSI behavior.
This issue became visible after updating to libctru v2.6.1, which includes a fix for 1-based coordinates. It’s possible this update introduced the inversion accidentally by fixing the origin without verifying argument order.
No changes were made to devkitPro tooling manually; all packages were installed through the official pacman method.
How can the issue be reproduced?
- Start a basic libctru 3DS homebrew project (with wide mode enabled).
- Use
printf("\x1b[5;20HHello world\n");
- Observe where the text is printed — it appears at row 20, column 5, not the expected row 5, column 20.
- Swap the arguments in the escape sequence (
\x1b[20;5H) — now it renders correctly.
This indicates an argument reversal in the library code.
Environment?
- Host OS: Windows 10
- Shell used:
msys2.exe
- Toolchain: Official devkitARM (installed via
pacman)
- libctru version: v2.6.1
- Console mode:
gfxSetWide(true) enabled
- Target device: New 2DS XL running homebrew
Additional context?
- The function
consolePosition(x, y) in console.c expects x = column and y = row.
- ANSI escape sequences define cursor positions as
ESC [ <row> ; <col> H.
- Therefore,
consolePosition(args[0], args[1]) is incorrect — it swaps the intended cursor placement.
- ✅ Fix: change to
consolePosition(args[1], args[0]).
This would restore ANSI compatibility and expected console behavior.
Let me know if you'd like a pull request or patch demonstrating the change.
Bug Report
What's the issue you encountered?
When using ANSI escape sequences to position the cursor in wide console mode on the New 2DS XL (e.g.
\x1b[5;20H), therowandcolvalues appear to be interpreted in the wrong order. That is, text intended for row 5, column 20 appears at row 20, column 5 instead.This breaks expected ANSI behavior, which uses the format
ESC [ <row> ; <col> H.After investigating the
console.cimplementation, it seems that the call toconsolePosition()usesconsolePosition(args[0], args[1]), which incorrectly assigns:However,
cursorXshould be the column, andcursorYshould be the row — this causes all cursor placement via ANSI codes to be reversed. Swapping the arguments toconsolePosition(args[1], args[0])fixes the issue and restores expected ANSI behavior.This issue became visible after updating to libctru v2.6.1, which includes a fix for 1-based coordinates. It’s possible this update introduced the inversion accidentally by fixing the origin without verifying argument order.
No changes were made to devkitPro tooling manually; all packages were installed through the official
pacmanmethod.How can the issue be reproduced?
printf("\x1b[5;20HHello world\n");\x1b[20;5H) — now it renders correctly.This indicates an argument reversal in the library code.
Environment?
msys2.exepacman)gfxSetWide(true)enabledAdditional context?
consolePosition(x, y)inconsole.cexpectsx = columnandy = row.ESC [ <row> ; <col> H.consolePosition(args[0], args[1])is incorrect — it swaps the intended cursor placement.consolePosition(args[1], args[0]).This would restore ANSI compatibility and expected console behavior.
Let me know if you'd like a pull request or patch demonstrating the change.