This commit is contained in:
@@ -6,6 +6,17 @@ An open source project to play the classic 1994 System Shock on a VR
|
||||
headset, built on top of [Shockolate](https://github.com/Interrupt/systemshock),
|
||||
a cross-platform port of the original game.
|
||||
|
||||
The game is played on a virtual screen: the engine renders its usual flat 2D
|
||||
frame, and Questshock shows it as a large screen floating in front of you in
|
||||
VR. It is not a stereoscopic 3D conversion; you sit or stand in front of the
|
||||
screen the way you would in front of a monitor or a cinema screen. The
|
||||
screen's width and distance can be set separately for the menus/intro and for
|
||||
gameplay. Both controllers act as laser pointers for the game's mouse-driven
|
||||
interface and for a VR menu and on-screen keyboard, and every controller
|
||||
button, stick direction and game hotkey can be assigned to a game action.
|
||||
Questshock runs entirely on the headset (tested on a Meta Quest 2) as a
|
||||
sideloaded Android app, and needs your own copy of the game data.
|
||||
|
||||
## 1. Design principles
|
||||
|
||||
- **Standalone-headset-only.** The game must run entirely on the headset
|
||||
@@ -31,6 +42,10 @@ a cross-platform port of the original game.
|
||||
"3. Game assets" below); `res/assets/extract_assets.sh` extracts it into
|
||||
`ss_ee/`.
|
||||
- `res/run.sh` - the launcher script, copied into `dist/` on build.
|
||||
- `res/questshock.config.default.json` - the bundled default configuration
|
||||
(see [CONFIG.md](CONFIG.md)); `res/controller_profiles/` - the per-controller
|
||||
illustrations and labels shown in the Controller Options tab (see
|
||||
[CONFIG.md](CONFIG.md)). Both are copied into the APK.
|
||||
- `Makefile` - targets:
|
||||
- `all` (default) - alias for `dist`.
|
||||
- `build-image` - builds the Docker build-image (`./build-image.sh`).
|
||||
@@ -105,6 +120,10 @@ Enhanced Edition one and `extract_assets.sh` pulls them out of it too,
|
||||
entirely optionally - it still runs fine with just the Enhanced Edition
|
||||
installer.
|
||||
|
||||
The intro cutscene follows the selected language too, when the matching
|
||||
voice-over file (`svfrintr.res`/`svgeintr.res` under `res/data/`) is present;
|
||||
otherwise the English intro plays.
|
||||
|
||||
## 4. Desktop build
|
||||
|
||||
Builds and runs Questshock natively on the desktop (your dev machine, or
|
||||
@@ -218,18 +237,17 @@ driven by a laser-pointer-style aim ray from each hand
|
||||
interact with it, same as the game's own Bluetooth mouse/keyboard input
|
||||
otherwise works unchanged.
|
||||
|
||||
The menu launcher (`MenuOverlay.java` - just a "Keyboard" button so far)
|
||||
and the keyboard (`KeyboardOverlay.java`) are two fully independent quads,
|
||||
each its own `XrOverlay` instance (`android/app/src/main/cpp/xr_overlay.c`
|
||||
- a generic "off-screen Android View rendered into an OpenXR quad,
|
||||
hit-tested via a laser pointer" module shared by both, and by whatever
|
||||
similar panel comes next) with its own swapchain, visibility, and
|
||||
position, so they can be shown/hidden/moved independently - a design
|
||||
specifically meant to let the keyboard stay open while also picking
|
||||
something from the (still-to-be-built-out) menu. The controller's menu
|
||||
button only ever opens/closes the launcher; clicking its "Keyboard" button
|
||||
only opens the keyboard (never touching the launcher's own visibility) -
|
||||
the keyboard's own title bar holds the only way to close it again.
|
||||
The menu (`MenuOverlay.java`, described in "5.1.1. Menu, controls and
|
||||
cheats" below) and the keyboard (`KeyboardOverlay.java`) are two fully
|
||||
independent quads, each its own `XrOverlay` instance
|
||||
(`android/app/src/main/cpp/xr_overlay.c` - a generic "off-screen Android View
|
||||
rendered into an OpenXR quad, hit-tested via a laser pointer" module shared by
|
||||
both) with its own swapchain, visibility, and position, so they can be
|
||||
shown/hidden/moved independently - the keyboard can stay open while also
|
||||
picking something from the menu. The controller's menu button only ever
|
||||
opens/closes the menu; the menu's "Keyboard" button only opens the keyboard
|
||||
(never touching the menu's own visibility) - the keyboard's own title bar
|
||||
holds the only way to close it again.
|
||||
|
||||
The keyboard is a hand-built, full US-layout key grid (there's no system
|
||||
IME to borrow once immersive) that forwards each key press straight to the
|
||||
@@ -288,7 +306,50 @@ debugging enabled.)
|
||||
`/sdcard/questshock/` also holds an optional persistent settings file,
|
||||
`questshock.config.json`, loaded automatically at startup and saved/loaded
|
||||
from the in-headset menu - see [CONFIG.md](CONFIG.md) for the documented
|
||||
options.
|
||||
options. Every launch also refreshes `questshock.config.default.json` (the
|
||||
bundled defaults, used when there is no `questshock.config.json`) and
|
||||
`controller_profiles/` (controller illustrations for the Controller Options
|
||||
tab) there; your own saved config and any extra profiles you add are left
|
||||
alone.
|
||||
|
||||
#### 5.1.1. Menu, controls and cheats
|
||||
|
||||
The controller's menu button (left controller) opens and closes the menu. It
|
||||
can't be reassigned. Opening it pauses a running game; closing it resumes the
|
||||
game, unless it was already paused. Aim with either hand's ray and pull the
|
||||
trigger to press buttons. The menu has four tabs:
|
||||
|
||||
- **Main Menu** - Keyboard, Save/Load Configuration, Reset Position and the
|
||||
language.
|
||||
- **Video Options** - renderer, resolution, and the width and distance of the
|
||||
virtual screen for the initial screen (splash, intro, main menu) and the game
|
||||
screen.
|
||||
- **Controller Options** - shows the active controller with labelled inputs,
|
||||
and one button per action to assign it to a controller input (tap the
|
||||
button, then press the input). Assigning an input that another action
|
||||
already uses unbinds that other action. **Reset to Defaults** restores the
|
||||
default bindings.
|
||||
- **Cheats** - the engine's cheats as buttons (give all items and weapons,
|
||||
toggle physics, next and previous level) and four independent switches for
|
||||
unlimited health, energy, ammo and items. The switches last until the app
|
||||
restarts and are not saved. They only work while a game is running.
|
||||
|
||||
Default controls (all assignable, see [CONFIG.md](CONFIG.md)):
|
||||
|
||||
| Input | On foot | In cyberspace |
|
||||
|---|---|---|
|
||||
| Left stick | Move forward/back, strafe | Pitch up/down, bank left/right |
|
||||
| Right stick left/right | Turn | Roll |
|
||||
| Right stick up | Stand | Thrust |
|
||||
| Right stick down | Prone | - |
|
||||
| Left stick click | Jump | - |
|
||||
| Right stick click | Automap | - |
|
||||
| Right A / B | Click / double-click | Click / double-click |
|
||||
| Right trigger | Fire weapon | Fire weapon |
|
||||
| Left grip (hold) | Free view with the left stick | Free view with the left stick |
|
||||
|
||||
Every game hotkey (weapon select, MFD panels, save/load, ...) can also be
|
||||
assigned to a controller input; they are unbound by default.
|
||||
|
||||
### 5.2. Building natively in Android Studio
|
||||
|
||||
@@ -533,6 +594,23 @@ each one does:
|
||||
`qs_config_load_startup()` in `Shock.c`'s `main()`, right after
|
||||
`LoadPrefs()`, and one check in `sdl_events.c`'s `pump_events()` to drain
|
||||
the custom SDL events the menu's Save/Load Configuration buttons enqueue.
|
||||
- **`22-android-screen-profile.patch`** - `mainloop.c` reports every
|
||||
loop-mode change to `qs_screen_profile_notify_loop_mode()`, which picks
|
||||
between the initial-screen and game-screen virtual-screen presets (see
|
||||
[CONFIG.md](CONFIG.md)) and tells the menu whether a game is running.
|
||||
- **`23-android-intro-language.patch`** - `cutsloop.c` opens the intro
|
||||
cutscene file for the current language (`svgaintr.res`/`svfrintr.res`/
|
||||
`svgeintr.res`), falling back to English when it isn't installed.
|
||||
- **`24-android-cyberspace-query.patch`** - adds `qs_in_cyberspace()` to
|
||||
`mouselook.c`, which `xr_input.c` uses to switch between the on-foot and
|
||||
cyberspace controller actions.
|
||||
- **`25-android-cyberspace-analog-scale.patch`** - `movekeys.c` scales the
|
||||
cyberspace pitch and bank strength by `qs_cyber_pitch_scale`/
|
||||
`qs_cyber_bank_scale`, which `xr_input.c` sets from the thumbstick
|
||||
deflection each frame (1.0 for keys and buttons).
|
||||
- **`26-android-cheat-refill.patch`** - adds `qs_cheat_refill()` to
|
||||
`hkeyfunc.c`, which tops up health, energy, ammo and items (grenades and
|
||||
drugs the player already holds) for the Cheats tab's unlimited switches.
|
||||
|
||||
`android/gl4es-patches/`:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user