Files
NX2navi/runtime/fs.h
chrg6 df2fbe4640 Play the game's own interface sounds in the settings menu.
Opening and closing the menu, moving the cursor, changing a value, pressing an item, cancelling a dialog and changing tabs play the game's system sounds (Plus menu open and close, cursor, decide, cancel, tab move), read from the user's RomFS at the first use and decoded from BWAV (DSP-ADPCM or PCM16, 48 kHz) in runtime/menu_sound.c. They are mixed over the game's output in the audio callback with up to eight voices started without locks. The Sound tab gets a Menu sounds volume (menu_sound_volume, 0 to 100, default 80, under the output volume). A RomFS without the files stays silent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:40 -05:00

64 lines
4.2 KiB
C

// Contains code Copyright (c) 2026 MacNativeGames contributors (MIT; see THIRD_PARTY_NOTICES.md).
// The nn::fs host layer: the read-only RomFS (romfs.c) and writable save, temporary and
// cache storage under the profile directory (fs_host.c). Both register their nn::fs overrides with HOST_OVERRIDE;
// this header is what the two files and the probe share.
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <wchar.h>
// ---- nn::fs results
#define FS_R_PATH_NOT_FOUND 0x202u
#define FS_R_ALREADY_EXISTS 0x402u
#define FS_R_NOT_EMPTY 0x1002u
#define FS_R_UNSUPPORTED_OPEN 0x6402u // RomFS: any open mode but read
#define FS_R_INVALID 0xe402u // RomFS: bad handle, offset or argument
#define FS_R_TARGET_NOT_FOUND 0x7d402u
#define FS_R_INVALID_ARGUMENT 0x2ee202u
#define FS_R_INVALID_PATH 0x2ee602u
#define FS_R_OPEN_MODE 0x307402u
#define FS_R_APPEND_REQUIRED 0x2f5e02u
enum { FS_OPEN_READ = 1, FS_OPEN_WRITE = 2, FS_OPEN_APPEND = 4 }; // nn::fs::OpenMode
enum { FS_ENTRY_DIRECTORY = 0, FS_ENTRY_FILE = 1 }; // nn::fs::DirectoryEntryType
// ---- romfs.c
// Handles 0x1_0000_0000 + j; host storage uses 0x2_0000_0000 + j (files) and 0x3_0000_0000 + j (directories).
#define ROMFS_HANDLE_BASE 0x100000000ull
int romfs_owns(const char *path); // path is on the mounted RomFS ("<mount>:...")
int romfs_handle(uint64_t h); // h is a RomFS file handle
uint32_t romfs_mount(const char *name); // nn::fs::MountRom; a second name is fatal
uint32_t romfs_open(uint64_t *out, const char *path, int mode);
uint32_t romfs_read(uint64_t *out, uint64_t h, int64_t offset, void *buffer, uint64_t size);
uint32_t romfs_size(int64_t *out, uint64_t h);
void romfs_close(uint64_t h);
uint8_t *romfs_load(const char *rel, uint64_t *size_out); // whole file by RomFS-relative path, malloc'd (or NULL)
uint32_t romfs_entry_type(int *out, const char *path);
// The children of RomFS directory path: fn(name, is_dir, size, ctx) once per file and once per subdirectory, in
// index order; fn returns 0 to stop. FS_R_PATH_NOT_FOUND when path is not a directory.
uint32_t romfs_list(const char *path, int (*fn)(const char *name, int is_dir, uint64_t size, void *ctx), void *ctx);
uint64_t romfs_file_count(void); // files in the index (fs_init first)
const char *romfs_entry(uint64_t i, uint64_t *offset, uint64_t *size); // path, image offset and size of index row i
const char *romfs_image_path(void); // the romfs.bin path fs_init opened
size_t romfs_overlay_count(void);
int romfs_patches_loaded(void); // a romfs-patches manifest gave at least one file
// The button prompts (input_prompts_folder): the folder loaded at start, NULL for the game's own prompts; whether a
// folder had a manifest at start; and why the folder the settings asked for at start was not loaded (ROMFS_PROMPTS_OK
// for any other folder: it was not asked for). romfs-patches-pc goes by that name also where romfs-patches-pc-<w>x<h>
// stands in for it (romfs.c overlay_init).
enum { ROMFS_PROMPTS_OK, ROMFS_PROMPTS_MISSING, ROMFS_PROMPTS_FAILED, ROMFS_PROMPTS_SHAPE, ROMFS_PROMPTS_MODS,
ROMFS_PROMPTS_PATCHES };
const char *romfs_prompts(void);
int romfs_prompts_ready(const char *folder);
int romfs_prompts_off(const char *folder);
const char *romfs_overlay(size_t k, const char **file, uint64_t *size, int *is_added); // RomFS path of overlay k
void fs_trace(const char *what, const char *path); // NX2NAVI_TRACE=fs: one line per open
// ---- fs_host.c
void fs_host_set_profile(const char *dir); // profile directory; before the first storage mount only
// (default rt_config()->profile)
int fs_save_busy(void); // a save is being written: a save file open for writing,
// or save data changed in the last 3 s and not committed
void fs_save_flush(void); // wait for a save Commit still running in the background;
// every exit path calls it before the process ends