emulators.azahar.Azahar
Nintendo 3DS via Azahar, driven by command line flags and config file patching.
Nintendo 3DS via Azahar, driven by command line flags and config file patching.
Azahar has no control API reachable from outside the process, so the
broker pins qt-config.ini before every launch (no close confirmation, no
update check, no Discord presence) and boots windowed with -w:
fullscreen Azahar stops rendering when the display resizes under it,
which happens whenever the player resizes their browser. Azahar installs
no SIGTERM handler, so the stop is a hard kill and the dump takes
whatever the game had already committed to disk.
There are no reachable save states: persistence is the game's own save data under the emulated SD card and NAND, and the archive is scoped to those save trees. At exit every file in the title save dirs written during the session gets its mtime refreshed so the delta dump ships those saves whole while other titles' saves stay filtered out. A resume slot is logged and ignored.
Attributes
attributename= 'azahar'Provider key, azahar.
attributedisplay_name= 'Azahar'Human-readable name.
attributesave_root= USER_DIRThe data root the save subtrees hang off.
attributesave_subtrees= (f'sdmc/Nintendo 3DS/{SYSTEM_ID}/{SDCARD_ID}/title', f'sdmc/Nintendo 3DS/{SYSTEM_ID}/{SDCARD_ID}/extdata', f'nand/data/{SYSTEM_ID}/extdata', f'nand/data/{SYSTEM_ID}/sysdata')The SD title and extdata trees plus the NAND extdata and sysdata trees.
attributerom_extensions= ROM_EXTENSIONSBootable formats, best first.
attributelog_path= AZAHAR_LOG_PATHThe emulator log file.
attributeterm_timeout= float(os.environ.get('AZAHAR_STOP_WAIT', '5'))SIGTERM grace before SIGKILL (env AZAHAR_STOP_WAIT, default 5).
attribute_session_start= 0.0Functions
func__init__(self) -> NoneInitialise the process handle and a zero session baseline.
paramselfReturns
Nonefuncprepare_restore(self) -> NoneStop a running Azahar so the archive can be extracted under it.
paramselfReturns
Nonefuncresolve_rom_file(self, path) -> Optional[Path]The file Azahar should boot for path.
paramselfparampathPathA ROM file, or a folder searched up to two levels deep.
Returns
typing.OptionalThe file itself, the best-ranked bootable file in the folder, or None.
funclaunch(self, rom_path, resume_slot) -> NonePatch qt-config.ini and boot the game windowed.
paramselfparamrom_pathPathThe file to boot.
paramresume_slotOptional[int]Ignored with a log line; there are no reachable save states.
Returns
Nonefunc_modified_title_saves(self) -> list[Path]Title save dirs holding a file written while the session ran.
paramselfReturns
listThe <titleHigh>/<titleLow> directories under every save group
funcsave_and_exit(self, slot) -> dict[str, Any]Stop Azahar and mark this session's title saves for the dump.
paramselfparamslotintIgnored; there are no save states.
Returns
dictstate_saved, state_slot and state_file, all None.