mirror of
https://github.com/DramaticShape/DramaticShapeVoxelMod.git
synced 2026-08-12 08:01:09 +02:00
fixed dll paths for vr
This commit is contained in:
@@ -4,6 +4,16 @@
|
||||
|
||||
### Added
|
||||
|
||||
- **VR works from an installed release.** The OpenXR loader used to be
|
||||
looked for only against the working directory and the game's source --
|
||||
right for the dev tree, wrong for a release install, where importing
|
||||
the mod lands it in the game's SAVE DIRECTORY (or keeps it zipped) and
|
||||
the VR row silently failed to start. The search now also asks the
|
||||
mount that actually holds the mod and the save directory itself; and
|
||||
if nothing on disk answers -- the mod imported as an archive -- the
|
||||
DLL is copied once out of the mod into the save directory and loaded
|
||||
from there, so every install shape reaches the headset.
|
||||
|
||||
- **SELECT walks the VOXEL ladder.** In free roam, the pad's SELECT
|
||||
button makes exactly the step hotkey 3 makes -- OFF through the angle
|
||||
rungs to 1ST and round, stepping over FULL, clearing TILT and GBC FX
|
||||
|
||||
@@ -44,4 +44,24 @@ alongside.
|
||||
| right stick left / right | *1ST only* — snap-turn 45° |
|
||||
| grip squeeze + raise / lower that hand | *diorama only* — drag the table's height |
|
||||
| head | *1ST and battles* — look; FreeMove walks where you look |
|
||||
| left hand | *1ST and battles* — the Pokédex: menus, dialogs and the 2D battle screen on its screen |
|
||||
| left hand | *1ST and battles* — the Pokédex: menus, dialogs and the 2D battle screen on its screen |
|
||||
|
||||
## Licenses
|
||||
|
||||
This mod redistributes one third-party binary:
|
||||
|
||||
- **`assets/vr/openxr_loader.dll`** — the Khronos OpenXR loader
|
||||
(version 1.0.10.2, x64, unmodified), © The Khronos Group Inc.,
|
||||
licensed under the **Apache License 2.0**. The full license text ships
|
||||
alongside the DLL at
|
||||
[`assets/vr/LICENSE-openxr_loader.txt`](assets/vr/LICENSE-openxr_loader.txt),
|
||||
as the license requires; keep the two files together if you
|
||||
redistribute this mod. Source:
|
||||
[KhronosGroup/OpenXR-SDK](https://github.com/KhronosGroup/OpenXR-SDK).
|
||||
|
||||
Everything else in this mod is original to it, except that the voxel
|
||||
geometry and shape profiles are derived from the tile and sprite data of
|
||||
the original game, as documented by the
|
||||
[pret/pokered](https://github.com/pret/pokered) disassembly. No ROM
|
||||
data, artwork or audio is included; the mod reads the assets the host
|
||||
game already has.
|
||||
+53
-6
@@ -361,18 +361,58 @@ local function check(r, what)
|
||||
end
|
||||
|
||||
-- Where the loader DLL might really be on disk. mod.path is
|
||||
-- PHYSFS-relative; ffi.load needs an OS path, so try it against the
|
||||
-- process's working directory and against the game's source directory.
|
||||
-- PHYSFS-relative; ffi.load needs an OS path. The dev tree answers to
|
||||
-- the working directory or the source directory -- but an INSTALLED
|
||||
-- release is neither: importing a mod there lands it in the game's SAVE
|
||||
-- DIRECTORY, so the mount that actually holds the mod
|
||||
-- (getRealDirectory) and the save directory itself are both tried too.
|
||||
local DLL_REL = "assets/vr/openxr_loader.dll"
|
||||
|
||||
local function loaderCandidates()
|
||||
local rel = (V.path or "mods/DramaticShapeVoxelMod")
|
||||
.. "/assets/vr/openxr_loader.dll"
|
||||
local rel = (V.path or "mods/DramaticShapeVoxelMod") .. "/" .. DLL_REL
|
||||
local list = { rel }
|
||||
local okR, real = pcall(function()
|
||||
return love.filesystem.getRealDirectory(rel)
|
||||
end)
|
||||
if okR and type(real) == "string" then
|
||||
list[#list + 1] = real .. "/" .. rel
|
||||
end
|
||||
local ok, src = pcall(function() return love.filesystem.getSource() end)
|
||||
if ok and type(src) == "string" then list[#list + 1] = src .. "/" .. rel end
|
||||
local okS, save = pcall(function()
|
||||
return love.filesystem.getSaveDirectory()
|
||||
end)
|
||||
if okS and type(save) == "string" then list[#list + 1] = save .. "/" .. rel end
|
||||
list[#list + 1] = "openxr_loader" -- last resort: the system search path
|
||||
return list
|
||||
end
|
||||
|
||||
VRXR._loaderCandidates = loaderCandidates -- named for the suite
|
||||
|
||||
-- The escape hatch for a mod imported as an ARCHIVE (or mounted anywhere
|
||||
-- else ffi.load cannot see): copy the DLL out of the mount into the save
|
||||
-- directory -- a real folder on every platform -- and load it from
|
||||
-- there. Written once and reused; rewritten only if the size changed (a
|
||||
-- mod update shipping a new loader).
|
||||
local EXTRACTED = "dramatic_shape_openxr_loader.dll"
|
||||
|
||||
local function extractLoader()
|
||||
local okB, bytes = pcall(function()
|
||||
return V.mod and V.mod.read and V.mod:read(DLL_REL)
|
||||
end)
|
||||
if not (okB and type(bytes) == "string" and #bytes > 0) then return nil end
|
||||
local ok, path = pcall(function()
|
||||
local have = love.filesystem.getInfo and love.filesystem.getInfo(EXTRACTED)
|
||||
if not (have and have.size == #bytes) then
|
||||
if not love.filesystem.write(EXTRACTED, bytes) then return nil end
|
||||
end
|
||||
local save = love.filesystem.getSaveDirectory()
|
||||
if type(save) ~= "string" then return nil end
|
||||
return save .. "/" .. EXTRACTED
|
||||
end)
|
||||
return ok and path or nil
|
||||
end
|
||||
|
||||
local function loadLoader()
|
||||
ffi = require("ffi")
|
||||
pcall(ffi.cdef, CDEF)
|
||||
@@ -383,8 +423,15 @@ local function loadLoader()
|
||||
if ok then return lib end
|
||||
errs[#errs + 1] = tostring(lib)
|
||||
end
|
||||
error("openxr_loader.dll not loadable (is the mod running from a real "
|
||||
.. "folder, not an archive?): " .. table.concat(errs, " | "), 0)
|
||||
-- nothing loadable in place: extract a copy to the save directory
|
||||
local extracted = extractLoader()
|
||||
if extracted then
|
||||
local ok, lib = pcall(ffi.load, extracted)
|
||||
if ok then return lib end
|
||||
errs[#errs + 1] = tostring(lib)
|
||||
end
|
||||
error("openxr_loader.dll not loadable from the mod, the save directory "
|
||||
.. "or the system: " .. table.concat(errs, " | "), 0)
|
||||
end
|
||||
|
||||
local function makeSwapchain(w, h, format)
|
||||
|
||||
@@ -47,7 +47,7 @@ return {
|
||||
"1ST needs the 3D pass like every rung; without it the level still persists but the world stays 2D and the grid walk stays in charge",
|
||||
"in 1ST, scripted walks, ledge hops and spinner slides play out as the grid moves they are, with the camera riding along; free control resumes when they land",
|
||||
"rooms have no ceilings, so a first-person look over an interior wall shows the void the diorama always had behind it",
|
||||
"VR is Windows x64 only (the shipped loader and the Win32 GL binding): on any other platform -- mobile above all -- the VR row is absent from the OPTIONS menu and the manager's page both, and a stored vr=true carried over in a save is ignored. On Windows it renders the scene once per eye (heavy with WATER FULL or AA up) and cannot start from a mounted .love archive -- the FFI needs the loader DLL on a real disk path; pad/keyboard/mouse keep working alongside the XR controllers",
|
||||
"VR is Windows x64 only (the shipped loader and the Win32 GL binding): on any other platform -- mobile above all -- the VR row is absent from the OPTIONS menu and the manager's page both, and a stored vr=true carried over in a save is ignored. On Windows it renders the scene once per eye (heavy with WATER FULL or AA up); pad/keyboard/mouse keep working alongside the XR controllers. The loader DLL is found wherever the mod was put -- the dev tree, an installed release's save directory, or an imported archive, from which it is copied once into the save directory so the FFI has a real disk path",
|
||||
"VR on and off are both the VR row's job (options menu or manager); no controller button does either",
|
||||
"the Pokedex needs a TRACKED left controller; without one there is no device in hand and the floating panel carries the UI as before",
|
||||
"while the VR row is ON, 3D-BTL is held ON and BACK SPRITES held OFF (the headset's battle staging assumes both), and both rows leave the OPTIONS menu until VR goes off -- their stored values come back with them",
|
||||
|
||||
@@ -3998,6 +3998,17 @@ T.eq(type(VRMod.supported), "function",
|
||||
"the platform gate exists -- off Windows the row is not offered at all")
|
||||
T.eq(VRMod.supported(), true,
|
||||
"and a headless run (no love.system) counts as supported, harmlessly")
|
||||
|
||||
-- the loader search covers every install shape: the mod-relative path
|
||||
-- first, the system name last, and (with a filesystem to ask) the real
|
||||
-- mount and the save directory in between
|
||||
local VRXR_ = run.loader.exports.DRAMATIC_SHAPE.lib.require("VRXR")
|
||||
local cands = VRXR_._loaderCandidates()
|
||||
T.check(#cands >= 2, "the loader has candidates to try")
|
||||
T.check(cands[1]:find("assets/vr/openxr_loader%.dll") ~= nil,
|
||||
"the first is the mod's own path")
|
||||
T.eq(cands[#cands], "openxr_loader",
|
||||
"and the system search path is the last resort")
|
||||
T.eq(type(VRMod.leave), "function",
|
||||
"VR.leave stays as the programmatic door out -- no controller button "
|
||||
.. "is wired to it")
|
||||
|
||||
Reference in New Issue
Block a user