Replace fetched overlay helper with project OpenVR EGL implementation

This commit is contained in:
L8OLOOE committed 2026-10-15 13:41:25 +02:00
1 parent b9f2bb5a22
commit 4d74625d20
21 files changed
+386 -106

No files matched your search

+1 -1
View File
@@ -3,7 +3,7 @@
"do_not_publish": false,
"date": "2026-10-15",
"distribution_scope": "English documentation, selected project-authored source, metadata, stock-relative differences and offline utilities; no vendor/patched firmware or native listings",
"bundled_source_files": 135,
"bundled_source_files": 136,
"full_build_tested": false,
"hardware_actions": false,
"stock_diff_variants": 24,
+1 -1
View File
@@ -28,6 +28,6 @@ The original third party prose is not relicensed here. Public ledger entries ori
AI assistants were used for coding, research organization, translation and review. Their output was treated as work to inspect, not independent hardware proof. Grok and Gemini performed bounded reviews; the exact limits are recorded in `verification/`.
The overlay depends on frame-mic-tuner at the recorded revision and retains its upstream MIT terms when acquired. OpenVR and other dependencies keep their own licenses. They are not bundled here. Published geometry and filtering methods are research foundations, not claims of inventing those algorithms.
The current dashboard uses a project authored OpenVR and OpenGL/EGL wrapper. It does not fetch or compile frame-mic-tuner code. Earlier research snapshots used that upstream overlay helper; those historical references remain part of the provenance. OpenVR and system dependencies retain their own licenses and are acquired separately. Published geometry and filtering methods are research foundations, not claims of inventing those algorithms.
The banner is AI generated editorial artwork. The avatar screenshot was provided by L8OLOOE to identify the author, with no transfer of rights to any underlying avatar model or other creator assets.
+1 -1
View File
@@ -2,7 +2,7 @@
The documentation and selected source export are complete for this handoff revision. Start at [quick setup](QUICK_SETUP.md), then [source instructions](source/README.md). The [package report](verification/PACKAGE_VERIFICATION.json) contains the final manifest hash; independently verify with `python tools/verify_package.py` before use.
Scope: 768 historical Markdown versions, 1680 translated narrative blocks, 24 exact stock-relative firmware differences, and 135 selected source files. The source export includes game and service Roy SRAM modules with distinct version/status information. No vendor firmware image, native library, decompilation, SDK, private calibration or raw recording is included.
Scope: 768 historical Markdown versions, 1680 translated narrative blocks, 24 exact stock-relative firmware differences, and 136 selected source files. The source export includes game and service Roy SRAM modules with distinct version/status information. No vendor firmware image, native library, decompilation, SDK, private calibration or raw recording is included.
Review: Grok independently inspected Roy, native UI and optics source provenance; findings were integrated and export changes are documented in [source review](verification/SOURCE_REVIEW.md) and [file manifest](verification/SOURCE_SUPPLEMENT.json). Earlier component reviews and corrections remain in [review disposition](verification/REVIEW_DISPOSITION.md).
+1 -1
View File
@@ -55,7 +55,7 @@ $env:PYTHONPATH = Join-Path (Get-Location) 'pc'
Linux equivalent, after changing to the received checkout: `python3 -m venv .venv`, then `.venv/bin/python -m pip --version`; use `export PYTHONUTF8=1` and `export PYTHONPATH="$PWD/pc"` for the historical Python layout. Confirm the received tree actually has that layout. Install the received component's pinned dependencies into that environment. Depending on the component, the historical stack uses numpy, openvr, python-osc and pytest, with optional image, video, binary-analysis and compression libraries. These are component requirements, not a claim that installing their latest versions reproduces the project.
Native Frame components have a distinct Linux ARM64 build/runtime environment: C++17, the matching OpenVR headers/runtime, and component-specific pkg-config, Cairo, libcurl and Vulkan dependencies. A Windows Python environment alone does not satisfy it. Follow the exact overlay dependency revision and license notices in the build chapter. Do not start services, install overlays or run device-facing scripts as part of initial setup.
Native Frame components have a distinct Linux ARM64 build/runtime environment: C++17, the matching OpenVR headers/runtime, and component-specific pkg-config, Cairo, libcurl, json-c, EGL and desktop OpenGL dependencies. A Windows Python environment alone does not satisfy it. Use the project authored overlay wrapper and separately supplied official OpenVR headers as described in the build chapter. No frame-mic-tuner checkout is needed. Do not start services, install overlays or run device-facing scripts as part of initial setup.
Record the received source revision, file hashes, host/target architecture, compiler/interpreter and dependency versions. Run the received component's offline checks first; record checks that cannot run because inputs are missing.
+2 -2
View File
@@ -49,7 +49,7 @@ If you are using an AI assistant, start with [AI_START_PROMPT.md](AI_START_PROMP
| Path | Contents |
| --- | --- |
| `source/pc/frame_app/` | Our native dashboard and device monitors. Upstream overlay code is acquired separately. |
| `source/pc/frame_app/` | Our native dashboard, project authored OpenVR/EGL overlay and device monitors. |
| `source/pc/radio/` | Protocol, diagnostics, session control and tracker firmware tooling. |
| `source/pc/radio/ram/` | Roy game and service modules, loader, runtime and recovery logic. |
| `source/historical-original210/` | The protected historical Roy source, separate from newer copies. |
@@ -62,7 +62,7 @@ If you are using an AI assistant, start with [AI_START_PROMPT.md](AI_START_PROMP
| `tools/` | Offline package checks, catalog queries and diff verification. |
| `verification/` | Hash manifests, review findings, exclusions and validation limits. |
There are 135 selected source files. Private calibration values were removed, personal device identifiers were replaced, and three legacy C candidates deliberately refuse compilation until their identity configuration is reviewed. Historical tests with unreviewed recorded fixtures are listed exclusions. This is not a fully reproducible build environment or a turnkey release.
There are 136 selected source files. Private calibration values were removed, personal device identifiers were replaced, and three legacy C candidates deliberately refuse compilation until their identity configuration is reviewed. Historical tests with unreviewed recorded fixtures are listed exclusions. This is not a fully reproducible build environment or a turnkey release.
No PICO or Valve firmware images, SDKs, native vendor libraries, decompilations, private calibration, raw captures or credentials are included. You obtain permitted copies of the necessary external inputs yourself. Firmware diffs require the exact matching stock image. Instructions and old experiments do not authorize a new hardware operation.
+1 -1
View File
@@ -11919,7 +11919,7 @@
"ownership": "Not legally adjudicated by path; request rights-cleared source from owner",
"selected_source_export_bundled": true,
"bundled_path": "source/pc/frame_app/main.cpp",
"bundled_sha256": "de8428b4fcc69d13f2ad1913d15b7ebfd84c45f55b2a36782a3566a550c67956",
"bundled_sha256": "e4b144e3a2de3501e70dbd1467c3a326f975cd9fc1a7cc6debbdde8e8f70ad2a",
"export_changes": [
"Publication added SPDX GPL-3.0-or-later and project attribution notice; original hashes remain provenance"
]
+1 -1
View File
@@ -2,7 +2,7 @@
## Reproducible offline setup
Resolve missing imports against the exported source, document Python and native dependency versions, and produce component build instructions. Do not assume the broad historical requirements are a lockfile. The native UI needs json-c as well as its other listed libraries. Fetch third party code only into a separate development checkout with upstream notices intact.
Resolve missing imports against the exported source, document Python and native dependency versions, and produce component build instructions. Do not assume the broad historical requirements are a lockfile. The native UI needs json-c, EGL and desktop OpenGL as well as its other listed libraries. Fetch third party code only into a separate development checkout with upstream notices intact.
## Source export configuration
+27
View File
@@ -0,0 +1,27 @@
# Dashboard overlay backend
The current dashboard no longer depends on frame-mic-tuner. The old dependency supplied a general overlay and Vulkan texture helper, not microphone functionality or tracker research. Historical references remain for provenance and do not describe the current build.
`source/pc/frame_app/frame_overlay.cpp` and `.h` are a new project implementation. They create a SteamVR dashboard with the public OpenVR API, upload Cairo's converted RGBA pixels to desktop OpenGL textures in an EGL pbuffer context, and submit them through `SetOverlayTexture`. They do not use `SetOverlayRaw`, vendor overlay sources, or code copied from the previous helper.
The wrapper supports panel and thumbnail creation, pointer events, dashboard selection, quit handling, an overlay presence probe and recreation when its handle disappears. It refuses a foreign owner of the same overlay key. Texture errors stop the UI rather than silently displaying a stale control panel. Closing the UI still does not stop the radio service.
## Build
Install component development packages for Cairo, libcurl, json-c, EGL and desktop OpenGL, a C++17 compiler and pkg-config. Acquire official OpenVR headers separately. On the Frame Linux ARM64 build host, in a separate copy of `source/`:
```sh
export OPENVR_INCLUDE_DIR=/your/official/openvr/headers
export OPENVR_LIB_DIR=/opt/steamvr/bin/linuxarm64
bash scripts/build_frame_app.sh
```
No dependency is downloaded by the script. It builds a local executable only. It does not install, connect to Roy or start a service. The context needs an EGL display compatible with SteamVR and desktop OpenGL support. This differs from the previous Vulkan path and must be validated on the actual runtime.
## Validation boundary
Offline compilation is distinct from target validation. Before calling this replacement equivalent to the previously installed UI, check it on the intended Frame session: dashboard visibility, image orientation and colors, pointer coordinates and click routing, thumbnail behavior, repeated open and close, SteamVR quit, overlay recreation and graceful failure when the EGL display is unavailable. A successful build does not prove those behaviors.
A separate Grok review was requested but timed out without findings. It is not counted as a completed review of this replacement. The object compilation used official API headers; the complete application has not been linked or run on Frame in this change.
No device operation is authorized by this document. Source and runtime dependencies remain under their respective licenses. The frozen October 15 handoff and previously installed private application are unchanged by this public source update.
+1 -1
View File
@@ -28,7 +28,7 @@ Run only relevant offline checks after reproducing the actual old failure. A gre
## Native dashboard and dependencies
Build requires a C++17 compiler, pkg-config, Cairo, libcurl, Vulkan headers and installed SteamVR LinuxARM64/OpenVR runtime. Existing build scripts in the publication source are scripts/build_frame_app.sh and scripts/prepare_overlay_dependency.py. Obtain frame-mic-tuner separately from `https://github.com/sasaken1102r/frame-mic-tuner` at recorded commit`d1e8c830b00928ab94a44e1d5323613af95263c6` and retain its upstream MIT notice. Obtain official OpenVR headers separately from ValveSoftware/openvr; do not bundle their runtime here.
The current dashboard build uses C++17, pkg-config, Cairo, libcurl, json-c, desktop OpenGL/EGL and the installed SteamVR LinuxARM64/OpenVR runtime. Its project authored `pc/frame_app/frame_overlay.cpp` replaces the earlier fetched overlay dependency. No upstream overlay project is cloned or compiled. Obtain official OpenVR headers separately, then set `OPENVR_INCLUDE_DIR` to the directory containing `openvr.h`. Optionally set `OPENVR_LIB_DIR`; the default is `/opt/steamvr/bin/linuxarm64`. Run `bash scripts/build_frame_app.sh` from a separate development copy of `source/`. The script performs no downloads, installation or service start. A valid EGL desktop OpenGL display compatible with SteamVR is required. Frame runtime behavior of this replacement still needs validation.
Publishing a native executable is separate from installing a device service, enabling radio or validating tracking. Do not auto-enable persistent startup before measured power-cycle reconnect, controller coexistence and pose quality. All actual deployment/execution requires the exact target/source/config/invocation and current authorization.
+2 -2
View File
@@ -2,7 +2,7 @@
This folder contains the selected project-authored implementation, not vendor SDK code or a firmware distribution. Read [the exact file and exclusion manifest](../verification/SOURCE_SUPPLEMENT.json). Each file has its original path/hash, bundled hash and any sanitization changes. The historical [source index](../catalog/SOURCE_CODE_INDEX.json) remains broader than this supplement.
Included components: native dashboard and monitors, Python diagnostics and transport, camera/timing/geometry/fusion, pose output and native driver source, Roy SRAM game/service C modules, loader/runtime and recovery logic, offline patch-generation scripts, requirements and two publication build scripts. Their presence is not proof of working full-body tracking or authorization to run device-facing tools.
Included components: native dashboard and monitors, Python diagnostics and transport, camera/timing/geometry/fusion, pose output and native driver source, Roy SRAM game/service C modules, loader/runtime and recovery logic, offline patch-generation scripts, requirements and the publication build script. Their presence is not proof of working full-body tracking or authorization to run device-facing tools.
## Roy variants
@@ -26,7 +26,7 @@ All files were normalized to UTF-8 and LF; compare original and bundled hashes t
Copy this source folder into a separate development checkout before installing dependencies, fetching upstream code or building. Keep this verified handoff unchanged. Follow [quick setup](../QUICK_SETUP.md) and [build notes](../docs/SOFTWARE_AND_BUILD.md).
`pc/requirements.txt` records broad historical minimums, not a reproducible dependency lock. Optional packages and system libraries remain component-specific. Native UI additionally includes `json-c/json.h` and needs json-c development headers/link flags. The historical `scripts/build_frame_app.sh` lacks explicit json-c pkg-config flags; review and add those flags in your development checkout if required by your toolchain. It fetches the pinned overlay dependency, so do not execute it as an offline verification command. Third-party notices must accompany separately obtained dependencies.
`pc/requirements.txt` records broad historical minimums, not a reproducible dependency lock. Optional packages and system libraries remain component-specific. The current native build links Cairo, libcurl, json-c, EGL, desktop OpenGL and the separately supplied OpenVR runtime. Set `OPENVR_INCLUDE_DIR` and optionally `OPENVR_LIB_DIR`, then run `bash scripts/build_frame_app.sh` in a separate source checkout. It does not fetch upstream overlay code. The project authored EGL wrapper is a new replacement, not hardware validated. See `docs/OVERLAY_BACKEND.md` in the repository root for its validation boundaries.
No clean-machine full build has been demonstrated. Configuration files, profile approvals, clocks, private calibration and recorded datasets are obtained/prepared separately. Offline patch generators write images only in your private development area. Packaging them does not waive the firmware-only-as-diff rule for this handoff.
+162
View File
@@ -0,0 +1,162 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright (C) 2026 L8OLOOE and contributors.
* Independent project implementation using the public OpenVR and EGL APIs.
*/
#include "frame_overlay.h"
#include <openvr.h>
#include <EGL/egl.h>
#include <GL/gl.h>
#include <chrono>
#include <cstdio>
#include <thread>
namespace {
constexpr const char* key="pico.frame-tracker";
bool overlayError(vr::EVROverlayError result,const char* operation) {
if(result==vr::VROverlayError_None)return false;
std::fprintf(stderr,"%s: %s\n",operation,vr::VROverlay()->GetOverlayErrorNameFromEnum(result));
return true;
}
}
struct VrOverlay::State {
bool connected=false;
int width=0,height=0;
vr::VROverlayHandle_t panel=vr::k_ulOverlayHandleInvalid,thumbnail=vr::k_ulOverlayHandleInvalid;
EGLDisplay display=EGL_NO_DISPLAY;
EGLContext context=EGL_NO_CONTEXT;
EGLSurface surface=EGL_NO_SURFACE;
GLuint textures[2]={0,0};
bool create(std::string& error) {
auto* api=vr::VROverlay();
auto result=api->CreateDashboardOverlay(key,"FramePicoTracker",&panel,&thumbnail);
if(result!=vr::VROverlayError_None){error=api->GetOverlayErrorNameFromEnum(result);return false;}
vr::HmdVector2_t scale={{static_cast<float>(width),static_cast<float>(height)}};
if(overlayError(api->SetOverlayWidthInMeters(panel,1.6f),"overlay width") ||
overlayError(api->SetOverlayInputMethod(panel,vr::VROverlayInputMethod_Mouse),"overlay input") ||
overlayError(api->SetOverlayMouseScale(panel,&scale),"overlay mouse scale")) {
error="Could not configure dashboard overlay";return false;
}
return true;
}
bool upload(vr::VROverlayHandle_t handle,GLuint texture,const uint8_t* rgba,int w,int h) {
if(!connected || !rgba || w<=0 || h<=0)return false;
if(!eglMakeCurrent(display,surface,surface,context))return false;
glBindTexture(GL_TEXTURE_2D,texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,rgba);
if(glGetError()!=GL_NO_ERROR){std::fprintf(stderr,"Overlay texture upload failed\n");return false;}
// Complete writes before the runtime copies from this application's texture.
glFinish();
vr::Texture_t data={reinterpret_cast<void*>(static_cast<uintptr_t>(texture)),vr::TextureType_OpenGL,vr::ColorSpace_Gamma};
auto result=vr::VROverlay()->SetOverlayTexture(handle,&data);
return !overlayError(result,"SetOverlayTexture");
}
};
VrOverlay::VrOverlay():state_(std::make_unique<State>()){}
VrOverlay::~VrOverlay(){shutdown();}
VrOverlay::ConnectResult VrOverlay::connect(int width,int height,std::string& error) {
shutdown();
if(width<=0 || height<=0){error="Invalid panel dimensions";return ConnectResult::Error;}
if(!vr::VR_IsRuntimeInstalled() || !vr::VR_IsHmdPresent()){error="SteamVR headset unavailable";return ConnectResult::NotRunning;}
vr::EVRInitError init=vr::VRInitError_None;
// Background initialization does not request launching SteamVR.
vr::VR_Init(&init,vr::VRApplication_Background);
if(init!=vr::VRInitError_None){error=vr::VR_GetVRInitErrorAsEnglishDescription(init);return ConnectResult::NotRunning;}
vr::VR_Shutdown();
vr::VR_Init(&init,vr::VRApplication_Overlay);
if(init!=vr::VRInitError_None){error=vr::VR_GetVRInitErrorAsEnglishDescription(init);return ConnectResult::Error;}
state_->connected=true;state_->width=width;state_->height=height;
if(!vr::VROverlay()){error="OpenVR overlay interface unavailable";shutdown();return ConnectResult::Error;}
state_->display=eglGetDisplay(EGL_DEFAULT_DISPLAY);
EGLint major=0,minor=0;
if(state_->display==EGL_NO_DISPLAY || !eglInitialize(state_->display,&major,&minor) || !eglBindAPI(EGL_OPENGL_API)) {
error="Cannot initialize EGL desktop OpenGL on the current display";shutdown();return ConnectResult::Error;
}
EGLint attributes[]={EGL_SURFACE_TYPE,EGL_PBUFFER_BIT,EGL_RENDERABLE_TYPE,EGL_OPENGL_BIT,EGL_RED_SIZE,8,EGL_GREEN_SIZE,8,EGL_BLUE_SIZE,8,EGL_ALPHA_SIZE,8,EGL_NONE};
EGLConfig config=nullptr;EGLint count=0;
if(!eglChooseConfig(state_->display,attributes,&config,1,&count) || count!=1) {
error="No EGL OpenGL pbuffer configuration";shutdown();return ConnectResult::Error;
}
EGLint size[]={EGL_WIDTH,1,EGL_HEIGHT,1,EGL_NONE};
state_->surface=eglCreatePbufferSurface(state_->display,config,size);
state_->context=eglCreateContext(state_->display,config,EGL_NO_CONTEXT,nullptr);
if(state_->surface==EGL_NO_SURFACE || state_->context==EGL_NO_CONTEXT || !eglMakeCurrent(state_->display,state_->surface,state_->surface,state_->context)) {
error="Cannot create current EGL OpenGL context";shutdown();return ConnectResult::Error;
}
glGenTextures(2,state_->textures);
if(!state_->textures[0] || !state_->textures[1] || !state_->create(error)){shutdown();return ConnectResult::Error;}
return ConnectResult::Ok;
}
void VrOverlay::shutdown() {
if(!state_)return;
auto& s=*state_;
if(s.connected && vr::VROverlay()) {
for(auto handle:{s.panel,s.thumbnail})if(handle!=vr::k_ulOverlayHandleInvalid) {
overlayError(vr::VROverlay()->ClearOverlayTexture(handle),"clear overlay");
overlayError(vr::VROverlay()->DestroyOverlay(handle),"destroy overlay");
}
// Let the runtime release its texture references before GL resources go away.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
if(s.connected)vr::VR_Shutdown();
if(s.display!=EGL_NO_DISPLAY) {
if(s.context!=EGL_NO_CONTEXT && eglMakeCurrent(s.display,s.surface,s.surface,s.context)) {
glFinish();glDeleteTextures(2,s.textures);
}
eglMakeCurrent(s.display,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
if(s.context!=EGL_NO_CONTEXT)eglDestroyContext(s.display,s.context);
if(s.surface!=EGL_NO_SURFACE)eglDestroySurface(s.display,s.surface);
eglTerminate(s.display);
}
state_=std::make_unique<State>();
}
VrEvents VrOverlay::pollEvents() {
VrEvents result;
if(!state_->connected || !vr::VROverlay()){result.quit=true;return result;}
vr::VREvent_t event{};
while(vr::VRSystem()->PollNextEvent(&event,sizeof(event)))if(event.eventType==vr::VREvent_Quit){result.quit=true;vr::VRSystem()->AcknowledgeQuit_Exiting();}
while(vr::VROverlay()->PollNextOverlayEvent(state_->panel,&event,sizeof(event))) {
switch(event.eventType) {
case vr::VREvent_Quit:result.quit=true;vr::VRSystem()->AcknowledgeQuit_Exiting();break;
case vr::VREvent_OverlayClosed:result.closeRequested=true;break;
case vr::VREvent_MouseMove:case vr::VREvent_MouseButtonDown:case vr::VREvent_MouseButtonUp:
if(event.eventType!=vr::VREvent_MouseMove && event.data.mouse.button!=vr::VRMouseButton_Left)break;
result.pointer.push_back({event.eventType==vr::VREvent_MouseMove?PointerInput::Type::Move:event.eventType==vr::VREvent_MouseButtonDown?PointerInput::Type::Down:PointerInput::Type::Up,event.data.mouse.x,state_->height-event.data.mouse.y});break;
case vr::VREvent_FocusLeave:result.pointer.push_back({PointerInput::Type::Leave,-1,-1});break;
default:break;
}
}
return result;
}
bool VrOverlay::steamVrAlive() const {return state_->connected && vr::VRSystem() && vr::VROverlay();}
void VrOverlay::showPanel(){if(state_->connected)vr::VROverlay()->ShowDashboard(key);}
bool VrOverlay::submitThumbnail(const uint8_t* rgba,int size){return state_->upload(state_->thumbnail,state_->textures[1],rgba,size,size);}
bool VrOverlay::submitPanel(const uint8_t* rgba){return state_->upload(state_->panel,state_->textures[0],rgba,state_->width,state_->height);}
OverlayRepair VrOverlay::ensureOverlay() {
if(!state_->connected || !vr::VROverlay())return OverlayRepair::Failed;
vr::VROverlayHandle_t found=vr::k_ulOverlayHandleInvalid;
auto error=vr::VROverlay()->FindOverlay(key,&found);
if(error==vr::VROverlayError_None)return found==state_->panel?OverlayRepair::Unchanged:OverlayRepair::Failed;
if(error!=vr::VROverlayError_UnknownOverlay)return OverlayRepair::Failed;
// Remove only this instance's old handles. Never destroy a foreign key owner.
for(auto handle:{state_->panel,state_->thumbnail})if(handle!=vr::k_ulOverlayHandleInvalid)vr::VROverlay()->DestroyOverlay(handle);
state_->panel=state_->thumbnail=vr::k_ulOverlayHandleInvalid;
std::string message;
if(!state_->create(message)){std::fprintf(stderr,"Overlay repair failed: %s\n",message.c_str());return OverlayRepair::Failed;}
return OverlayRepair::Repaired;
}
int VrOverlay::probe() {
vr::EVRInitError error=vr::VRInitError_None;vr::VR_Init(&error,vr::VRApplication_Background);
if(error!=vr::VRInitError_None)return 1;
vr::VROverlayHandle_t handle=vr::k_ulOverlayHandleInvalid;
bool found=vr::VROverlay() && vr::VROverlay()->FindOverlay(key,&handle)==vr::VROverlayError_None;
std::printf("FramePicoTracker overlay: %s\n",found?"present":"absent");vr::VR_Shutdown();return found?0:1;
}
+40
View File
@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright (C) 2026 L8OLOOE and contributors.
*/
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
struct PointerInput {
enum class Type { Move, Down, Up, Leave };
Type type;
double x, y;
};
struct VrEvents {
bool quit=false, closeRequested=false;
std::vector<PointerInput> pointer;
};
enum class OverlayRepair { Unchanged, Repaired, Failed };
class VrOverlay {
public:
enum class ConnectResult { Ok, NotRunning, Error };
VrOverlay();
~VrOverlay();
VrOverlay(const VrOverlay&)=delete;
VrOverlay& operator=(const VrOverlay&)=delete;
ConnectResult connect(int width,int height,std::string& error);
void shutdown();
VrEvents pollEvents();
bool steamVrAlive() const;
void showPanel();
bool submitThumbnail(const uint8_t* rgba,int size);
bool submitPanel(const uint8_t* rgba);
OverlayRepair ensureOverlay();
static int probe();
private:
struct State;
std::unique_ptr<State> state_;
};
+9 -6
View File
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright (C) 2026 L8OLOOE and contributors. See CREDITS.md and NOTICE.md.
*/
#include "vendor/vr_overlay.h"
#include "frame_overlay.h"
#include <cairo/cairo.h>
#include <curl/curl.h>
#include <atomic>
@@ -61,12 +61,13 @@ int main(int argc,char** argv){
VrOverlay overlay;std::string error;
if(overlay.connect(1200,700,error)!=VrOverlay::ConnectResult::Ok){fprintf(stderr,"%s\n",error.c_str());return 1;}
std::vector<unsigned char> rgba(1200*700*4),thumb(128*128*4,255);
overlay.submitThumbnail(thumb.data(),128);overlay.showPanel();
if(!overlay.submitThumbnail(thumb.data(),128)){fprintf(stderr,"Could not submit dashboard thumbnail\n");overlay.shutdown();curl_global_cleanup();close(lock);return 1;}
overlay.showPanel();
auto* surface=cairo_image_surface_create(CAIRO_FORMAT_ARGB32,1200,700);auto* c=cairo_create(surface);
std::string state="Connecting to diagnostic agent...",result="";
std::future<std::string> pending=std::async(std::launch::async,api,std::string("/status"));
bool recordRequest=false;auto refresh=std::chrono::steady_clock::now();
bool savedPreview=false;
bool savedPreview=false,uiFailed=false;
double mouseX=-1,mouseY=-1;
std::string queuedRoute;
std::vector<std::string> updateRoutes;
@@ -139,10 +140,12 @@ int main(int argc,char** argv){
cairo_surface_write_to_png(surface,"/home/steamos/pico-ram-work/frame-pico-ui-preview.png");savedPreview=true;
}
for(size_t i=0;i<rgba.size();i+=4){rgba[i]=pixels[i+2];rgba[i+1]=pixels[i+1];rgba[i+2]=pixels[i];rgba[i+3]=pixels[i+3];}
overlay.submitPanel(rgba.data());
if(overlay.ensureOverlay()==OverlayRepair::Repaired){overlay.submitThumbnail(thumb.data(),128);overlay.submitPanel(rgba.data());}
auto repair=overlay.ensureOverlay();
if(repair==OverlayRepair::Failed){fprintf(stderr,"Dashboard overlay unavailable\n");uiFailed=true;break;}
if(repair==OverlayRepair::Repaired && !overlay.submitThumbnail(thumb.data(),128)){fprintf(stderr,"Could not restore dashboard thumbnail\n");uiFailed=true;break;}
if(!overlay.submitPanel(rgba.data())){fprintf(stderr,"Could not submit dashboard panel\n");uiFailed=true;break;}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
if(pending.valid())pending.wait();
cairo_destroy(c);cairo_surface_destroy(surface);overlay.shutdown();curl_global_cleanup();close(lock);return 0;
cairo_destroy(c);cairo_surface_destroy(surface);overlay.shutdown();curl_global_cleanup();close(lock);return uiFailed?1:0;
}
+10 -6
View File
@@ -3,11 +3,15 @@
# Copyright (C) 2026 L8OLOOE and contributors. See CREDITS.md and NOTICE.md.
set -euo pipefail
cd "$(dirname "$0")/.."
python3 scripts/prepare_overlay_dependency.py
# Official OpenVR headers and runtime are supplied by the builder, never fetched here.
: "${OPENVR_INCLUDE_DIR:?Set OPENVR_INCLUDE_DIR to the directory containing official openvr.h}"
OPENVR_LIB_DIR="${OPENVR_LIB_DIR:-/opt/steamvr/bin/linuxarm64}"
test -f "$OPENVR_INCLUDE_DIR/openvr.h"
pkg-config --exists cairo libcurl json-c egl gl
mkdir -p build
g++ -std=c++17 -O2 -Wall -Wextra -Werror \
-I.deps/frame-mic-tuner/third_party/openvr \
pc/frame_app/main.cpp pc/frame_app/vendor/vr_overlay.cpp pc/frame_app/vendor/vk_texture.cpp \
$(pkg-config --cflags --libs cairo libcurl vulkan) -pthread \
-L/opt/steamvr/bin/linuxarm64 -lopenvr_api \
-Wl,-rpath,/opt/steamvr/bin/linuxarm64 -o build/FramePicoTracker
-I"$OPENVR_INCLUDE_DIR" \
pc/frame_app/main.cpp pc/frame_app/frame_overlay.cpp \
$(pkg-config --cflags --libs cairo libcurl json-c egl gl) -pthread \
-L"$OPENVR_LIB_DIR" -lopenvr_api \
-Wl,-rpath,"$OPENVR_LIB_DIR" -o build/FramePicoTracker
@@ -1,27 +0,0 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2026 L8OLOOE and contributors. See CREDITS.md and NOTICE.md.
from pathlib import Path
import shutil
import subprocess
ROOT = Path(__file__).resolve().parents[1]
REVISION = "d1e8c830b00928ab94a44e1d5323613af95263c6"
upstream = ROOT / ".deps" / "frame-mic-tuner"
if not upstream.exists():
upstream.parent.mkdir(parents=True, exist_ok=True)
subprocess.run(["git", "clone", "https://github.com/sasaken1102r/frame-mic-tuner", str(upstream)], check=True)
subprocess.run(["git", "-C", str(upstream), "checkout", "--detach", REVISION], check=True)
vendor = ROOT / "pc" / "frame_app" / "vendor"
vendor.mkdir(parents=True, exist_ok=True)
for name in ("vr_overlay.cpp", "vr_overlay.h", "vk_texture.cpp", "vk_texture.h"):
shutil.copy2(upstream / "src" / name, vendor / name)
shutil.copy2(upstream / "LICENSE", vendor / "LICENSE")
p = vendor / "vr_overlay.cpp"
text = p.read_text(encoding="utf-8")
import re
text, key_count = re.subn(r'(kDashboardKey\s*=\s*)"[^"]*"', r'\1"pico.frame-tracker"', text)
text, name_count = re.subn(r'(kDashboardName\s*=\s*)"[^"]*"', r'\1"PICO"', text)
if key_count != 1 or name_count != 1:
raise RuntimeError("Upstream branding layout changed; review before building")
p.write_text(text, encoding="utf-8")
print("Prepared pinned overlay dependency; upstream license retained")
+34
View File
@@ -0,0 +1,34 @@
{
"date": "2026-10-15",
"removed_build_dependency": "frame-mic-tuner",
"replacement": "project authored OpenVR/EGL desktop OpenGL overlay",
"compile": {
"target": "aarch64-linux-gnu",
"compiler": "Zig 0.13.0 clang C++17",
"flags": [
"-Wall",
"-Wextra",
"-Werror",
"-c"
],
"object_sha256": "d1166c30add6a7848081c6b7ba9129d37bff057dcd5780c63ebac927fdd5a37b",
"object_bundled": false,
"header_sources": [
"official Valve OpenVR header, private local copy",
"Khronos EGL-Registry",
"Khronos OpenGL-Registry"
],
"passed": true
},
"full_application_link_tested": false,
"frame_runtime_tested": false,
"hardware_actions": false,
"required_runtime_checks": [
"EGL context and SteamVR GPU compatibility",
"dashboard render and orientation",
"pointer coordinates and clicks",
"close and SteamVR quit",
"thumbnail and handle repair",
"texture lifetime and absence of flicker"
]
}
+45 -30
View File
@@ -32,7 +32,7 @@
{
"path": "BUILD_STATUS.json",
"bytes": 926,
"sha256": "d83687febf57f933032ac5d31a92757c4fbcea30441c8a3eab319059ee152d9e"
"sha256": "5874940bcddaf3db9dbbe67298da630605939e811b9d4b5c90fccd85b9892d89"
},
{
"path": "catalog/ASSET_REGISTER.json",
@@ -72,7 +72,7 @@
{
"path": "catalog/SOURCE_CODE_INDEX.json",
"bytes": 834911,
"sha256": "e57471c0f042554926f7948c39ccc8a62e20a836e486f4b84738f61182eeef1b"
"sha256": "0b83b56335fe99c715703d5a01410234b9d52b094949b6392c077570bab0eb58"
},
{
"path": "CONTRIBUTING.md",
@@ -81,8 +81,8 @@
},
{
"path": "CREDITS.md",
"bytes": 3037,
"sha256": "b44f5e779ff6435112b36d5204561ccd090114386b3c466a964858d60c55e4c4"
"bytes": 3176,
"sha256": "fab306093ea1c2fb52a343bc405bb4618b5cd5458887d4f41fa97e3388bdd960"
},
{
"path": "docs/ACQUISITION.md",
@@ -101,8 +101,8 @@
},
{
"path": "docs/CONTRIBUTION_TASKS.md",
"bytes": 1974,
"sha256": "a03c09ed2952eb1582a3fc71854bec02804069010ae77a0d1e7cfc04b3e9e114"
"bytes": 1998,
"sha256": "006b4724b9cdc981aa86a37ff65132906e6d255a0d8ae307309bef16edeb3d16"
},
{
"path": "docs/COVERAGE.md",
@@ -149,6 +149,11 @@
"bytes": 5766,
"sha256": "6cc71646ebfe0e49cde801ee64aced7cdb212fabe05d4d9a3676d75f45fa7265"
},
{
"path": "docs/OVERLAY_BACKEND.md",
"bytes": 2716,
"sha256": "5be73fe38c2925c41d639ca2a8e4314a71e1ee2d4c1a46aade69e4d76a26ea0a"
},
{
"path": "docs/PUBLIC_STATUS.md",
"bytes": 3797,
@@ -171,8 +176,8 @@
},
{
"path": "docs/SOFTWARE_AND_BUILD.md",
"bytes": 5380,
"sha256": "ab2bde5dd4aec6a7a71ffa36560ebc8a1e9346889b11c825300735c9cb6ff501"
"bytes": 5626,
"sha256": "82b6b7a9ea52441f478c5cda4f59effea56315acba50f6d5155e413af1b1f6be"
},
{
"path": "docs/SUPERSESSION.md",
@@ -437,7 +442,7 @@
{
"path": "FROZEN_HANDOFF.md",
"bytes": 1778,
"sha256": "29ce342fd0255044864b964e3aa5056410253e3c335c47e25ae944f6b31af2ff"
"sha256": "ad18a71e3b60ab2bae627119a557b2a337f4b22c4129a5600274bc28f59d9f3c"
},
{
"path": "LICENSE",
@@ -451,13 +456,13 @@
},
{
"path": "QUICK_SETUP.md",
"bytes": 10403,
"sha256": "67adf102ec34b267409e9b4735aec6a7e6da69bf2347c320e9c3466b4ca0ebfb"
"bytes": 10500,
"sha256": "6be726dc5ab2fb739e5a9725bf59cbfa11a47fc715350b1d5e263696fecf8ff2"
},
{
"path": "README.md",
"bytes": 8407,
"sha256": "a005cce8823582ce1e47e9408282bff4c5d70881fc36b72eaa939b73fe580703"
"bytes": 8398,
"sha256": "dfb32c838d9b85edbaa1d6275ada5d02987f7a05edce1974bb5bbd2f1dff44f5"
},
{
"path": "research/INDEX.md",
@@ -4774,6 +4779,16 @@
"bytes": 353,
"sha256": "2929646510825afecc20e986709caa7d0538a00c1ebb1bac2a7f5f86e1fcace6"
},
{
"path": "source/pc/frame_app/frame_overlay.cpp",
"bytes": 9539,
"sha256": "b3bc6b5f35ff21d45d1a2632746d3fb815b5f469814768f044fad7fabf5e85f6"
},
{
"path": "source/pc/frame_app/frame_overlay.h",
"bytes": 1050,
"sha256": "5a083dfb635cf1f3ea493582ec90e875f7d03699a8b2ec30844d3b6659c1f58e"
},
{
"path": "source/pc/frame_app/FramePicoTracker.desktop",
"bytes": 225,
@@ -4786,8 +4801,8 @@
},
{
"path": "source/pc/frame_app/main.cpp",
"bytes": 9660,
"sha256": "de8428b4fcc69d13f2ad1913d15b7ebfd84c45f55b2a36782a3566a550c67956"
"bytes": 10082,
"sha256": "e4b144e3a2de3501e70dbd1467c3a326f975cd9fc1a7cc6debbdde8e8f70ad2a"
},
{
"path": "source/pc/frame_app/tracking_watch.cpp",
@@ -5361,18 +5376,13 @@
},
{
"path": "source/README.md",
"bytes": 4893,
"sha256": "b3a4bdf5a4ef4a161829ebe53e639328681cb8dc4e8f01e06e54f1077349d80c"
"bytes": 4911,
"sha256": "ede7f39b6c1da0cfe53525464ca61cd62fa688db7212f3a023fb918a2cfa7cf7"
},
{
"path": "source/scripts/build_frame_app.sh",
"bytes": 608,
"sha256": "80973e3dea97a7a9a0bef1cf593a847a3e3ad8e5b37b8b09f6568d48976a15c8"
},
{
"path": "source/scripts/prepare_overlay_dependency.py",
"bytes": 1371,
"sha256": "e99ab95d8ef5ce45493bbbd25b3c76ac1d2953b45746558050b241ada98abc95"
"bytes": 825,
"sha256": "635b8ac50343bf26084c7d73b2e26d8798eec5b9870ced783f64844ec56a3a99"
},
{
"path": "START_HERE.md",
@@ -5434,6 +5444,11 @@
"bytes": 4683,
"sha256": "388a39b624c1ac6986005c27f2ab3675854faf8451f17e2fd1f35ef92bbd1c2c"
},
{
"path": "verification/OVERLAY_REPLACEMENT.json",
"bytes": 991,
"sha256": "84f7adaebdccd50a378ef5adb8c221f76204b313c4e59c2fd6a1b2ba96a9d1a2"
},
{
"path": "verification/PUBLICATION_ASSETS.json",
"bytes": 395,
@@ -5451,8 +5466,8 @@
},
{
"path": "verification/SOURCE_EXPORT_CHECKS.json",
"bytes": 538,
"sha256": "658d690b0c190b76925a085161ed70aba93cbd4e8894449399364067dd091deb"
"bytes": 705,
"sha256": "561b8afc5fca6daa5cfa115908840897509fe00dac5cca372ce943c601988adf"
},
{
"path": "verification/SOURCE_POINTER_UPDATES.json",
@@ -5461,13 +5476,13 @@
},
{
"path": "verification/SOURCE_REVIEW.md",
"bytes": 2250,
"sha256": "d2ed36412d1a08d0bfa2bfbf0daacebe883cf78308efce3466e251d37532233f"
"bytes": 2691,
"sha256": "7cc9bf2f195659cc714dbac0a432ccefac16227808ac4b8631381dc643c9773a"
},
{
"path": "verification/SOURCE_SUPPLEMENT.json",
"bytes": 116077,
"sha256": "0a56baac8bd5760214aef66279238ed234a2697b7c1c011f2c0a2935a74876b6"
"bytes": 116956,
"sha256": "1109a9e2e08244b37e16acd6c3d7051fe1e2839d3b6904161a555ab20d24dd11"
},
{
"path": "verification/TRANSLATION_CHECKS.json",
+6 -6
View File
@@ -1,9 +1,9 @@
{
"verified": true,
"files": 1097,
"manifested_files": 1095,
"bytes": 61403406,
"local_links_checked": 44499,
"files": 1100,
"manifested_files": 1098,
"bytes": 61418972,
"local_links_checked": 44501,
"allowlisted_extensions": [
".json",
".md",
@@ -50,8 +50,8 @@
"public_edition_note": "Frozen handoff inventory/translation counts retained as provenance. 54 ledger entries from Hinata reference replace verbatim prose with links to attributed factual digest; IDs and original source locations retained. See PUBLICATION_CHANGES.json."
},
"errors": [],
"manifest_sha256": "38502a2351dc978538ee9d3aae98404305b8d7c37898ff2088c274385b0d3fde",
"completed_utc": "2026-10-15T11:24:02.968029+00:00",
"manifest_sha256": "ef870a8d91efeaadfdb3097bc5260ce111a6ba6cfc1dfdd21398a31435c9bd47",
"completed_utc": "2026-10-15T11:41:22.321006+00:00",
"publication_edition": true,
"approved_presentation_assets": 2,
"full_build_tested": false
+4 -3
View File
@@ -1,6 +1,6 @@
{
"source_files": 135,
"python_syntax_files": 99,
"source_files": 136,
"python_syntax_files": 98,
"calibration_defaults_rejected": true,
"explicit_synthetic_geometry_accepted": true,
"test_method": "AST-extracted dataclass guard checks with stdlib stubs; full module import not tested because audit interpreter lacks numpy",
@@ -11,5 +11,6 @@
"pc/radio/ram/roy_ram_rx.c",
"pc/radio/ram/roy_ram_station_link.c",
"pc/radio/ram/roy_ram_station_three.c"
]
],
"note": "Previous calibration guards unchanged. Dependency preparation script removed; new overlay object compile recorded separately in OVERLAY_REPLACEMENT.json."
}
+4
View File
@@ -9,3 +9,7 @@ Additional findings were resolved: camera spline numeric defaults were removed a
Two concrete issues were corrected before inclusion: private factory LED geometry was removed with fail-closed construction, and private identity/address literals were replaced with explicit non-working placeholders without removing comparison gates. Original files remain unchanged.
Known limits: broad requirements are not lockfiles; third-party overlay/OpenVR and vendor runtime inputs are separately acquired; the native build script needs json-c linkage review; test fixtures and several captured-payload/binary-analysis utilities remain listed exclusions. Missing implementation dependencies must be resolved explicitly in the separate development checkout.
## Overlay dependency removal
The public source now uses project authored OpenVR/EGL desktop OpenGL code, replacing the previously fetched helper. Older Vulkan and upstream revision references are historical. See [replacement build evidence](OVERLAY_REPLACEMENT.json) and [runtime validation checklist](../docs/OVERLAY_BACKEND.md). Strict Linux ARM64 object compilation passed. The full application link and Frame runtime remain untested.
+34 -17
View File
@@ -198,9 +198,10 @@
"source_root": "pico",
"original_path": "pc/frame_app/main.cpp",
"original_sha256": "f4802ab88b738a3a87d524734c92c8c167d29d29f616e0d8fee98152b1d308d0",
"bundled_sha256": "de8428b4fcc69d13f2ad1913d15b7ebfd84c45f55b2a36782a3566a550c67956",
"bundled_sha256": "e4b144e3a2de3501e70dbd1467c3a326f975cd9fc1a7cc6debbdde8e8f70ad2a",
"changes": [
"Publication added SPDX GPL-3.0-or-later and project attribution notice; original hashes remain provenance"
"Publication added SPDX GPL-3.0-or-later and project attribution notice; original hashes remain provenance",
"Replaced fetched overlay helper with project OpenVR/EGL implementation; build no longer downloads dependencies"
],
"provenance": "Project implementation candidate; third-party/vendor trees excluded; no blanket license grant",
"hardware_executed": false
@@ -1594,21 +1595,10 @@
"source_root": "publication",
"original_path": "scripts/build_frame_app.sh",
"original_sha256": "47f16d10f4558f452b610bafe755c214e76930b625f412796dda1be1fabe0fb2",
"bundled_sha256": "80973e3dea97a7a9a0bef1cf593a847a3e3ad8e5b37b8b09f6568d48976a15c8",
"bundled_sha256": "635b8ac50343bf26084c7d73b2e26d8798eec5b9870ced783f64844ec56a3a99",
"changes": [
"Publication added SPDX GPL-3.0-or-later and project attribution notice; original hashes remain provenance"
],
"provenance": "Project implementation candidate; third-party/vendor trees excluded; no blanket license grant",
"hardware_executed": false
},
{
"path": "scripts/prepare_overlay_dependency.py",
"source_root": "publication",
"original_path": "scripts/prepare_overlay_dependency.py",
"original_sha256": "a031256d5b6b1db48c3f18921a6fabd5acc4525d77a44f7a3b182329c073cb15",
"bundled_sha256": "e99ab95d8ef5ce45493bbbd25b3c76ac1d2953b45746558050b241ada98abc95",
"changes": [
"Publication added SPDX GPL-3.0-or-later and project attribution notice; original hashes remain provenance"
"Publication added SPDX GPL-3.0-or-later and project attribution notice; original hashes remain provenance",
"Replaced fetched overlay helper with project OpenVR/EGL implementation; build no longer downloads dependencies"
],
"provenance": "Project implementation candidate; third-party/vendor trees excluded; no blanket license grant",
"hardware_executed": false
@@ -1624,6 +1614,30 @@
],
"provenance": "Project implementation candidate; third-party/vendor trees excluded; no blanket license grant",
"hardware_executed": false
},
{
"path": "pc/frame_app/frame_overlay.cpp",
"source_root": "publication-new",
"original_path": "pc/frame_app/frame_overlay.cpp",
"original_sha256": "8229ee26230405be9039dbbc5a508b2b6feb76eb85049d8adad390e723de17cc",
"bundled_sha256": "b3bc6b5f35ff21d45d1a2632746d3fb815b5f469814768f044fad7fabf5e85f6",
"changes": [
"New project authored OpenVR/EGL wrapper; not derived from upstream implementation source"
],
"provenance": "Authored for this repository using public API interfaces",
"hardware_executed": false
},
{
"path": "pc/frame_app/frame_overlay.h",
"source_root": "publication-new",
"original_path": "pc/frame_app/frame_overlay.h",
"original_sha256": "5a083dfb635cf1f3ea493582ec90e875f7d03699a8b2ec30844d3b6659c1f58e",
"bundled_sha256": "5a083dfb635cf1f3ea493582ec90e875f7d03699a8b2ec30844d3b6659c1f58e",
"changes": [
"New project authored OpenVR/EGL wrapper; not derived from upstream implementation source"
],
"provenance": "Authored for this repository using public API interfaces",
"hardware_executed": false
}
],
"excluded": [
@@ -2309,5 +2323,8 @@
}
],
"scope": "Text implementation source only. Original binaries, calibration, captures and tests with unreviewed fixtures are excluded. Source packaging is not hardware approval.",
"not_a_clean_machine_build": true
"not_a_clean_machine_build": true,
"removed_dependencies": [
"scripts/prepare_overlay_dependency.py and fetched frame-mic-tuner implementation"
]
}