diff --git a/docs/STEAM_FRAME_VR.md b/docs/STEAM_FRAME_VR.md index 82f373c..268e67b 100644 --- a/docs/STEAM_FRAME_VR.md +++ b/docs/STEAM_FRAME_VR.md @@ -43,14 +43,22 @@ that for logs. Start it from the Steam library to actually play. ## Game data -Copy the `valve` folder from your Steam copy of Half-Life to -`~/Documents/Lambda1VR/valve` on the headset. Inside Lepton that's -`/sdcard/Documents/Lambda1VR/valve`. Documents is the headset's own folder, so -it's still there after a Lepton reset. On the Quest it's `/sdcard/xash`, that -hasn't changed. +Install Half-Life from Steam on the Frame, and that's it. The Android container shows the headset's +Steam folders (read only), so the game uses the files where Steam put them, there's nothing to copy. At +start the app looks for `steamapps/common/Half-Life/valve/liblist.gam` in the Steam library (and in the +other libraries `libraryfolders.vdf` lists, like one on an SD card) and tells the engine to treat that folder +as read only (`-rodir`). The expansions (Opposing Force, Blue Shift) are in the same folder on Steam. -The app makes the folder on first start and puts its own files in it (config, -the weapon models and so on), like it does on the Quest. +`~/Documents/Lambda1VR` is the writable side, and it wins when the same file is in both. Inside Lepton it's +`/sdcard/Documents/Lambda1VR`, the headset's own folder, so it survives a Lepton reset. It holds your saves and +settings, and the files this app puts there on first start (the replacement weapon models, the sprites, the +loading screens), like it does on the Quest. The engine also makes empty folders there with the names of the +game folders in Steam's. On the Quest it's `/sdcard/xash`, that hasn't changed. + +If there's no Half-Life in Steam on the headset, it falls back to the old way: copy the `valve` folder from a +PC's Steam copy to `~/Documents/Lambda1VR/valve`. A copy there is used too when Steam has one as well (it's +found first, so a stale copy would be used over the Steam files). The log says which one it picked, with a +`[data]` line. ## Controls diff --git a/java/com/drbeef/lambda1vr/GLES3JNIActivity.java b/java/com/drbeef/lambda1vr/GLES3JNIActivity.java index cc136cf..c088815 100644 --- a/java/com/drbeef/lambda1vr/GLES3JNIActivity.java +++ b/java/com/drbeef/lambda1vr/GLES3JNIActivity.java @@ -151,6 +151,53 @@ import static android.system.Os.setenv; System.exit(0); } + /** + * The Frame's Android container shows the headset's Steam folders at the same paths, read only. If + * Half-Life is installed there, the game's files can be used from where they are instead of a copy. + * Looks in the Steam library folders (the main one, and the others libraryfolders.vdf lists, such as + * one on an SD card) for steamapps/common/Half-Life/valve/liblist.gam. Returns the Half-Life folder or null. + */ + private String findSteamHalfLife() + { + final String steam = "/home/steamos/.local/share/Steam"; + java.util.ArrayList libraries = new java.util.ArrayList(); + libraries.add(steam); + + try + { + BufferedReader br = new BufferedReader(new FileReader(steam + "/steamapps/libraryfolders.vdf")); + String line; + while ((line = br.readLine()) != null) + { + // "path" "/some/library" + line = line.trim(); + if (line.startsWith("\"path\"")) + { + String[] parts = line.split("\""); + if (parts.length >= 4 && !libraries.contains(parts[3])) + { + libraries.add(parts[3]); + } + } + } + br.close(); + } catch (IOException e) + { + Log.i(TAG, "[data] no libraryfolders.vdf: " + e.getMessage()); + } + + for (String library : libraries) + { + File liblist = new File(library + "/steamapps/common/Half-Life/valve/liblist.gam"); + if (liblist.canRead()) + { + return library + "/steamapps/common/Half-Life"; + } + Log.i(TAG, "[data] no Half-Life in the Steam library " + library); + } + return null; + } + public void create() { copy_asset(getFilesDir().getPath(), "extras.pak", false); @@ -509,6 +556,22 @@ import static android.system.Os.setenv; try { ApplicationInfo info = getApplicationInfo(); setenv("XASH3D_BASEDIR", DATA_DIR, true); + + if (BuildConfig.STEAM_FRAME) + { + // Half-Life from Steam, read only, in place. The folder above is searched after it, so what's + // in there (the saves, the settings, this app's own models and sprites) wins over Steam's files. + String steamHalfLife = findSteamHalfLife(); + if (steamHalfLife != null) + { + setenv("XASH3D_RODIR", steamHalfLife, true); + Log.i(TAG, "[data] game files: Steam, in place, read only (" + steamHalfLife + "); saves and settings in " + DATA_DIR); + } + else + { + Log.i(TAG, "[data] game files: no Steam install of Half-Life found, using the copy in " + DATA_DIR); + } + } setenv("XASH3D_GAMELIBDIR", info.nativeLibraryDir, true); setenv("XASH3D_GAMEDIR", "valve", true); setenv( "XASH3D_EXTRAS_PAK1", getFilesDir().getPath() + "/extras.pak", true );