Open-source project
EstebanPdN/zelda-alttp-3ds avatar
EstebanPdN/zelda-alttp-3ds

Zelda A Link to the Past 3DS Port: A Dual-Screen Port of the zelda3 Engine

Nintendo 3DS dual-screen port of Zelda A Link to the Past based on zelda3

687 stars13 forksCLicense varies

At a glance

What is it?
EstebanPdN/zelda-alttp-3ds repackages the reverse-engineered zelda3 engine for the Nintendo 3DS, putting gameplay on the top screen and a touch map on the bottom. Here is how it installs, what it refuses to ship, and where it breaks.
Who is it for?
This port is for people who already own a USA, unheadered A Link to the Past ROM, run Luma3DS, and want the game on 3DS hardware with a live bottom-screen map. It is not for anyone without a legally obtained ROM, nor for players expecting gameplay hacks or translation patches to work reliably, since the README says hacks are not guaranteed compatible.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the 3DS Port Adds to the zelda3 Engine

The upstream zelda3 project is a reverse-engineered reimplementation of the A Link to the Past engine, and this repository is a Nintendo 3DS port of it. The README credits the original zelda3 engine, the Android port by Waterdish, and a dual-screen Android branch by samyost1 as the source base, and says the port was built with help from Codex. The audience is narrow and specific: someone with a modded 3DS, a legally obtained USA, unheadered ROM, and enough patience to place files on an SD card by hand.

The value is the second screen. The top screen renders gameplay at 400x240, while the bottom 320x240 screen carries a live map, dungeon map, gear view, item selection and touch settings. On the original hardware that information lived behind a pause menu or a button press. Here it is always visible, which changes how the game is played rather than how it looks. A 400x240 WIDE mode exists as well, with fixed-camera edge corrections, so the field of view can be widened beyond the original framing. Display modes also include stretched original and original aspect.

The repository ships source code, build scripts, redistributable port assets and patch/extraction logic. It does not ship a ROM, extracted game assets, or zelda3_assets.dat. That is the central design constraint: the user supplies the cartridge data, and the port extracts what it needs on the console itself.

How the Top and Bottom Screens Are Driven

The README describes PICA200/Citro2D presentation for both screens with nearest-neighbor sampling and RGB565 display output. On Old 3DS, rendering goes through the PICA200 GPU with an automatic software fallback for unsupported effects. New 3DS keeps its existing CPU renderer instead. That split matters: the two hardware revisions do not take the same rendering path, so a bug on one is not automatically a bug on the other.

Gameplay timing is a fixed-step 60 Hz loop with bounded catch-up, which the README frames as a deliberate choice against letting game speed depend on when a VBlank wait returns. PPU scanline rendering is parallelized across Core 0 and Core 1, plus Core 2 on New 3DS, with persistent tile-row caches. In practice this means the port does work per scanline across cores rather than treating the frame as one serial job.

Assets are extracted on first launch. The ROM is read locally and is never copied into the CIA, and zelda3_assets.dat is produced on the console from the user's ROM. If you use a translated or patched ROM, the README says to place both the clean USA ROM and the patched ROM in the same directory, so the port can take original assets from the clean file and translated text from the patched one. Turbo speed is selectable at off, x2, x3, x4 or x5, and on New 3DS the ZL button or C-stick can hold turbo while it is enabled.

Installing the CIA and Getting Past First Launch

Releases include an installable CIA, a Homebrew Launcher 3DSX, and a QR code for scanning the CIA URL from FBI on the console. Install the CIA first, then create the directory the README specifies on the SD card:

text
sdmc:/3ds/Zelda 3DS/

Place a legally obtained USA, unheadered ROM in that directory. The preferred filename is zelda3.sfc, but other .sfc or .smc filenames are accepted. If you use a translated or patched ROM, put both the clean USA ROM and the patched ROM in the same folder.

Audio needs a DSP firmware dump in a separate location. Luma3DS can produce it through Rosalina's Dump DSP firmware command:

text
sdmc:/3ds/dspfirm.cdc

On first launch, press A to validate the ROM and extract the assets. The README states that the ROM is read locally and never copied into the CIA, so the extraction happens on the console. Expect a wait on that first run; subsequent launches reuse the extracted data. If the ROM fails validation, the likely causes are a headered file or a non-USA region, neither of which the README says is supported.

Building from source is a separate path. It requires devkitARM, libctru and 3ds-cmake under DEVKITPRO, plus makerom and bannertool for CIA packaging and the vendored SDL2 source in app/jni/SDL2. The banner.cgfx file is prebuilt in platform/3ds/assets. The build command is short:

sh
chmod +x platform/3ds/build.sh
platform/3ds/build.sh

The script places the 3DSX and CIA under build-3ds/game/. Note that the README's Releases section still links v3.0 as the latest release even though v3.1 and v3.2-E2 exist, so read the release list rather than that line.

Diagnostic Dumps and the Update Channel

Support runs through a single mechanism. Pressing L + R + A creates a dump containing memory files, physical 400x240 and 320x240 screen captures, raw display framebuffers, and a validated load-state.bin checkpoint. Audio pauses during capture, and a DUMP SAVED notice on the top screen confirms success. Dumps land in sdmc:/3ds/Zelda 3DS/dumps/, and the README's bug-report instructions are to press the combination while the issue is visible and attach the result. That is a better support story than most homebrew ports offer, and it is also the only one documented: there is no issue template described beyond attaching the dump.

Updates are handled in-game under Settings > Update, where you choose the Stable or Pre-release channel. Tapping a release name shows its changelog on the top screen with Prev/Next paging, and Download Update installs it. The README says to save in-game before installing and to reopen the game afterward. Startup checks also flag newer releases. If touch controls are broken badly enough that you cannot reach Update, the documented workaround is the FBI QR code from the release page.

The version history is worth reading before you pick a channel. v3.2-E2 is an experimental pre-release that fixes Restart retaining stale game RAM after ROM reselection, a bug that could leave gameplay black and silent. v3.1 remains the stable release, and it changed touch detection to use the native HID contact flag, including startup and releases with residual coordinates, while keeping physical coordinates protected from SDL viewport transforms. The last 32 touch selections are recorded in diagnostic dumps. If you value predictability over the newest fix, v3.1 is the documented stable choice.

Where This Port Is the Wrong Tool

The ROM requirement is not a formality. No ROM or extracted asset package is distributed here, and zelda3_assets.dat is not included. Without a legally obtained USA, unheadered ROM, the software has nothing to run. A headered or non-USA dump is outside what the README describes.

Gameplay hacks are the second boundary. The README states that translation patches may work through the two-ROM arrangement, but gameplay hacks are not guaranteed to be compatible. Randomizers and difficulty mods that alter game logic are therefore a gamble, not a supported configuration. If your interest in A Link to the Past is a randomizer run, this port is not the tool to reach for.

Hardware revision is the third. Old 3DS uses PICA200 GPU rendering with automatic software fallback for unsupported effects, while New 3DS uses its existing CPU renderer. The README does not document what the fallback costs in visual fidelity or frame time, and it does not provide a comparison between the two paths. Anyone on an Old 3DS should treat the fallback as an unknown rather than assume parity with New 3DS. The absence of a documented performance baseline is a real gap in the project's own notes.

Finally, the licence is unstated in the repository metadata. The README has a Legal section covering ROMs and assets, but nothing here identifies the licence terms for the port's own code. That is a question to resolve before redistributing anything built from this tree.

How It Differs from the Android Dual-Screen Branch

The closest alternative is the dual-screen Android branch by samyost1 that this port uses as its source base. Both descend from the same zelda3 engine and both put a map on a second display, so the difference is not in the game logic. It is in the platform layer. The Android branch targets phones and tablets with touch input and the graphics stack those devices provide. This port replaces that layer with Citro2D presentation, PICA200 or CPU rendering depending on the model, fixed-step 60 Hz timing, and scanline work spread across the 3DS cores.

The practical consequence is that the Android branch runs on hardware you already carry, while this one runs on a 3DS with its physical buttons, its two fixed screens, and its own constraints. Turbo on this port is bound to ZL or the C-stick on New 3DS, which has no equivalent on a phone. Conversely, the Android branch is not limited to a USA, unheadered ROM in the same documented way, because the platform and packaging assumptions differ. Choosing between them is choosing hardware, not features.

A second reference point is the upstream zelda3 project itself, which targets desktop platforms and has no second screen to fill. If you want the game on a monitor with a keyboard, the upstream engine is the direct route. The 3DS port exists for the case where the hardware is the point.

Maintenance and Upgrade Cost

The repository is not archived, and the last push was on 2026-09-13, the same day v3.2-E2 was tagged. Three releases landed within four days: v3.0 on 2026-09-10, v3.1 on 2026-09-11, and v3.2-E2 on 2026-09-13. That cadence means the in-game updater is not decorative; a Stable-channel user will see new builds regularly, and the Pre-release channel moves faster still.

The upgrade cost is low on the surface and slightly higher underneath. Installing an update requires saving in-game first, then reopening the game afterward, and the README warns about this explicitly. The v3.2-E2 notes describe a Restart bug that retained stale game RAM after ROM reselection and could leave gameplay black and silent, which is exactly the class of problem that makes an experimental channel risky for a playthrough you care about. Running the Pre-release channel means accepting that kind of regression in exchange for earlier fixes.

There is no documented rollback procedure. The README does not describe how to return to an earlier version after installing a newer one, and it does not say whether saves remain compatible across versions, only that Restart preserves existing saves. If you install v3.2-E2 and it misbehaves, the path back is not written down. Keep the CIA you are replacing.

On licensing, the Legal section is explicit that the repository contains only source code, build scripts, redistributable port assets and patch/extraction logic, and that users are responsible for their own ROM. Nothing in the repository states the licence for the port's own source, so treat redistribution of builds as unresolved until you confirm the terms yourself.

Editorial conclusion

This port is for people who already own a USA, unheadered A Link to the Past ROM, run Luma3DS, and want the game on 3DS hardware with a live bottom-screen map. It is not for anyone without a legally obtained ROM, nor for players expecting gameplay hacks or translation patches to work reliably, since the README says hacks are not guaranteed compatible. Before installing, verify that dspfirm.cdc exists at sdmc:/3ds/dspfirm.cdc, that the ROM is unheadered, and that you can dump a diagnostic with L + R + A, because that dump is the only bug-report channel the project documents.

Frequently asked questions

Is there a Zelda game available for the 3DS?

This project is a Nintendo 3DS dual-screen port of the zelda3 engine, which is a reverse-engineered reimplementation of A Link to the Past. It installs as a CIA and requires the user to supply their own legally obtained USA, unheadered ROM.

Is Zelda A Link to the Past hard?

The repository does not discuss difficulty. What it does document is that turbo speed can be set to off, x2, x3, x4 or x5, and that on New 3DS the ZL button or C-stick can hold turbo while it is enabled.

How much is a Zelda edition 3DS worth?

The repository contains no pricing information. It covers installing the CIA, placing a USA, unheadered ROM at sdmc:/3ds/Zelda 3DS/, and providing sdmc:/3ds/dspfirm.cdc for audio.

What is the rarest 3DS game?

The repository does not address game rarity or collecting. Its scope is a dual-screen 3DS port of the zelda3 engine, distributed as source code, build scripts and redistributable port assets without a ROM or extracted game assets.

Official sources

  1. EstebanPdN/zelda-alttp-3ds on GitHub
  2. Issues
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/estebanpdn-zelda-alttp-3ds.svg)](https://hysenlabs.com/projects/estebanpdn-zelda-alttp-3ds)