Studio: bundles (Bundle menu and Inspector tab), Sound into the Environment tab, tab labels no longer clipped

- Bundle tab: name, environments with their pictures (read in place), add the open one / My Environments / any
  .fenv, reorder, remove, double-click to open (unpacked first), Save / Save As, Install on Steam Frame (onto the
  Headset tab's list), Unpack into My Environments. Saving and unpacking run in the background.
- .fbundle opens from File > Open, the Bundle menu or a drop; the installer takes bundles and shows the first .fenv.
- HslRenderer::createPicture / releasePicture for UI thumbnails.
- Inspector tabs: ImGui draws a tab's label with the padding at BeginTabBar, so the snug padding is pushed there too.
- Self-test: bundle make, save, validate, reopen and unpack (93/93).
- docs/bundles.md written; Studio guide and README follow.
- Linux: no GLFW_INCLUDE_NONE redefinition, freopen's result checked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ToastconcernandClaude Opus 5.5 committed 2026-10-21 12:44:57 -05:00
1 parent 95ccea95ca
commit 8b0c2aa5a3
7 files changed
+644 -30

No files matched your search

+14
View File
@@ -337,6 +337,18 @@ void HslRenderer::destroy(Image& i) {
i = Image{};
}
VkImageView HslRenderer::createPicture(const u8* rgba, uint32_t w, uint32_t h) {
Image i = createTexture(rgba, w, h, false);
if (!i.view) return VK_NULL_HANDLE;
pictures_.push_back(i);
return i.view;
}
void HslRenderer::releasePicture(VkImageView view) {
for (size_t k = 0; k < pictures_.size(); ++k)
if (pictures_[k].view == view) { destroy(pictures_[k]); pictures_.erase(pictures_.begin() + static_cast<std::ptrdiff_t>(k)); return; }
}
template <typename F> void HslRenderer::oneShot(F&& record) {
if (recordInto_) { // streaming: ride along in the frame's command buffer, no stall
record(recordInto_);
@@ -4266,6 +4278,8 @@ void HslRenderer::shutdown() {
destroyGuide();
destroyDebug();
for (VkImageView v : layerViews_) if (v) vkDestroyImageView(device_, v, nullptr);
for (Image& i : pictures_) destroy(i);
pictures_.clear();
for (Image* i : {&colorMs_, &depth_, &resolve_, &fdm_, &sub_, &white_, &black_, &nullTex_, &noMetal_, &flatNormal_, &whiteCube_, &white3D_, &shadowMap_}) destroy(*i);
if (fovFb_) vkDestroyFramebuffer(device_, fovFb_, nullptr);
if (fovPipe_) vkDestroyPipeline(device_, fovPipe_, nullptr);