Skip to content

Commit 7bdcefe

Browse files
authored
Preview 1.84.2 (#875)
![UpdateIsAvailable-Campaign-Columbina](https://github.com/user-attachments/assets/e7043018-4d49-48f2-adf1-3c846fd3c3e4) # Preview 1.84.2 (Codename: Columbina) ## What's changed? - **[Fix]** [ImageCropper crash for small image](d35a4fc), by @shatyuka - **[Imp]** [Update tooling version requirements](fdc8215), by @Cryotechnic - **[Imp+Fix]** [Background image system improvements](9e6905c), by @neon-nyan - Applies fading transition while pausing background to static image - Reduce UI thread overhead while transitioning between backgrounds - [Fix seeking on pause causing background position to reset](dd6f624) - [Fix 0x8001010E Exception on ImageBackgroundManager.CanOpenCropOverlay](beed30b) - **[Fix]** XAML Binding warnings, by @neon-nyan - [Fix binding on FFmpeg decoding mode settings](af44646) - [Fix binding on Image Event icon](b8a5915) - [Fix bind conversion warning on SettingsPage](f997f32) - **[Fix]** [Manual Game Switching doesn't reload the page](a04d41f), by @neon-nyan - **[Fix]** [Disable system media transport controls](1b3f5dc), by @shatyuka - **[Fix]** [Crash due to missing Contrast brushes on Contrast-enabled theme](41479dc), by @Cryotechnic - **[HSR][Fix]** Crash due to Missing URLs on Audio and Video files while performing Game Repair, by @neon-nyan - **[Plugin][Fix]** File URL formatting and ensure successful HTTP response in plugin, by @Cryotechnic - **[Sophon][Fix]** Excessive File Package Size on Preload, by @Cryotechnic - **[Sophon][Fix]** Incorrect state display based on preload status, by @Cryotechnic - **[Imp]** Update WindowsAppSDK from v1.8 to v2.0 build - **[Imp]** [Deprecating x86-64-v2 compile target](9a60396), by @neon-nyan As per this release, we are going to set target build to x86-64-v4 or native. This means, the ILC could possibly support latest intrinsics like AVX2 and AVX512, allowing some code to run better due to wide vectorization. Some static libraries which utilizes BMI and AVX intrinsics (like ZStandard library) might not run properly on an old machine without AVX or BMI intrinsics support. - **[Imp]** Localization updates, by localizers 🥳 - de-DE - German (Progress: 99%) - es-419 - Spanish (Latin America)(Progress: 99%) - fr-FR - French (Progress: 98%) - id-ID - Bahasa Indonesia (Progress: 100%) - it-IT - Italian (Progress: 44%) - ja-JP - Japanese (Progress: 99%) - ko-KR - Korean (Progress: 90%) - nl-NL - Dutch (Progress: 99%) - pl-PL - Polish (Progress: 55%) - pt-BR - Portuguese (Brazil)(Progress: 72%) - pt-PT - Portuguese (Portugal)(Progress: 65%) - ru-RU - Russian (Progress: 75%) - th-TH - Thai (Progress: 94%) - uk-UA - Ukrainian (Progress: 84%) - zh-CN - Chinese Simplified (Progress: 100%) - zh-TW - Chinese Traditional (Progress: 60%) **Full Changelog**: CL-v1.84.1-pre...CL-v1.84.2-pre # Code Signing Policy > Free code signing provided by [SignPath.io], certificate by [SignPath Foundation] - This program will not transfer any information to other networked systems. - Read our full [**Privacy Policy**](https://github.com/CollapseLauncher/Collapse/blob/main/PRIVACY.md) - Also read our [**Third Party Notices**](https://github.com/CollapseLauncher/Collapse/blob/main/THIRD_PARTY_NOTICES.md) for license used by third party libraries that we use. [SignPath Foundation]:https://signpath.org [SignPath.io]:https://signpath.io
2 parents 36b58bb + 88dd306 commit 7bdcefe

100 files changed

Lines changed: 2024 additions & 715 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ If you wish to add new language that isn't yet listed in the Transifex project,
1515

1616
## Tools Needed
1717
Below is a list of tools needed to contribute to this project:
18-
1. **Visual Studio 2022 (Any Edition - latest version)** or **JetBrains Rider (Any Edition - latest version)**
18+
1. **Visual Studio 2026 (Any Edition - latest version)** or **JetBrains Rider (Any Edition - latest version)**
1919
- Select .NET desktop development component
2020
2. **Windows SDK (10.0.26100.0 ONLY)** via Visual Studio Installer
21-
3. .NET 9 SDK: [**(9.0.4 or later)**](https://dotnet.microsoft.com/en-us/download/dotnet/9.0)
21+
3. .NET 10 SDK: [**(10.0.5 or later)**](https://dotnet.microsoft.com/en-us/download/dotnet/10.0)
2222

2323
> **Note**:
2424
> Make sure to always use the latest version of Visual Studio or Rider in order to be able to open the project.

CollapseLauncher.slnx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,6 @@
6969
<BuildType Solution="Publish|*" Project="Release" />
7070
<Platform Project="x64" />
7171
</Project>
72-
<Project Path="Hi3Helper.SourceGen/Hi3Helper.SourceGen.csproj">
73-
<BuildType Solution="Publish|*" Project="Release" />
74-
</Project>
7572
<Project Path="Hi3Helper.TaskScheduler/Hi3Helper.TaskScheduler.csproj">
7673
<BuildType Solution="Publish|*" Project="Release" />
7774
<Platform Project="x64" />

CollapseLauncher/Classes/Extension/UIElementExtensions.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,16 @@ internal static T BindNavigationViewItemText<T>(this T element, object? localeOb
5454
element.BindTooltipToLocale(localeObjBinding, localePropertyName);
5555
}
5656

57-
internal static T BindTooltipToLocale<T>(this T element, object? localeObjBinding, string localePropertyName)
57+
internal static T BindTooltipToLocale<T>(this T element, object? localeObjBinding, string localePropertyName, IValueConverter? converter = null, object? converterParameter = null)
5858
where T : DependencyObject
5959
{
6060
TextBlock tooltipTextBlock = new();
6161
tooltipTextBlock.BindProperty(TextBlock.TextProperty,
6262
localeObjBinding,
6363
localePropertyName,
64-
sourceTrigger: UpdateSourceTrigger.PropertyChanged);
64+
sourceTrigger: UpdateSourceTrigger.PropertyChanged,
65+
converter: converter,
66+
converterParameter: converterParameter);
6567

6668
ToolTipService.SetToolTip(element, tooltipTextBlock);
6769
return element;

CollapseLauncher/Classes/GameManagement/ImageBackground/ImageBackgroundManager.CodecDetect.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public partial class ImageBackgroundManager
1616
{
1717
#region Codec Checks
1818

19-
private async Task<(bool IsSupported, bool IsVideo)> CheckCodecOrSpawnDialog(Uri? fileUri)
19+
private async ValueTask<(bool IsSupported, bool IsVideo)> CheckCodecOrSpawnDialog(Uri? fileUri)
2020
{
2121
// -- Cancel if null
2222
if (fileUri == null)

CollapseLauncher/Classes/GameManagement/ImageBackground/ImageBackgroundManager.Control.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,18 @@ public void Play(bool isUserRequest = true)
5252
{
5353
CurrentIsEnableBackgroundAutoPlay = true;
5454
}
55+
56+
// Alter to load static image if it has one instead of pausing.
57+
LayeredImageBackgroundContext? context = CurrentSelectedBackgroundContext;
58+
bool hasStaticImage = !string.IsNullOrEmpty(context?.BackgroundImageStaticPath);
59+
if (isUserRequest && hasStaticImage && context != null)
60+
{
61+
LoadImageAtIndex(CurrentSelectedBackgroundIndex, false, CancellationToken.None);
62+
}
5563

5664
// Force to restore autoplay status to true.
5765
CurrentBackgroundElement?.SetValue(LayeredBackgroundImage.IsVideoAutoplayProperty, true);
58-
66+
5967
Interlocked.Exchange(ref _isPausedByUser, false);
6068
CurrentBackgroundElement?.Play();
6169
}
@@ -67,6 +75,15 @@ public void Pause(bool isUserRequest = true)
6775
Interlocked.Exchange(ref _isPausedByUser, true);
6876
CurrentIsEnableBackgroundAutoPlay = false;
6977
}
78+
79+
// Alter to load static image if it has one instead of pausing.
80+
LayeredImageBackgroundContext? context = CurrentSelectedBackgroundContext;
81+
bool hasStaticImage = !string.IsNullOrEmpty(context?.BackgroundImageStaticPath);
82+
if (isUserRequest && hasStaticImage && context != null)
83+
{
84+
LoadImageAtIndex(CurrentSelectedBackgroundIndex, true, CancellationToken.None);
85+
return;
86+
}
7087

7188
CurrentBackgroundElement?.Pause();
7289
}

CollapseLauncher/Classes/GameManagement/ImageBackground/ImageBackgroundManager.FFmpeg.cs

Lines changed: 113 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
using CollapseLauncher.Helper;
2+
using CollapseLauncher.Helper.FFmpegPInvoke;
23
using CollapseLauncher.Helper.StreamUtility;
4+
using FFmpegInteropX;
35
using Hi3Helper;
46
using Hi3Helper.Shared.Region;
57
using System;
68
using System.Collections;
79
using System.Diagnostics.CodeAnalysis;
810
using System.IO;
11+
using System.Linq;
912
using System.Runtime.CompilerServices;
1013
// ReSharper disable StringLiteralTypo
1114
// ReSharper disable IdentifierTypo
@@ -15,26 +18,51 @@
1518

1619
namespace CollapseLauncher.GameManagement.ImageBackground;
1720

18-
#region File Exclusive Fields
19-
file static class Fields
20-
{
21-
public const string DllNameAvcodec = "avcodec-61.dll";
22-
public const string DllNameAvdevice = "avdevice-61.dll";
23-
public const string DllNameAvfilter = "avfilter-10.dll";
24-
public const string DllNameAvformat = "avformat-61.dll";
25-
public const string DllNameAvutil = "avutil-59.dll";
26-
public const string DllNamePostproc = "postproc-58.dll";
27-
public const string DllNameSwresample = "swresample-5.dll";
28-
public const string DllNameSwscale = "swscale-8.dll";
29-
}
30-
#endregion
31-
3221
public partial class ImageBackgroundManager
3322
{
3423
#region Shared/Static Properties and Fields
3524

36-
private const string GlobalIsUseFFmpegConfigKey = "GlobalIsUseFFmpeg";
37-
private const string GlobalFFmpegCustomPathConfigKey = "GlobalFFmpegCustomPath";
25+
private const string GlobalIsUseFFmpegConfigKey = "GlobalIsUseFFmpeg";
26+
private const string GlobalFFmpegVersionToUseConfigKey = "GlobalFFmpegVersionToUse";
27+
private const string GlobalFFmpegCustomPathConfigKey = "GlobalFFmpegCustomPath";
28+
private const string GlobalFFmpegDecodingModeConfigKey = "GlobalFFmpegDecodingMode";
29+
30+
public VideoDecoderMode[] AvailableFFmpegDecodingModes => field ??= Enum.GetValues<VideoDecoderMode>();
31+
32+
public int GlobalFFmpegVersionToUse
33+
{
34+
get
35+
{
36+
int version = LauncherConfig.GetAppConfigValue(GlobalFFmpegVersionToUseConfigKey);
37+
return FFmpegPInvoke.FFmpegVersionLibNames.ContainsKey(version) ?
38+
version :
39+
FFmpegPInvoke.FFmpegVersionLibNames.Keys.FirstOrDefault();
40+
}
41+
set
42+
{
43+
if (!FFmpegPInvoke.FFmpegVersionLibNames.ContainsKey(value))
44+
{
45+
return;
46+
}
47+
48+
LauncherConfig.SetAndSaveConfigValue(GlobalFFmpegVersionToUseConfigKey, value);
49+
OnPropertyChanged();
50+
OnPropertyChanged(nameof(GlobalFFmpegLibraryNames)); // Notify FFmpeg library names update too.
51+
}
52+
}
53+
54+
public FFmpegPInvoke.FFmpegLibraryNames GlobalFFmpegLibraryNames
55+
{
56+
get
57+
{
58+
if (FFmpegPInvoke.FFmpegVersionLibNames.TryGetValue(GlobalFFmpegVersionToUse, out var names))
59+
{
60+
return names;
61+
}
62+
63+
return FFmpegPInvoke.FFmpegVersionLibNames.Values.FirstOrDefault();
64+
}
65+
}
3866

3967
public bool GlobalIsUseFFmpeg
4068
{
@@ -56,7 +84,7 @@ public string? GlobalCustomFFmpegPath
5684
}
5785
}
5886

59-
public bool GlobalIsFFmpegAvailable => IsFFmpegAvailable(Directory.GetCurrentDirectory(), out _);
87+
public bool GlobalIsFFmpegAvailable => IsFFmpegAvailable(Directory.GetCurrentDirectory(), GlobalFFmpegLibraryNames, out _);
6088

6189
public bool GlobalIsFFmpegCurrentlyUsed
6290
{
@@ -68,6 +96,31 @@ public bool GlobalIsFFmpegCurrentlyUsed
6896
}
6997
}
7098

99+
public VideoDecoderMode GlobalFFmpegDecodingMode
100+
{
101+
get
102+
{
103+
string? value = LauncherConfig.GetAppConfigValue(GlobalFFmpegDecodingModeConfigKey);
104+
if (Enum.TryParse<VideoDecoderMode>(value, out var result))
105+
{
106+
return result;
107+
}
108+
109+
return default;
110+
}
111+
set
112+
{
113+
if (!Enum.IsDefined(value))
114+
{
115+
value = default;
116+
}
117+
118+
string valueStr = value.ToString();
119+
LauncherConfig.SetAndSaveConfigValue(GlobalFFmpegDecodingModeConfigKey, valueStr);
120+
OnPropertyChanged();
121+
}
122+
}
123+
71124
#endregion
72125

73126
public void RefreshFFmpegBinding()
@@ -89,8 +142,10 @@ public bool TryRelinkFFmpegPath()
89142
return false;
90143
}
91144

145+
var names = GlobalFFmpegLibraryNames;
146+
92147
string curDir = Directory.GetCurrentDirectory();
93-
bool isFFmpegAvailable = IsFFmpegAvailable(curDir, out exception);
148+
bool isFFmpegAvailable = IsFFmpegAvailable(curDir, names, out exception);
94149
string? customFFmpegDirPath = GlobalCustomFFmpegPath;
95150

96151
if (isFFmpegAvailable)
@@ -100,16 +155,16 @@ public bool TryRelinkFFmpegPath()
100155

101156
// -- 1. Check from custom path first. If it exists, then pass.
102157
if (!string.IsNullOrEmpty(customFFmpegDirPath) &&
103-
IsFFmpegAvailable(customFFmpegDirPath, out exception) &&
104-
TryLinkFFmpegLibrary(customFFmpegDirPath, curDir, out exception))
158+
IsFFmpegAvailable(customFFmpegDirPath, names, out exception) &&
159+
TryLinkFFmpegLibrary(customFFmpegDirPath, curDir, names, out exception))
105160
{
106161
return result = true;
107162
}
108163

109164
// -- 2. Find one from environment variables. If it exists, then pass.
110165
// Otherwise, return false.
111-
return result = TryFindFFmpegInstallFromEnvVar(out string? envVarPath, out exception) &&
112-
TryLinkFFmpegLibrary(envVarPath, curDir, out exception);
166+
return result = TryFindFFmpegInstallFromEnvVar(names, out string ? envVarPath, out exception) &&
167+
TryLinkFFmpegLibrary(envVarPath, curDir, names, out exception);
113168
}
114169
finally
115170
{
@@ -122,7 +177,7 @@ public bool TryRelinkFFmpegPath()
122177
}
123178
}
124179

125-
internal bool TryFindFFmpegInstallFromEnvVar([NotNullWhen(true)] out string? path, out Exception? exception)
180+
internal bool TryFindFFmpegInstallFromEnvVar(FFmpegPInvoke.FFmpegLibraryNames libraries, [NotNullWhen(true)] out string? path, out Exception? exception)
126181
{
127182
return FindIn(EnvironmentVariableTarget.User, out path, out exception) ||
128183
FindIn(EnvironmentVariableTarget.Machine, out path, out exception);
@@ -152,7 +207,7 @@ bool FindIn(EnvironmentVariableTarget target, [NotNullWhen(true)] out string? in
152207
string thisPath = envVarPath.ToString();
153208

154209
if (!Path.IsPathFullyQualified(thisPath) ||
155-
!IsFFmpegAvailable(thisPath, out exception)) continue;
210+
!IsFFmpegAvailable(thisPath, libraries, out exception)) continue;
156211

157212
innerPath = thisPath;
158213
GlobalCustomFFmpegPath = thisPath; // Set as custom path
@@ -165,6 +220,7 @@ bool FindIn(EnvironmentVariableTarget target, [NotNullWhen(true)] out string? in
165220
}
166221

167222
internal static bool IsFFmpegAvailable(string? checkOnDirectory,
223+
FFmpegPInvoke.FFmpegLibraryNames libraries,
168224
[NotNullWhen(false)]
169225
out Exception? exception)
170226
{
@@ -176,13 +232,13 @@ internal static bool IsFFmpegAvailable(string? checkOnDirectory,
176232

177233
checkOnDirectory = FileUtility.GetFullyQualifiedPath(checkOnDirectory);
178234

179-
string dllPathAvcodec = Path.Combine(checkOnDirectory, Fields.DllNameAvcodec);
180-
string dllPathAvdevice = Path.Combine(checkOnDirectory, Fields.DllNameAvdevice);
181-
string dllPathAvfilter = Path.Combine(checkOnDirectory, Fields.DllNameAvfilter);
182-
string dllPathAvformat = Path.Combine(checkOnDirectory, Fields.DllNameAvformat);
183-
string dllPathAvutil = Path.Combine(checkOnDirectory, Fields.DllNameAvutil);
184-
string dllPathSwresample = Path.Combine(checkOnDirectory, Fields.DllNameSwresample);
185-
string dllPathSwscale = Path.Combine(checkOnDirectory, Fields.DllNameSwscale);
235+
string dllPathAvcodec = Path.Combine(checkOnDirectory, libraries.Codec);
236+
string dllPathAvdevice = Path.Combine(checkOnDirectory, libraries.Device);
237+
string dllPathAvfilter = Path.Combine(checkOnDirectory, libraries.Filter);
238+
string dllPathAvformat = Path.Combine(checkOnDirectory, libraries.Format);
239+
string dllPathAvutil = Path.Combine(checkOnDirectory, libraries.Util);
240+
string dllPathSwresample = Path.Combine(checkOnDirectory, libraries.Resample);
241+
string dllPathSwscale = Path.Combine(checkOnDirectory, libraries.Scale);
186242

187243
return FileUtility.IsFileExistOrSymbolicLinkResolved(dllPathAvcodec, out _, out exception) &&
188244
FileUtility.IsFileExistOrSymbolicLinkResolved(dllPathAvdevice, out _, out exception) &&
@@ -193,29 +249,32 @@ internal static bool IsFFmpegAvailable(string? checkOnDirectory,
193249
FileUtility.IsFileExistOrSymbolicLinkResolved(dllPathSwscale, out _, out exception);
194250
}
195251

196-
internal static string[] GetFFmpegRequiredDllFilenames() =>
197-
[
198-
Fields.DllNameAvcodec,
199-
Fields.DllNameAvdevice,
200-
Fields.DllNameAvfilter,
201-
Fields.DllNameAvformat,
202-
Fields.DllNameAvutil,
203-
Fields.DllNameSwresample,
204-
Fields.DllNameSwscale
205-
];
206-
207-
internal static string? FindFFmpegInstallFolder(string checkOnDirectory)
252+
internal static string[] GetFFmpegRequiredDllFilenames()
253+
{
254+
var names = Shared.GlobalFFmpegLibraryNames;
255+
return [
256+
names.Codec,
257+
names.Device,
258+
names.Filter,
259+
names.Format,
260+
names.Util,
261+
names.Resample,
262+
names.Scale
263+
];
264+
}
265+
266+
internal static string? FindFFmpegInstallFolder(string checkOnDirectory, FFmpegPInvoke.FFmpegLibraryNames libraries)
208267
{
209268
try
210269
{
211-
if (IsFFmpegAvailable(checkOnDirectory, out _))
270+
if (IsFFmpegAvailable(checkOnDirectory, libraries, out _))
212271
{
213272
return checkOnDirectory;
214273
}
215274

216275
foreach (string dirPath in FileUtility.EnumerateDirectoryRecursive(checkOnDirectory))
217276
{
218-
if (IsFFmpegAvailable(dirPath, out _))
277+
if (IsFFmpegAvailable(dirPath, libraries, out _))
219278
{
220279
return dirPath;
221280
}
@@ -232,6 +291,7 @@ internal static string[] GetFFmpegRequiredDllFilenames() =>
232291
public static bool TryLinkFFmpegLibrary(
233292
string? sourceDir,
234293
string? targetDir,
294+
FFmpegPInvoke.FFmpegLibraryNames libraries,
235295
[NotNullWhen(false)]
236296
out Exception? exception)
237297
{
@@ -251,14 +311,14 @@ public static bool TryLinkFFmpegLibrary(
251311
return false;
252312
}
253313

254-
string dllPathAvcodec = Path.Combine(sourceDir, Fields.DllNameAvcodec);
255-
string dllPathAvdevice = Path.Combine(sourceDir, Fields.DllNameAvdevice);
256-
string dllPathAvfilter = Path.Combine(sourceDir, Fields.DllNameAvfilter);
257-
string dllPathAvformat = Path.Combine(sourceDir, Fields.DllNameAvformat);
258-
string dllPathAvutil = Path.Combine(sourceDir, Fields.DllNameAvutil);
259-
string dllPathPostproc = Path.Combine(sourceDir, Fields.DllNamePostproc);
260-
string dllPathSwresample = Path.Combine(sourceDir, Fields.DllNameSwresample);
261-
string dllPathSwscale = Path.Combine(sourceDir, Fields.DllNameSwscale);
314+
string dllPathAvcodec = Path.Combine(sourceDir, libraries.Codec);
315+
string dllPathAvdevice = Path.Combine(sourceDir, libraries.Device);
316+
string dllPathAvfilter = Path.Combine(sourceDir, libraries.Filter);
317+
string dllPathAvformat = Path.Combine(sourceDir, libraries.Format);
318+
string dllPathAvutil = Path.Combine(sourceDir, libraries.Util);
319+
string dllPathPostproc = Path.Combine(sourceDir, libraries.PostProc);
320+
string dllPathSwresample = Path.Combine(sourceDir, libraries.Resample);
321+
string dllPathSwscale = Path.Combine(sourceDir, libraries.Scale);
262322

263323
bool result =
264324
CreateSymbolLink(dllPathAvcodec, targetDir, out exception) &&

0 commit comments

Comments
 (0)