forked from mediaexplorer74/WPR
-
Notifications
You must be signed in to change notification settings - Fork 1
Update History
Bubbleshum edited this page May 22, 2026
·
17 revisions
Running changelog of WPR fixes / features / compatibility changes. Most recent entries are at the top.
- Compat: Assassin's Creed: Altaïr's Chronicles promoted from Partial →
Playable (end-to-end after
SignedInGamer.SignedIndeferred-invoke fix below) - Fix: Assassin's Creed crashed in
XNAGame..ctorwith aNullReferenceExceptioninside its ownSignedInhandler. Root cause:SignedInGamer.SignedIn'saddaccessor took two paths — a deferred 2sTask.Delayfor the very first subscriber in the session, and a synchronous invoke for any later subscriber (gated by a staticFirstSignInSessionDoneflag). Two compounding problems: (1)SignedInGamer.Reset()was called afterActivator.CreateInstance(mainType!)inApplicationLaunch.Start, so the flag set by a previous game launch in the same WPR session carried into the new game's ctor; (2) the synchronous path then fired the just-attached handler during+=, while the game's ctor was still mid-construction, and the immediate-fire branch had no try/catch wrapper (unlike the deferred branch). Assassin'sXNAGame.aaccessed athis-field its ctor hadn't initialised yet, NRE'd, and the exception escaped up throughActivator.CreateInstance. Fix: collapse the two paths into one — every subscription dispatches onTask.Run(delay 0 for late subscribers, 2s for the first), goes through the same_SignInGatesemaphore + try/catch, and never runs synchronously from+=. Also movedSignedInGamer.Reset()to run beforeActivator.CreateInstance. Shim-only — no reinstall - Compat: Plants vs Zombies promoted from Broken → Playable (end-to-end after achievement-seed + SpriteBatch tolerance fixes below)
- Fix: PvZ launched to a black screen because
Lawn.AchievementsWidget.DrawNRE'd insideAchievements.GetAchievementItem— the game's staticgAchievementListwas empty, so the lookup returned null and the NRE escaped mid-SpriteBatch.Begin, wedging every subsequent frame on"Begin has been called before calling End". Root cause: PvZ stores its 18 achievement keys in an inlineAchievements.ACHIEVEMENT_KEYS[]static array (built in the cctor), so none ofXnaAchievementCodeExtractor's three sources —Content/xml/socialnetworks.xml.xnb, ILldstrnearAwardAchievement*callsites, orContent/Achievements/*.xnbfilenames — recovered any keys at install time. The seeder wrote 0 rows;BeginGetAchievementsreturned 0 rows; the game'sGetAchievementsCallbackadded 0 items togAchievementList. Added a Source D (KnownProductCatalogues) keyed by ProductId that returns hardcoded keys recovered via decompilation, threadedproductIdthroughXnaAchievementCodeExtractor.ExtractRichandXnaAchievementSeeder.SeedAsync. Install-time change — affected games need reinstalling. Now seeds 18 rows andBeginGetAchievements: 18 rowsconfirms it - Fix: After the achievement seed worked the game flickered on main menu and
in level —
Lawn.GameSelector.DrawOverlaystill NRE'd every frame on some other null reference, but the deeper problem was that PvZ'sSexy.Graphicslayer tracks its ownspritebatchBeganflag separately from FNA'sbeginCalled, and the two desync once any Draw exception leaves the game's flag stale. The result was a within-frame double-Begin viaSetupDrawMode → EndFrame → EndDrawImageTransformed → BeginFrame, throwingInvalidOperationExceptionand dropping every other frame. We can't reach the game's private flag from the shim. Made FNA'sSpriteBatch.Begin/Endtolerant of out-of-order calls: a secondBeginwithout an interveningEndsoft-resets and starts a fresh batch (drops the queued sprites of the discarded batch); a strayEndwithout a matchingBeginno-ops. First 5 of each are logged so we can spot if it's firing in production. Shim-only — no reinstall - Feat: Diagnostic
[wpr-trace] BeginGetAchievements: N rows for <ProductId>log inSignedInGamer.BeginGetAchievementsconfirms whether the install- time seed populated for a given game on first launch - Feat: Keyboard accelerometer simulator. New Controls page in the desktop
sidebar binds four keys (defaults WASD) to tilt directions; readings flow
through the existing
Microsoft.Devices.Sensors.Accelerometerso games see them without any per-game shim work. Sensitivity slider, master toggle, in-game tilt-overlay (Avalonia for Silverlight host, FNADrawableGameComponentfor XNA), and a live-preview dial on the Controls page. Orientation-aware: the screen-relative key intent gets rotated into the device-portrait frame the WP7 sensor contract expects, so a landscape game (W = "tilt up the screen") produces the correct device-X tilt the game interprets as steer-left. Desktop orientation is inferred from the back-buffer aspect because FNA'sWindow.CurrentOrientationonly updates from SDL display-rotation events that never fire on the desktop.Accelerometer.CurrentValue/IsDataValid/TimeBetweenUpdateswere also added so games that poll instead of subscribing toReadingChangedsee live readings too - Compat: Hydro Thunder GO promoted from Partial → Playable (steerable via the keyboard accelerometer)
- Compat: Uno confirmed Playable
- Fix: Sonic 4 Episode I self-paused on every Update tick. The game's
AppMain.isForegroundflag is flipped true only by itsGame.Activatedhandler, andActivatednever fired on WPR becauseINTERNAL_isActivewas initialisedtrue(suppressing the BeforeLoop setter's no-op transition to avoid Asphalt 5's pre-Initialize KeyNotFoundException). Net effect:isForegroundstayed false, the game's pause condition (!isForegroundORed into the trigger) re-armed every frame, and pause reasserted itself immediately after dismissal. Fix: defer a one-shotOnActivatedto the end of the firstGame.Tick, where every game's per-Update state (including Asphalt 5's) is already populated - Fix: Window background/foreground transitions now fire
Deactivated/Activatedcorrectly on desktop and Android. Restored theSDL_WINDOWEVENT_FOCUS_LOST → IsActive=falsebranch inSDL2_FNAPlatform.PollEventsthat had been commented out under a//RnDmarker. SymmetricFOCUS_GAINEDwas already wired - Feat: Multi-touch input is now additive with the mouse-as-touch shim.
UpdateTouchPanelStatepreviously branched either-or — ifTouchPanel.MouseAsTouchwas on (the default for XNA games on WPR) the real-finger poll loop was skipped entirely, capping all input at a single touch even on multi-touch hardware. New shape: real fingers fill slots0..MAX_TOUCHES-2fromSDL_GetTouchFinger; whenMouseAsTouchis on the mouse takes the last slot with synthetic finger IDint.MaxValueso it can never collide with a real finger's ID. Sonic 4's "hold D-pad + tap jump" gameplay now works - Fix: Asphalt 5 splash → menu tap-to-continue now registers. The
per-
Game.TickFrameworkDispatcher.Update()call added on 21/05 was redundant — stock FNA'sGame.Updatealready pumps the dispatcher at its end. Pumping twice per tick madeTouchPanel.Updaterun twice in close succession; the second run promotedtouches[0]fromPressedtoMovedbeforeCGame1.g()could read it, soh2.b(press handler) never recorded the finger andh2.d'sif (i > 0)release-guard always failed. Splash-statelt.b()waiting onbe.ey.fm != 0was the surfaced case. Removed the redundant pump in FNAGame.Tick - Compat: Asphalt 5 promoted from Partial → Playable
- Compat: Sonic 4 Episode I confirmed Playable (pause loop fixed, multi-touch routed)
- Compat: Tentacles promoted from Broken → Playable (end-to-end after the fixes below)
- Fix: FNA's
ContentTypeReaderManagercouldn't resolveReflectiveReader<PressPlay.FFWD.Scene>becauseType.GetType()doesn't see types in the user game's collectible ALC, and the existingstring.Split(',')fallback broke on the generic argument[[PressPlay.FFWD.Scene, PressPlay.FFWD, …]](the comma between the inner type and its assembly hint was indistinguishable from the outer delimiter). Replaced withType.GetType's resolver-callback overload that walksAppDomain.CurrentDomain.GetAssemblies()— which returns every loaded assembly across every ALC — so generic readers parameterised by user-ALC types resolve correctly. Tentacles' Preloader scene XNB now deserialises - Fix: FFWD-based games call
Application.LoadLevel("X")with bare scene names even though every level XNB ships underContent/Scenes/. ContentManager constructedContent/X.xnb, the file wasn't there,AssetHelper.Load<T>silently swallowed the failure and returneddefault(T), and the loading screen hung forever waiting onloadingProgress == 1.0f.TitleContainer.OpenStreamnow retriesContent/<name>.xnbasContent/Scenes/<name>.xnbwhen the original is missing and has no subdirectory hint. Safe for non-FFWD games (fallback file simply won't exist either) - Fix:
Microsoft.Phone.Shell.StandardTileData.Countwasintin our shim but the WP7 SDK usesint?. Tentacles' live-tile updater callsset_Count(int?)every frame from a component Update and was trippingMissingMethodException~once per tick - Fix:
FNA.Game.RunLoopnow wraps the finalOnExiting(this, EventArgs.Empty)in try/catch + log. Tentacles'MetricsSender.CreateTearDownExtendedKeysNREs onGlobalManager.Instance.currentProfilewhen the user closes during early boot (currentProfile is null until the preloader finishes loading it). Can't fix the game code, but the host no longer surfaces its "unexpected error" dialog on close - Fix:
SignedInGamer.SignedInhandler invocations now serialise behind aSemaphoreSlim. Tentacles'Game1.Initializeregisters the same callback twice; both invocations were firing in parallel via separateTask.Delay.ContinueWiths, racing on the sharedAchievementContext.Currentand tripping EF Core'sConcurrencyDetectorinsideGamer.GetProfile. Handlers still get their independent ~2 s delay; only the synchronous Invoke runs single-file - Fix: Mouse-as-touch clicks now produce
GestureType.Tapgestures on desktop.SDL_MOUSEMOTIONwas forwarded toINTERNAL_onTouchEventunconditionally, including hover (no button held). Hover motion ranGestureDetector.OnMovedwhich setactiveFingerId = 1; the nextMOUSEBUTTONDOWN'sOnPressed(1)then sawactiveFingerId != NO_FINGERand routed into pinch-init (state = PINCHING). The matchingMOUSEBUTTONUPranOnReleased_Pinchinstead of Tap detection — so Tap-gated screens (Tentacles'LemmyTravelScreen, "tap to continue" prompts) never advanced from mouse but worked fine from real touch (no hover). Fix:SDL2_FNAPlatformskips the synthesised Moved event whenevt.motion.state == 0. Drag (button-held motion) still goes through, so swipe/pinch/drag from mouse continue to work - Feat: Periodic FFWD loading-state heartbeat in FNA
Game.Tick([wpr-heartbeat], fires ~every 2 s past the first-30-ticks verbose trace cap). ReflectsPressPlay.FFWD.ApplicationandPressPlay.Tentacles.Scripts.LevelHandlerstatic fields plus the active screen stack and the current level identity — turned a "stuck on loading screen" symptom into a precise gate-by-gate diagnosis. Best-effort, swallows all reflection errors,[Conditional("DEBUG")]-gated - Feat:
ContentManager.Load<T>now logs the underlying exception with type/HResult/inner/stack before rethrowing ([wpr-content]). FFWD'sAssetHelper.Loadsilently catches ContentManager.Load failures and returnsdefault(T); without the trace, a missing ContentTypeReader or malformed XNB was invisible. Trace lets the caller's swallow stand — only adds visibility - Feat: Assembly-resolver diagnostics in
ApplicationLaunch—[wpr-resolve-user]/[wpr-resolve-default]lines log every Resolving probe with full exception details whenLoadFromAssemblyPathfails
- Fix: Asphalt 5 sat on a blank loading screen —
StartupModeenum integer values now match the WP7 SDK (Launch=1,Activate=2), and FNA'sGame.IsActiveno longer fires a spuriousActivatedevent at first frame - Fix: Tentacles crashed at exit on a null
ApplicationCurrentMemoryUsage—Microsoft.Phone.Info.DeviceExtendedPropertiesnow returns the WP7 memory counters (ApplicationCurrentMemoryUsage,ApplicationPeakMemoryUsage,ApplicationMemoryUsageLimit) - Fix: XNA games that wait on
MediaPlayer/ song-finished callbacks before advancing past their splash now progress —Game.Tickauto-pumpsFrameworkDispatcher.Update()once per update, matching WP7 XNA 4.0 behaviour - Feat: Per-game
wpr_game_debug.logand the in-engine[wpr-trace]output are now#if DEBUG-gated viaWprDebugTrace— Release builds elide the trace formatting and file listener entirely (no log spam, no per-frame cost) - Feat: Richer assembly-resolver diagnostics in
ApplicationLaunch—Resolvingfailures log the underlying exception type, HResult and inner exception instead of the opaque "Operation is not supported" surface error - Compat: Asphalt 5 promoted from Broken → Partial (loads splash, gameplay TBD)
- Compat: Final Fantasy promoted to Playable
- Compat: Fruit Ninja confirmed Playable (no longer blocked on
GamerProfile.GetGamerPicture)
- Fix: Small bug on second launch of XNA games, where resources arent released fully
- Feat: Added Windows based notifications
- Feat: Added game icon as window icon for XNA