#ifndef QUESTSHOCK_QS_CONFIG_H #define QUESTSHOCK_QS_CONFIG_H #include #ifdef __cplusplus extern "C" { #endif // Persistent, human-editable JSON config file - see CONFIG.md at the repo // root for the documented schema. Lives at a plain relative path // ("questshock.config.json") since the whole engine already runs with its // cwd chdir()'d to the user-facing /sdcard/questshock/ folder (see // QuestShockActivity.java's nativeChdir()) before main() ever runs - the // same way prefs.txt/keybinds.txt (Prefs.c) already do. // // Deliberately independent of prefs.txt: this file is never read or written // as a side effect of prefs.txt load/save, and vice versa. // Parses the config file if it exists (silent no-op if it doesn't - this // never creates the file itself) and applies every recognized option // directly into gShockPrefs/mode_id. Call once, early in main() - see // android/engine-patches/21-android-config.patch - after LoadPrefs() (so the // config file can override prefs.txt) and before init_all() (so there's no // live-vs-restart distinction to worry about: nothing is initialized yet, so // every field takes full effect as part of this same startup). void qs_config_load_startup(void); // Called from the "Save Configuration"/"Load Configuration" button JNI // handlers (questshock_native.c), which run on Android's UI thread. These // only enqueue a custom SDL event - the actual file I/O and any // gShockPrefs/mode_id/message_info() work happens on the engine's own SDL // main thread instead (see qs_config_handle_event() below), matching this // codebase's existing convention for crossing this exact thread boundary // (xr_session.c's xr_poll_events(), questshock_native.c's SDL_TEXTINPUT // push for keyboard input). void qs_config_request_save(void); void qs_config_request_load(void); // Same cross-thread-dispatch reasoning as qs_config_request_save()/_load() // above - called from the Video Options tab's controls (MenuOverlay.java), // which are just as much on Android's UI thread as the Save/Load buttons. // opengl=true/false selects "opengl"/"software"; resolution_index is 0-4, // indexing the same table qs_config_current_resolution_index() below // reads. Applies live immediately (no restart involved - see CONFIG.md); // unlike Load Configuration, these don't post a message_info() HUD // notification for every single tap - the tab's own selection highlight is // the feedback. void qs_config_request_set_renderer(bool opengl); void qs_config_request_set_resolution(int resolution_index); // Same cross-thread-dispatch reasoning as the two above - called from the // Main Menu tab's Language row (MenuOverlay.java). language_index is 0 // English/1 French/2 German (gShockPrefs.goLanguage's own numbering, // Prefs.h). Applies live immediately, the same way the game's own options // menu applies a language change (see qs_config.c's qs_apply_language()). void qs_config_request_set_language(int language_index); // Same cross-thread-dispatch reasoning as the three above - called from the // Main Menu tab's "Reset Position" button. A pure, live "return to a sane // view of the game quad" action (see xr_input.h's own // xr_input_recenter_player_to_screen(), which this dispatches to) - // unrelated to questshock.config.json despite living in this file for the // cross-thread dispatch machinery: it never reads or writes the config // file, and isn't a "reset to (0,0,0)" - it recenters based on the // player's current real head pose instead. void qs_config_request_reset_position(void); // Returns true and handles the event if it's one of the six custom events // qs_config_request_save()/_load()/_set_renderer()/_set_resolution()/ // _set_language()/_reset_position() enqueue - called from pump_events() // (sdl_events.c, see android/engine-patches/21-android-config.patch) on the // engine's own thread, once per polled event, before its normal switch on // well-known SDL_* event types. Returns false (no-op) for any other event // type, including before the six custom types have even been registered. bool qs_config_handle_event(const SDL_Event *event); // Read-only queries for the Video Options tab's own selection highlight // (MenuOverlay.java re-reads these whenever the tab is (re)shown, so it // reflects the live value even if it was last changed some other way, e.g. // the Ctrl+G hotkey or Load Configuration). Safe to call directly from // Android's UI thread despite not going through the event-queue dispatch // the mutating calls above use - same low-risk reasoning already used for // Save Configuration's own reads of gShockPrefs/mode_id: these are simple, // independent POD scalar reads, not a sequence that needs to be atomic // with anything else. bool qs_config_current_renderer_is_opengl(void); int qs_config_current_resolution_index(void); // gShockPrefs.goLanguage (0 English/1 French/2 German, Prefs.h) - read by // MenuOverlay.java's/KeyboardOverlay.java's periodic header-refresh timer // to pick which language's chrome text (Strings.java) to display, so a // language change made mid-session via the game's own options menu (or our // own Language row, or Load Configuration) is picked up without needing to // reopen either panel; also doubles as the Main Menu tab's Language row's // own selection highlight, same as qs_config_current_renderer_is_opengl()/ // qs_config_current_resolution_index() above. Same off-thread-scalar-read // reasoning as those two getters. int qs_config_current_language(void); #ifdef __cplusplus } #endif #endif // QUESTSHOCK_QS_CONFIG_H