Repository navigation
UIX Desktop 0.4.0 - #89
Merged
Merged
Conversation
pkg-config is the dependency contract now, with Homebrew keg-only paths folded in when brew exists. README and Makefile list deps for apt, dnf, pacman, brew, MacPorts and MSYS2. cxbe follows OXDK's move under xbox/ and fails loudly instead of silently producing nothing.
shared/platform.h is the first include everywhere. A build is _XBOX or THESEUS_DESKTOP, and a desktop build is one of THESEUS_HOST_WIN/MAC/LINUX. Bad combinations stop the compile. _WIN32 is true on the Xbox too, so Xbox-built code no longer reads it. Retires _DESKTOP, UIX_DESKTOP and _WINDOWS. make lint-platform keeps them out and runs in CI.
Code holding an Xbox path calls the Theseus file functions in theseus.h: CreateFile, CreateDirectory, DeleteFile, RemoveDirectory, the attribute and free-space queries, FindFirst/Next/Close, MoveFile, CopyFile and FOpen. The Xbox build passes each straight to XTL. The desktop build translates first (xbox_file.cpp) and host paths call the OS directly. xbox_path.h is the one translator, caller-owned buffers, with a write variant that never follows the virtual-game icon redirect. xboxfs.h, the fopen and Win32-name macros, the POSIX Win32 path stubs, the lite translator and the Windows host-path whitelist are gone. Fixes along the way: Windows created TDATA on a real E: drive, TheseusCreateDirectory made literal Q:\ dirs on mac/Linux, lstrcpyn didn't terminate on POSIX, CGameCopier::DeleteFile recursed on desktop, and texture loads decode the bytes they fetched instead of reopening by name. -Wno-macro-redefined is gone; the build is clean without it.
Configs/Library mkdirs used relative paths and dropped folders in the working directory. The hang dump and graphics log now land in the user data dir. MediaDB's cache rename replaces the old file on Windows, where rename() won't.
shared/frame_profiler replaces the loose g_* counters and hand-rolled averaging: fixed phases and counters, averaged over 250ms, read as one snapshot by the perf widget, the fps widget, the System page and the desktop --graphics-debug overlay. Xbox measures CPU time blocked on the GPU with a per-frame fence, only while the perf widget is on screen. Desktop pulls GPU time, draw count and transient buffer use from bgfx::getStats, and --graphics-debug writes a line every 5s to theseus_perf.log in the user data dir. Scene draws are counted apart from the HUD, and D3DX text mesh draws, world updates, state calls and repeats, disk queries and Inline load time are counted for the first time. Xbox state repeats are counted against a shadow copy only; every call still goes to the device.
Went through date, math, string, array, file_util, timezone and screen and noted where the code has to match the dashboard: calendar math, the JS built-ins, the script tables. Each note says what the binary does and where.
Moved every material the 5960 dash builds into materials_retail.inl, shared by both builds. Stock.xbx doesn't have to list anything anymore, and other skins only need the materials they change.
A lot of bounds checks were ASSERTs, which are gone in retail. Fixed the ones that matter: XIP and XPR loading, the skin path from Config.ini, FormatMemoryUnit on the hard drive slot, save metadata parsing, the script stack and settings writes per key. The panic screen now says what to do next. Booted and launched games on hardware once; not everything is covered.
ES-DE can be pointed straight at an es_systems.xml (AppImage installs keep theirs inside the image), and the empty-scan message says which problem you hit. Movies and episodes dropped loose in a folder show up now instead of being skipped.
The Xbox now drops render and texture stage states that didn't change, and forgets them on Reset and in the panic screen. Overlays set their full 2D state themselves since they can't count on leftovers anymore. The profiler splits the tree into material, world and draw and lists the heaviest meshes. Needs a hardware test.
Index buffers go into their vertex buffer's slot, but the check only looked at the index count. On desktop the check was an ASSERT that just warned and kept writing. Both readers skip the extra entry now, and check the mesh index before drawing.
It compared 15 characters against a 14 character name, so it never matched.
Plex, Jellyfin and xCloud read the in-flight map outside its lock while finished downloads were erasing from it on other threads.
Advance() used GetTickCount in a float. On Windows that's system uptime in 15.6 ms steps, so animation got choppier the longer the PC had been up. It uses the SDL performance counter in a double now, same as mac and Linux. Still needs a run on Windows.
Every episode dropped straight in the TV root got the root folder as its show path, so they all collided when TMDB data carried over on a rescan. Each one now keys on its own file.
Episodes sitting straight in a show folder came out in whatever order the disk listed them. Now they sort by season and episode from the filename (S01E02, s1e2, 1x02), and anything unnumbered follows in natural name order.
Reloading games.ini wiped the injected xCloud and ES-DE rows, and they stayed gone until a restart. The reload now carries them over since they never live in the file.
A resync only marked the old ES-DE rows dead and appended the whole library again, so every rescan burned another library's worth of slots. Same with an xCloud refresh. Dead rows now get compacted away, and Title Maker drops its cached rows and selections when that happens.
Opening a show or season read the server list straight off while a sync worker could be swapping it out after a sign in. It copies the address under the lock now.
The lookup workers each save a checkpoint every 10 titles, all through the same temp file. Two at once could interleave and rename a scrambled cache into place. Saves take turns now.
The last change put the clock on the performance counter, which on mac counts from boot. Scripts time the screensaver against zero, so it fired on the first frame before the menu existed and threw an array error. Windows had the same problem before, since GetTickCount is uptime there too.
ASSERT is nothing in retail and only a warning on desktop, and a lot of code leaned on it anyway. Switched the ones that touch real memory: long numbers in scripts overran a stack buffer in the compiler, big language files ran off the translation table, scripts could write junk parental control values into EEPROM, and XIP reloads trusted the buffer counts.
The library scene's getters and the cache load touched the movie and show lists with no lock while a refresh thread could be swapping them, so browsing during a rescan could read freed strings. They take the library lock now, and a cache that fails to load halfway leaves the old list alone.
Hitting Refresh Library in Playlist Maker kicks a scan that swaps the movie and show lists, while the window kept reading titles and paths out of them every frame. The listing holds the library lock now.
The Xbox file functions now reach the OS through host.h, with one version for mac and Linux and one for Windows. Folder listing works the same everywhere, so Windows gets the games.ini-only folders it was missing. Needs a Windows test.
Library keys, episode order, the games list keeping xCloud and ES-DE rows, and a handful of threading fixes in Plex and the media library.
Http_GetToFile wrote straight to the final path, so the art loader could pick up half a jpg and a failed fetch wiped whatever was there. It now writes beside the target and renames on success. Needs a Windows test.
Plex, Jellyfin and xCloud ids came straight off the server into cache paths, so an id with a slash or .. in it could write outside the art folder. Anything that isn't a plain filename is skipped now, including xCloud rows whose id becomes an icon name.
A lookup that got no real answer (network down, bad key) came back as not found, and the library saved that as a permanent miss. Now only real search responses get cached, and a failed one stays unlooked up so the next scan tries again. Old cached error pages are ignored too.
Wrote GenerateRadialAlphaMask fresh from the disassembly at 0x56110, with the per-pixel math, constants and the four callers noted above it. Output matches what we had pixel for pixel on all four masks.
Wrote both nodes fresh from 0x400f0..0x40320 and 0x418a0..0x41bc0 and added them to the Settings doc. Reads, writes, file switches, the setting objects and four screen saver timelines with resets and enable flips all match the old code step for step.
Wrote both fresh from 0x4f990..0x4fb70 and 0x3ba60..0x3bb70 and wrote them up in a new Screen doc. Also fixed two wrong Settings rows in the decomp index. Both builds compile clean and the desktop runs as before.
Read the 75 zones straight out of the 5960 table at 0x201f0 and wrote them one per row. Every name, bias and change date matches the old table.
Wrote MaxMaterial and every material type's Setup again from 0x56110..0x5a130 and wrote up what the binary does in a new Materials doc. The skin editor color access and the retail table are untouched. Every Setup leaves the same state as the old Xbox file on 121,920 checked draws across all 127 materials, no skin and all 11 skins, and the masks, editor colors and skin reloads match too.
Dropped the desktop copy of the materials and built render/materials.cpp instead. The two NV2A antialias states are Xbox only and the skin editor's frame stamp is desktop only. Every Setup leaves the same state as the old desktop file on all 121,920 checked draws, no skin and all 11 skins.
Wrote CNameSpace, CLerper and the array SetSize calls fresh from the 5960 XBE and added their addresses to the Util doc. Lookups, a lerper timeline with removals and array growth match the old code exactly. Dropped the unused namespace Dump.
Wrote Reset, Fetch, FetchFile and MakeUnicode fresh from 0x2e560..0x2e840 and added them to the FileUtil doc. Fetch results match the old code on every URL kind against the real Data folder, low memory and failed reads included. Dropped Update and the stream reader, which nothing used.
NewFailed now follows the 5960 out of memory sequence, texture cache then mesh cache then give up, with the same retries as before on every mix of cache results. Dropped the assert handler, hex dump and class dump that nothing called.
Added what the 5960 Setups do that ours skipped: the base Setup and the icons reset stage 0's coordinate index and transform flags, FreeSpace resets stage 1's index, MotdIcon draws without the soft edge, the Live keys take the pulse clock, and the extra stock logo names load from the XIP. Checked that those are the only state changes across all 127 materials. orangeEggGlow is still a plain color; its camera space projection needs texture coordinate generation the desktop renderer doesn't have.
Wrote the binding, the properties, the secret key and the event rules of Advance fresh from 0x40620..0x41800 and wrote them up in a new Input doc. The SDL pad and keyboard reading stays as it was. Every event matches the old code over 4,000 scripted frames of pad, keyboard, rebinding and secret key input.
CanDriveBeCleanup is written fresh from 0x3b460 and gives the same answer as before for every character. The rest of the desktop Config is desktop stubs. Dropped a password encoder nothing called. 5960 allows F to M, T and U where Theseus allows H to O, T and U; left as is.
Wrote both fresh from 0x32950..0x32ba0 and 0x606d0..0x60930. The Math constants match the binary's bits, and DotField spacing, drift and every drawn frame match the old code bit for bit over 5,000 frames.
Wrote the array, its element references and the five script methods fresh from 0x30440..0x30e70. Contents, lengths, errors and reference counts match the old code over every constructor form, out of range writes, slices, sorts and joins. Like 5960, arrays made by concat, reverse, slice and sort aren't typed as arrays, so concat refuses them; left as is.
Nothing called the software blits, DrawImage, GetImageSize, FetchImage, the RAW decoder, LoadTextureFromXPR, CreateMesh or CMesh::Create from memory, on either build. Removed them and their declarations. The image cache stays since the skin preload fills it.
Locale, date, strings, file paths, settings files and nodes, screen, timezone, util, activefile, joystick, config, math, dotfield and arrays written from the 5960 binary; desktop's separate locale.cpp is gone. Also fixes desktop language files losing every non-ASCII character.
Took main's Math, Array, DotField and Settings nodes over the copies rebuilt here, and its memory hooks. The ScreenSaver index rows now point at the Settings doc.
Rebuilt the texture nodes, the texture cache and its background loader, the XPR parser, CMesh, the Mesh node and MakeSphere from the 5960 XBE. The skin folder probing, loose file fallbacks, skin preload and the flushes are kept as they were. ParseTexture gives the same result as before on all 294 shipped .xbx files plus broken variants of each, 19404 cases.
When D3DX couldn't make the sphere, MakeSphere released the buffers, deleted the mesh, which released them again, and then went on to repack the vertices through a NULL mesh. It deletes the mesh and returns NULL now, which the Sphere node already handles. Desktop had its own guard for this.
Mesh nodes delete their mesh through CMeshCore, which had no virtual destructor, so CMesh never released its vertex and index buffers. Every skin switch leaked the buffers of every loose mesh. Gave CMeshCore a virtual destructor; a flushed mesh's vertex buffer now drops to zero references on desktop instead of staying at one. 5960 has the same leak.
Dropped the desktop copies of the texture, image and mesh code and built render/asset_loader.cpp instead, with the desktop decoders, preload scan and inspector names behind seams. Every mesh, XIP mesh, texture and cache step in my test gives the same result as before under no skin and all eleven skins, 10861 checks. A mesh that fails to load now leaves an empty mesh on the node like on Xbox, which draws nothing either way.
5960 has a function that throws a url out of the texture cache, and its MOTD clear calls it for the .xbx it just deleted. Theseus deleted the files but kept the textures cached. Added UnloadTexture and call it for both MOTD files. Tested on desktop: a cached texture leaves the cache under any case of its name, an unknown name reports false. Needs an Xbox Live Today test.
Materials, camera, animation nodes, starfield and the asset loader written from the 5960 binary; desktop's separate materials, image, texture and mesh files are gone. Also stops every skin switch from leaking loose mesh buffers.
Assigning to a negative index wrote in front of the array, and slice with a negative start or an end past the last element read outside it. 5960 does both; scripts get the out of bounds error or a clamped slice now.
rnd() divided rand() by 32767, the Xbox RAND_MAX. On mac and Linux RAND_MAX is about two billion, so the starfield, dotfield and texture effects got values far past what they asked for. It divides by RAND_MAX now, which is the same thing on Xbox.
When a new [Playlist:] section started, the item still being read from the previous playlist was carried into the new one, through a pointer the new section could already have moved.
config.xap read AdvancedMode in initialize(), which runs before an Inline can see default.xap, so GetSavedBooleanValue came up as an unknown function. It reads the setting when the list is built now.
Opening the panel ran OnActivate before its own scene had loaded, so building the list hit an empty children array (Array reference out of bounds, line 593). The first time in, the panel's onLoad builds the list instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
UIX Desktop 0.4.0, for the Xbox's 25th birthday.
What's in it
make lint-platformandmake win64-import-guardkeep it that way.theseus.log), and crash reports in thecrashesfolder.Fixes
Fixes #83, fixes #85, fixes #86, fixes #37, fixes #71, fixes #44, fixes #42, fixes #24, fixes #58, fixes #79, fixes #80.
Also: Windows dashboard launches, desktop frame timing, garbled desktop keyboard text, sounds playing fast on 48 kHz and surround devices, random values out of range on mac/Linux, a mesh buffer leak on every skin switch, UIX Settings and Skins menu script errors, playlists losing items, and a pile of crashes on broken XIPs and scripts.
Probably fixed, needs a retest on this build: #77, #39, #18. Still open: #76, #38, #47, #41, #54, #84, #28.
Tested
mac desktop, Linux x64/ARM64 and Windows x64 builds in CI; Windows run under Wine; Xbox retail and debug compile. Not yet run on Xbox hardware.