3 Commits

Author SHA1 Message Date
patchzyy 384623a4c7 version update 2026-08-23 23:12:34 +02:00
patchzyy 6c2712307e Update vi.cpp 2026-08-23 23:04:32 +02:00
patchzyy c5a53ce0b3 Update InstallerEngine.cs 2026-08-23 22:57:28 +02:00
5 changed files with 33 additions and 21 deletions
+1 -1
View File
@@ -253,7 +253,7 @@ foreach ($required in @('ToolkitFingerprint','TranslationFingerprint','NativeToo
$manifest = [ordered]@{
SchemaVersion = 2
ProductVersion = '0.2.20'
ProductVersion = '0.2.21'
ExpectedGameId = $pins.GameId
ExpectedDolSha256 = $pins.DolSha256
ExpectedRelSha256 = $pins.RelSha256
+17 -17
View File
@@ -305,27 +305,27 @@ internal sealed class InstallerEngine
RuntimeConfiguration.SetRetroRewindRoot(configPath, canonicalRetroRoot);
transaction.Commit();
// A portable installation is owned by the folder it lives in, not by this machine. Adding a
// machine-wide uninstall entry for it would outlive the folder and, worse, would overwrite
// the entry of a normal installation on the same account.
if (PortableRoot.TryFind(installDirectory) is not null)
try
{
_reporter.Diagnostic(
"Portable installation: no Windows uninstall entry was registered. Remove the folder, " +
"or run the copied setup with --uninstall, to uninstall it.");
}
else
{
try
// A portable installation is owned by the folder it lives in, not by this machine. Adding
// a machine-wide uninstall entry for it would outlive the folder and, worse, would
// overwrite the entry of a normal installation on the same account.
if (PortableRoot.TryFind(installDirectory) is not null)
{
_reporter.Diagnostic(
"Portable installation: no Windows uninstall entry was registered. Remove the folder, " +
"or run the copied setup with --uninstall, to uninstall it.");
}
else
{
ShellIntegration.RegisterUninstaller(installDirectory, state.RetroRewindInstalled);
ShellIntegration.CreateShortcuts(installDirectory);
}
catch (Exception ex)
{
_reporter.Diagnostic("The installation succeeded, but Windows shell integration failed: " +
ex.Message);
}
ShellIntegration.CreateShortcuts(installDirectory);
}
catch (Exception ex)
{
_reporter.Diagnostic("The installation succeeded, but Windows shell integration failed: " +
ex.Message);
}
_reporter.Progress(InstallStages.Publish, "Installation complete.", completionPercent);
+1 -1
View File
@@ -121,7 +121,7 @@ internal static class PlatformChecks
internal static class ProductInfo
{
public const string Name = "WiiCompiled";
public const string Version = "0.2.20";
public const string Version = "0.2.21";
/// <summary>
/// The setup executable is copied into the installation under this name. It is the launcher and
@@ -7,7 +7,7 @@
<AssemblyName>WiiCompiled.Setup</AssemblyName>
<RootNamespace>WiiCompiled.Setup</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Version>0.2.20</Version>
<Version>0.2.21</Version>
<Authors>patchzy</Authors>
<Product>WiiCompiled</Product>
<Description>Command-line installer and launcher for WiiCompiled</Description>
+13 -1
View File
@@ -259,6 +259,12 @@ uint32_t ExtractTvFormat(uint32_t tvMode) {
// Re-entry guard to prevent AdvanceRetrace calling itself via OSWakeupThread -> SelectThread
static std::atomic<bool> s_inAdvanceRetrace{false};
// Set while VI_HLE_PresentFrame runs its seal/pace/pre-warm sequence. Guest callbacks
// serviced during that window (pace-loop alarms, GX timing polls) still see the stale
// hasValidXfb/g_auroraFrameActive flags; a retrace-context present fired from them would
// end the freshly pre-warmed empty frame and show it as a black frame group.
static std::atomic<bool> s_presentSequenceActive{false};
void AdvanceRetrace(CpuContext* ctx, Clock::time_point retraceStamp, bool serviceAurora) {
// Prevent re-entry - this can happen if OSWakeupThread triggers SelectThread
// which goes idle and calls ProcessTimerEvents again
@@ -347,7 +353,7 @@ void AdvanceRetrace(CpuContext* ctx, Clock::time_point retraceStamp, bool servic
// VISetBlack(TRUE) keeps frame submission running but shows only the clear color: GX render work is
// skipped and Aurora's end_frame() clears to black, matching the hardware manual's "signal continues,
// pixels go black" behavior. When not black, submission waits for hasXfbReady (GXCopyDisp done).
if (serviceAurora) {
if (serviceAurora && !s_presentSequenceActive.load(std::memory_order_acquire)) {
const bool frameActive = g_auroraFrameActive.load(std::memory_order_acquire);
const bool xfbMatches = (readyXfb != 0 && readyXfb == currentFb);
const bool shouldPresentXfb = hasXfbReady && !isBlack && xfbMatches;
@@ -512,6 +518,12 @@ void PaceToRetraceBoundary(Clock::time_point deadline) {
// producer to the VI retrace boundary, and pre-warms the next frame. Paced from GXCopyDisp; unpaced for
// the retrace-context black/boot present path in AdvanceRetrace.
void VI_HLE_PresentFrame(bool presentedXfb, bool paceToRetrace) {
if (s_presentSequenceActive.exchange(true, std::memory_order_acq_rel)) {
return;
}
struct SequenceGuard {
~SequenceGuard() { s_presentSequenceActive.store(false, std::memory_order_release); }
} sequenceGuard;
Clock::time_point paceDeadline{};
bool paceThisFrame = false;
if (paceToRetrace) {