Compare commits
17 Commits
Canary-1.2
...
Canary-1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1dee50275 | ||
|
|
c2ae49eb47 | ||
|
|
47c71966d0 | ||
|
|
f9e8f4bc29 | ||
|
|
7694c8c046 | ||
|
|
0dd789e8a5 | ||
|
|
4e0aafd005 | ||
|
|
c5091f499e | ||
|
|
41c8fd8194 | ||
|
|
d4a7ee25ea | ||
|
|
3141c560fb | ||
|
|
de341b285b | ||
|
|
cc95e80ee9 | ||
|
|
d75ce52bd4 | ||
|
|
4a4ea557de | ||
|
|
33f42adb11 | ||
|
|
cca429d46a |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -129,11 +129,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
global-json-file: global.json
|
global-json-file: global.json
|
||||||
|
|
||||||
- name: Setup LLVM 14
|
- name: Setup LLVM 17
|
||||||
run: |
|
run: |
|
||||||
wget https://apt.llvm.org/llvm.sh
|
wget https://apt.llvm.org/llvm.sh
|
||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
sudo ./llvm.sh 14
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
- name: Install rcodesign
|
- name: Install rcodesign
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
4
.github/workflows/canary.yml
vendored
4
.github/workflows/canary.yml
vendored
@@ -210,11 +210,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
global-json-file: global.json
|
global-json-file: global.json
|
||||||
|
|
||||||
- name: Setup LLVM 15
|
- name: Setup LLVM 17
|
||||||
run: |
|
run: |
|
||||||
wget https://apt.llvm.org/llvm.sh
|
wget https://apt.llvm.org/llvm.sh
|
||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
sudo ./llvm.sh 15
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
- name: Install rcodesign
|
- name: Install rcodesign
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
@@ -3,16 +3,6 @@ name: Release job
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs: {}
|
inputs: {}
|
||||||
push:
|
|
||||||
branches: [ release ]
|
|
||||||
paths-ignore:
|
|
||||||
- '.github/**'
|
|
||||||
- 'docs/**'
|
|
||||||
- 'assets/**'
|
|
||||||
- '*.yml'
|
|
||||||
- '*.json'
|
|
||||||
- '*.config'
|
|
||||||
- '*.md'
|
|
||||||
|
|
||||||
concurrency: release
|
concurrency: release
|
||||||
|
|
||||||
@@ -201,11 +191,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
global-json-file: global.json
|
global-json-file: global.json
|
||||||
|
|
||||||
- name: Setup LLVM 15
|
- name: Setup LLVM 17
|
||||||
run: |
|
run: |
|
||||||
wget https://apt.llvm.org/llvm.sh
|
wget https://apt.llvm.org/llvm.sh
|
||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
sudo ./llvm.sh 15
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
- name: Install rcodesign
|
- name: Install rcodesign
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
<PackageVersion Include="Gommon" Version="2.7.0.1" />
|
<PackageVersion Include="Gommon" Version="2.7.0.2" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ if platform.system() == "Darwin":
|
|||||||
else:
|
else:
|
||||||
OTOOL = shutil.which("llvm-otool")
|
OTOOL = shutil.which("llvm-otool")
|
||||||
if OTOOL is None:
|
if OTOOL is None:
|
||||||
for llvm_ver in [15, 14, 13]:
|
for llvm_ver in [17, 16, 15, 14, 13]:
|
||||||
otool_path = shutil.which(f"llvm-otool-{llvm_ver}")
|
otool_path = shutil.which(f"llvm-otool-{llvm_ver}")
|
||||||
if otool_path is not None:
|
if otool_path is not None:
|
||||||
OTOOL = otool_path
|
OTOOL = otool_path
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ else:
|
|||||||
LIPO = shutil.which("llvm-lipo")
|
LIPO = shutil.which("llvm-lipo")
|
||||||
|
|
||||||
if LIPO is None:
|
if LIPO is None:
|
||||||
for llvm_ver in [15, 14, 13]:
|
for llvm_ver in [17, 16, 15, 14, 13]:
|
||||||
lipo_path = shutil.which(f"llvm-lipo-{llvm_ver}")
|
lipo_path = shutil.which(f"llvm-lipo-{llvm_ver}")
|
||||||
if lipo_path is not None:
|
if lipo_path is not None:
|
||||||
LIPO = lipo_path
|
LIPO = lipo_path
|
||||||
|
|||||||
@@ -67,11 +67,11 @@ python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_APP_
|
|||||||
|
|
||||||
if ! [ -x "$(command -v lipo)" ];
|
if ! [ -x "$(command -v lipo)" ];
|
||||||
then
|
then
|
||||||
if ! [ -x "$(command -v llvm-lipo-14)" ];
|
if ! [ -x "$(command -v llvm-lipo-17)" ];
|
||||||
then
|
then
|
||||||
LIPO=llvm-lipo
|
LIPO=llvm-lipo
|
||||||
else
|
else
|
||||||
LIPO=llvm-lipo-14
|
LIPO=llvm-lipo-17
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
LIPO=lipo
|
LIPO=lipo
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTP
|
|||||||
|
|
||||||
if ! [ -x "$(command -v lipo)" ];
|
if ! [ -x "$(command -v lipo)" ];
|
||||||
then
|
then
|
||||||
if ! [ -x "$(command -v llvm-lipo-14)" ];
|
if ! [ -x "$(command -v llvm-lipo-17)" ];
|
||||||
then
|
then
|
||||||
LIPO=llvm-lipo
|
LIPO=llvm-lipo
|
||||||
else
|
else
|
||||||
LIPO=llvm-lipo-14
|
LIPO=llvm-lipo-17
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
LIPO=lipo
|
LIPO=lipo
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1243,7 +1243,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "问答与指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4018,7 +4018,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "与 PC 日期和时间重新同步",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -14193,7 +14193,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Ryujinx — це емулятор для Nintendo Switch™.\nОтримуйте всі останні новини в нашому Discord.\nРозробники, які хочуть зробити внесок, можуть дізнатися більше на нашому GitHub або в Discord.",
|
"uk_UA": "Ryujinx — це емулятор для Nintendo Switch™.\nОтримуйте всі останні новини в нашому Discord.\nРозробники, які хочуть зробити внесок, можуть дізнатися більше на нашому GitHub або в Discord.",
|
||||||
"zh_CN": "",
|
"zh_CN": "Ryujinx 是一个 Nintendo Switch™ 模拟器。\n有兴趣做出贡献的开发者可以在我们的 GitHub 或 Discord 上了解更多信息。\n",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -17818,7 +17818,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "档案对话框",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19543,7 +19543,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Необрізаних {0} тайтл(ів)...",
|
"uk_UA": "Необрізаних {0} тайтл(ів)...",
|
||||||
"zh_CN": "",
|
"zh_CN": "正在精简 {0} 个游戏",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19718,7 +19718,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Заголовок",
|
"uk_UA": "Заголовок",
|
||||||
"zh_CN": "",
|
"zh_CN": "标题",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19743,7 +19743,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Економія місця",
|
"uk_UA": "Економія місця",
|
||||||
"zh_CN": "",
|
"zh_CN": "节省空间",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -19793,7 +19793,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Зшивання",
|
"uk_UA": "Зшивання",
|
||||||
"zh_CN": "",
|
"zh_CN": "取消精简",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22597,6 +22597,31 @@
|
|||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "CompatibilityListLastUpdated",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Last updated: {0}",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "最后更新于: {0}",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "CompatibilityListWarning",
|
"ID": "CompatibilityListWarning",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
@@ -22618,7 +22643,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "此兼容性列表可能包含过时的条目。\n不要只测试 \"进入游戏\" 状态的游戏。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22643,7 +22668,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "正在搜索兼容性条目...",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22668,7 +22693,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "打开兼容性列表",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22693,7 +22718,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "仅显示拥有的游戏",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22718,7 +22743,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "可游玩",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22743,7 +22768,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "进入游戏",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22768,7 +22793,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "菜单",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22793,7 +22818,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "启动",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22818,7 +22843,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "什么都没有",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,12 +133,13 @@
|
|||||||
Spacing="5">
|
Spacing="5">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Text="{Binding TimePlayedString}"
|
Text="{Binding LastPlayedString}"
|
||||||
TextAlignment="End"
|
TextAlignment="End"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Text="{Binding LastPlayedString}"
|
Text="{Binding TimePlayedString}"
|
||||||
|
IsVisible="{Binding HasPlayedPreviously}"
|
||||||
TextAlignment="End"
|
TextAlignment="End"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
|
|||||||
@@ -1,152 +1,53 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Models.Input
|
namespace Ryujinx.Ava.UI.Models.Input
|
||||||
{
|
{
|
||||||
public class HotkeyConfig : BaseModel
|
public partial class HotkeyConfig : BaseModel
|
||||||
{
|
{
|
||||||
private Key _toggleVSyncMode;
|
[ObservableProperty] private Key _toggleVSyncMode;
|
||||||
public Key ToggleVSyncMode
|
|
||||||
{
|
|
||||||
get => _toggleVSyncMode;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_toggleVSyncMode = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _screenshot;
|
[ObservableProperty] private Key _screenshot;
|
||||||
public Key Screenshot
|
|
||||||
{
|
|
||||||
get => _screenshot;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_screenshot = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _showUI;
|
[ObservableProperty] private Key _showUI;
|
||||||
public Key ShowUI
|
|
||||||
{
|
|
||||||
get => _showUI;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_showUI = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _pause;
|
[ObservableProperty] private Key _pause;
|
||||||
public Key Pause
|
|
||||||
{
|
|
||||||
get => _pause;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_pause = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _toggleMute;
|
[ObservableProperty] private Key _toggleMute;
|
||||||
public Key ToggleMute
|
|
||||||
{
|
|
||||||
get => _toggleMute;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_toggleMute = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _resScaleUp;
|
[ObservableProperty] private Key _resScaleUp;
|
||||||
public Key ResScaleUp
|
|
||||||
{
|
|
||||||
get => _resScaleUp;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_resScaleUp = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _resScaleDown;
|
[ObservableProperty] private Key _resScaleDown;
|
||||||
public Key ResScaleDown
|
|
||||||
{
|
|
||||||
get => _resScaleDown;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_resScaleDown = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _volumeUp;
|
[ObservableProperty] private Key _volumeUp;
|
||||||
public Key VolumeUp
|
|
||||||
{
|
|
||||||
get => _volumeUp;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_volumeUp = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _volumeDown;
|
[ObservableProperty] private Key _volumeDown;
|
||||||
public Key VolumeDown
|
|
||||||
{
|
|
||||||
get => _volumeDown;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_volumeDown = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _customVSyncIntervalIncrement;
|
[ObservableProperty] private Key _customVSyncIntervalIncrement;
|
||||||
public Key CustomVSyncIntervalIncrement
|
|
||||||
{
|
|
||||||
get => _customVSyncIntervalIncrement;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_customVSyncIntervalIncrement = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Key _customVSyncIntervalDecrement;
|
[ObservableProperty] private Key _customVSyncIntervalDecrement;
|
||||||
public Key CustomVSyncIntervalDecrement
|
|
||||||
{
|
|
||||||
get => _customVSyncIntervalDecrement;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_customVSyncIntervalDecrement = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public HotkeyConfig(KeyboardHotkeys config)
|
public HotkeyConfig(KeyboardHotkeys config)
|
||||||
{
|
{
|
||||||
if (config != null)
|
if (config == null)
|
||||||
{
|
return;
|
||||||
ToggleVSyncMode = config.ToggleVSyncMode;
|
|
||||||
Screenshot = config.Screenshot;
|
ToggleVSyncMode = config.ToggleVSyncMode;
|
||||||
ShowUI = config.ShowUI;
|
Screenshot = config.Screenshot;
|
||||||
Pause = config.Pause;
|
ShowUI = config.ShowUI;
|
||||||
ToggleMute = config.ToggleMute;
|
Pause = config.Pause;
|
||||||
ResScaleUp = config.ResScaleUp;
|
ToggleMute = config.ToggleMute;
|
||||||
ResScaleDown = config.ResScaleDown;
|
ResScaleUp = config.ResScaleUp;
|
||||||
VolumeUp = config.VolumeUp;
|
ResScaleDown = config.ResScaleDown;
|
||||||
VolumeDown = config.VolumeDown;
|
VolumeUp = config.VolumeUp;
|
||||||
CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement;
|
VolumeDown = config.VolumeDown;
|
||||||
CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement;
|
CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement;
|
||||||
}
|
CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardHotkeys GetConfig()
|
public KeyboardHotkeys GetConfig() =>
|
||||||
{
|
new()
|
||||||
var config = new KeyboardHotkeys
|
|
||||||
{
|
{
|
||||||
ToggleVSyncMode = ToggleVSyncMode,
|
ToggleVSyncMode = ToggleVSyncMode,
|
||||||
Screenshot = Screenshot,
|
Screenshot = Screenshot,
|
||||||
@@ -160,8 +61,5 @@ namespace Ryujinx.Ava.UI.Models.Input
|
|||||||
CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement,
|
CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement,
|
||||||
CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement,
|
CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement,
|
||||||
};
|
};
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,13 @@
|
|||||||
using Avalonia.Svg.Skia;
|
using Avalonia.Svg.Skia;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Ryujinx.Ava.UI.Models.Input;
|
using Ryujinx.Ava.UI.Models.Input;
|
||||||
using Ryujinx.Ava.UI.Views.Input;
|
using Ryujinx.Ava.UI.Views.Input;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class ControllerInputViewModel : BaseModel
|
public partial class ControllerInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private GamepadInputConfig _config;
|
[ObservableProperty] private GamepadInputConfig _config;
|
||||||
public GamepadInputConfig Config
|
|
||||||
{
|
|
||||||
get => _config;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_config = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _isLeft;
|
private bool _isLeft;
|
||||||
public bool IsLeft
|
public bool IsLeft
|
||||||
@@ -43,16 +35,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
|
|
||||||
public bool HasSides => IsLeft ^ IsRight;
|
public bool HasSides => IsLeft ^ IsRight;
|
||||||
|
|
||||||
private SvgImage _image;
|
[ObservableProperty] private SvgImage _image;
|
||||||
public SvgImage Image
|
|
||||||
{
|
|
||||||
get => _image;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_image = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly InputViewModel ParentModel;
|
public readonly InputViewModel ParentModel;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
|
||||||
using Avalonia.Svg.Skia;
|
using Avalonia.Svg.Skia;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Input;
|
using Ryujinx.Ava.Input;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
@@ -32,7 +31,7 @@ using Key = Ryujinx.Common.Configuration.Hid.Key;
|
|||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class InputViewModel : BaseModel, IDisposable
|
public partial class InputViewModel : BaseModel, IDisposable
|
||||||
{
|
{
|
||||||
private const string Disabled = "disabled";
|
private const string Disabled = "disabled";
|
||||||
private const string ProControllerResource = "Ryujinx/Assets/Icons/Controller_ProCon.svg";
|
private const string ProControllerResource = "Ryujinx/Assets/Icons/Controller_ProCon.svg";
|
||||||
@@ -48,8 +47,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
private int _controller;
|
private int _controller;
|
||||||
private string _controllerImage;
|
private string _controllerImage;
|
||||||
private int _device;
|
private int _device;
|
||||||
private object _configViewModel;
|
[ObservableProperty] private object _configViewModel;
|
||||||
private string _profileName;
|
[ObservableProperty] private string _profileName;
|
||||||
private bool _isLoaded;
|
private bool _isLoaded;
|
||||||
|
|
||||||
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||||
@@ -73,17 +72,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
public bool IsModified { get; set; }
|
public bool IsModified { get; set; }
|
||||||
public event Action NotifyChangesEvent;
|
public event Action NotifyChangesEvent;
|
||||||
|
|
||||||
public object ConfigViewModel
|
|
||||||
{
|
|
||||||
get => _configViewModel;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_configViewModel = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerIndex PlayerIdChoose
|
public PlayerIndex PlayerIdChoose
|
||||||
{
|
{
|
||||||
get => _playerIdChoose;
|
get => _playerIdChoose;
|
||||||
@@ -200,16 +188,6 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ProfileName
|
|
||||||
{
|
|
||||||
get => _profileName; set
|
|
||||||
{
|
|
||||||
_profileName = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Device
|
public int Device
|
||||||
{
|
{
|
||||||
get => _device;
|
get => _device;
|
||||||
|
|||||||
@@ -1,20 +1,12 @@
|
|||||||
using Avalonia.Svg.Skia;
|
using Avalonia.Svg.Skia;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Ryujinx.Ava.UI.Models.Input;
|
using Ryujinx.Ava.UI.Models.Input;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class KeyboardInputViewModel : BaseModel
|
public partial class KeyboardInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private KeyboardInputConfig _config;
|
[ObservableProperty] private KeyboardInputConfig _config;
|
||||||
public KeyboardInputConfig Config
|
|
||||||
{
|
|
||||||
get => _config;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_config = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _isLeft;
|
private bool _isLeft;
|
||||||
public bool IsLeft
|
public bool IsLeft
|
||||||
@@ -42,16 +34,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
|||||||
|
|
||||||
public bool HasSides => IsLeft ^ IsRight;
|
public bool HasSides => IsLeft ^ IsRight;
|
||||||
|
|
||||||
private SvgImage _image;
|
[ObservableProperty] private SvgImage _image;
|
||||||
public SvgImage Image
|
|
||||||
{
|
|
||||||
get => _image;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_image = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly InputViewModel ParentModel;
|
public readonly InputViewModel ParentModel;
|
||||||
|
|
||||||
|
|||||||
@@ -1,93 +1,23 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class MotionInputViewModel : BaseModel
|
public partial class MotionInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private int _slot;
|
[ObservableProperty] private int _slot;
|
||||||
public int Slot
|
|
||||||
{
|
|
||||||
get => _slot;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_slot = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int _altSlot;
|
[ObservableProperty] private int _altSlot;
|
||||||
public int AltSlot
|
|
||||||
{
|
|
||||||
get => _altSlot;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_altSlot = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string _dsuServerHost;
|
[ObservableProperty] private string _dsuServerHost;
|
||||||
public string DsuServerHost
|
|
||||||
{
|
|
||||||
get => _dsuServerHost;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_dsuServerHost = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int _dsuServerPort;
|
[ObservableProperty] private int _dsuServerPort;
|
||||||
public int DsuServerPort
|
|
||||||
{
|
|
||||||
get => _dsuServerPort;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_dsuServerPort = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _mirrorInput;
|
[ObservableProperty] private bool _mirrorInput;
|
||||||
public bool MirrorInput
|
|
||||||
{
|
|
||||||
get => _mirrorInput;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_mirrorInput = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int _sensitivity;
|
[ObservableProperty] private int _sensitivity;
|
||||||
public int Sensitivity
|
|
||||||
{
|
|
||||||
get => _sensitivity;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_sensitivity = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private double _gryoDeadzone;
|
[ObservableProperty] private double _gyroDeadzone;
|
||||||
public double GyroDeadzone
|
|
||||||
{
|
|
||||||
get => _gryoDeadzone;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_gryoDeadzone = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _enableCemuHookMotion;
|
[ObservableProperty] private bool _enableCemuHookMotion;
|
||||||
public bool EnableCemuHookMotion
|
|
||||||
{
|
|
||||||
get => _enableCemuHookMotion;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_enableCemuHookMotion = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,11 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels.Input
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class RumbleInputViewModel : BaseModel
|
public partial class RumbleInputViewModel : BaseModel
|
||||||
{
|
{
|
||||||
private float _strongRumble;
|
[ObservableProperty] private float _strongRumble;
|
||||||
public float StrongRumble
|
|
||||||
{
|
|
||||||
get => _strongRumble;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_strongRumble = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private float _weakRumble;
|
[ObservableProperty] private float _weakRumble;
|
||||||
public float WeakRumble
|
|
||||||
{
|
|
||||||
get => _weakRumble;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_weakRumble = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -743,7 +743,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
.Sort(GetComparer())
|
.Sort(GetComparer())
|
||||||
#pragma warning disable MVVMTK0034
|
#pragma warning disable MVVMTK0034
|
||||||
.Bind(out _appsObservableList)
|
.Bind(out _appsObservableList)
|
||||||
#pragma warning enable MVVMTK0034
|
#pragma warning restore MVVMTK0034
|
||||||
.AsObservableList();
|
.AsObservableList();
|
||||||
|
|
||||||
OnPropertyChanged(nameof(AppsObservableList));
|
OnPropertyChanged(nameof(AppsObservableList));
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplicationLibrary_LdnGameDataReceived(object sender, LdnGameDataReceivedEventArgs e)
|
private void ApplicationLibrary_LdnGameDataReceived(LdnGameDataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
{
|
{
|
||||||
@@ -408,13 +408,10 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
{
|
{
|
||||||
StatusBarView.VolumeStatus.Click += VolumeStatus_CheckedChanged;
|
StatusBarView.VolumeStatus.Click += VolumeStatus_CheckedChanged;
|
||||||
|
|
||||||
|
ApplicationGrid.DataContext = ApplicationList.DataContext = ViewModel;
|
||||||
|
|
||||||
ApplicationGrid.ApplicationOpened += Application_Opened;
|
ApplicationGrid.ApplicationOpened += Application_Opened;
|
||||||
|
|
||||||
ApplicationGrid.DataContext = ViewModel;
|
|
||||||
|
|
||||||
ApplicationList.ApplicationOpened += Application_Opened;
|
ApplicationList.ApplicationOpened += Application_Opened;
|
||||||
|
|
||||||
ApplicationList.DataContext = ViewModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetWindowSizePosition()
|
private void SetWindowSizePosition()
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input;
|
||||||
using FluentAvalonia.Core;
|
using FluentAvalonia.Core;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
@@ -23,6 +25,11 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Load();
|
Load();
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
this.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Alt));
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SettingsWindow()
|
public SettingsWindow()
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
|
|
||||||
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
|
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
|
||||||
|
|
||||||
|
public bool HasPlayedPreviously => TimePlayedString != string.Empty;
|
||||||
|
|
||||||
public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n");
|
public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n");
|
||||||
|
|
||||||
public string FileSizeString => ValueFormatUtils.FormatFileSize(FileSize);
|
public string FileSizeString => ValueFormatUtils.FormatFileSize(FileSize);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
public const string DefaultLanPlayWebHost = "ryuldnweb.vudjun.com";
|
public const string DefaultLanPlayWebHost = "ryuldnweb.vudjun.com";
|
||||||
public Language DesiredLanguage { get; set; }
|
public Language DesiredLanguage { get; set; }
|
||||||
public event EventHandler<ApplicationCountUpdatedEventArgs> ApplicationCountUpdated;
|
public event EventHandler<ApplicationCountUpdatedEventArgs> ApplicationCountUpdated;
|
||||||
public event EventHandler<LdnGameDataReceivedEventArgs> LdnGameDataReceived;
|
public event Action<LdnGameDataReceivedEventArgs> LdnGameDataReceived;
|
||||||
|
|
||||||
public readonly IObservableCache<ApplicationData, ulong> Applications;
|
public readonly IObservableCache<ApplicationData, ulong> Applications;
|
||||||
public readonly IObservableCache<(TitleUpdateModel TitleUpdate, bool IsSelected), TitleUpdateModel> TitleUpdates;
|
public readonly IObservableCache<(TitleUpdateModel TitleUpdate, bool IsSelected), TitleUpdateModel> TitleUpdates;
|
||||||
@@ -779,7 +779,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
using HttpClient httpClient = new HttpClient();
|
using HttpClient httpClient = new HttpClient();
|
||||||
string ldnGameDataArrayString = await httpClient.GetStringAsync($"https://{ldnWebHost}/api/public_games");
|
string ldnGameDataArrayString = await httpClient.GetStringAsync($"https://{ldnWebHost}/api/public_games");
|
||||||
ldnGameDataArray = JsonHelper.Deserialize(ldnGameDataArrayString, _ldnDataSerializerContext.IEnumerableLdnGameData);
|
ldnGameDataArray = JsonHelper.Deserialize(ldnGameDataArrayString, _ldnDataSerializerContext.IEnumerableLdnGameData);
|
||||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
LdnGameDataReceived?.Invoke(new LdnGameDataReceivedEventArgs
|
||||||
{
|
{
|
||||||
LdnData = ldnGameDataArray
|
LdnData = ldnGameDataArray
|
||||||
});
|
});
|
||||||
@@ -787,7 +787,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Application, $"Failed to fetch the public games JSON from the API. Player and game count in the game list will be unavailable.\n{ex.Message}");
|
Logger.Warning?.Print(LogClass.Application, $"Failed to fetch the public games JSON from the API. Player and game count in the game list will be unavailable.\n{ex.Message}");
|
||||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
LdnGameDataReceived?.Invoke(new LdnGameDataReceivedEventArgs
|
||||||
{
|
{
|
||||||
LdnData = Array.Empty<LdnGameData>()
|
LdnData = Array.Empty<LdnGameData>()
|
||||||
});
|
});
|
||||||
@@ -795,7 +795,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
LdnGameDataReceived?.Invoke(new LdnGameDataReceivedEventArgs
|
||||||
{
|
{
|
||||||
LdnData = Array.Empty<LdnGameData>()
|
LdnData = Array.Empty<LdnGameData>()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
|
using Humanizer;
|
||||||
using nietras.SeparatedValues;
|
using nietras.SeparatedValues;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
@@ -56,7 +57,7 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
? titleIdRow
|
? titleIdRow
|
||||||
: default(Optional<string>);
|
: default(Optional<string>);
|
||||||
|
|
||||||
GameName = ColStr(row[indices.GameName]).Trim().Trim('"');
|
GameName = ColStr(row[indices.GameName]);
|
||||||
|
|
||||||
Labels = ColStr(row[indices.Labels]).Split(';');
|
Labels = ColStr(row[indices.Labels]).Split(';');
|
||||||
Status = ColStr(row[indices.Status]).ToLower() switch
|
Status = ColStr(row[indices.Status]).ToLower() switch
|
||||||
@@ -83,12 +84,14 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
public LocaleKeys? Status { get; }
|
public LocaleKeys? Status { get; }
|
||||||
public DateTime LastUpdated { get; }
|
public DateTime LastUpdated { get; }
|
||||||
|
|
||||||
|
public string LocalizedLastUpdated =>
|
||||||
|
LocaleManager.FormatDynamicValue(LocaleKeys.CompatibilityListLastUpdated, LastUpdated.Humanize());
|
||||||
|
|
||||||
public string LocalizedStatus => LocaleManager.Instance[Status!.Value];
|
public string LocalizedStatus => LocaleManager.Instance[Status!.Value];
|
||||||
public string FormattedTitleId => TitleId
|
public string FormattedTitleId => TitleId
|
||||||
.OrElse(new string(' ', 16));
|
.OrElse(new string(' ', 16));
|
||||||
|
|
||||||
public string FormattedIssueLabels => Labels
|
public string FormattedIssueLabels => Labels
|
||||||
.Where(it => !it.StartsWithIgnoreCase("status"))
|
|
||||||
.Select(FormatLabelName)
|
.Select(FormatLabelName)
|
||||||
.JoinToString(", ");
|
.JoinToString(", ");
|
||||||
|
|
||||||
@@ -97,7 +100,9 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
StringBuilder sb = new("CompatibilityEntry: {");
|
StringBuilder sb = new("CompatibilityEntry: {");
|
||||||
sb.Append($"{nameof(GameName)}=\"{GameName}\", ");
|
sb.Append($"{nameof(GameName)}=\"{GameName}\", ");
|
||||||
sb.Append($"{nameof(TitleId)}={TitleId}, ");
|
sb.Append($"{nameof(TitleId)}={TitleId}, ");
|
||||||
sb.Append($"{nameof(Labels)}=\"{Labels}\", ");
|
sb.Append($"{nameof(Labels)}={
|
||||||
|
Labels.FormatCollection(it => $"\"{it}\"", separator: ", ", prefix: "[", suffix: "]")
|
||||||
|
}, ");
|
||||||
sb.Append($"{nameof(Status)}=\"{Status}\", ");
|
sb.Append($"{nameof(Status)}=\"{Status}\", ");
|
||||||
sb.Append($"{nameof(LastUpdated)}=\"{LastUpdated}\"");
|
sb.Append($"{nameof(LastUpdated)}=\"{LastUpdated}\"");
|
||||||
sb.Append('}');
|
sb.Append('}');
|
||||||
|
|||||||
@@ -44,8 +44,11 @@
|
|||||||
ItemsSource="{Binding CurrentEntries}">
|
ItemsSource="{Binding CurrentEntries}">
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate DataType="{x:Type local:CompatibilityEntry}">
|
<DataTemplate DataType="{x:Type local:CompatibilityEntry}">
|
||||||
<Grid Width="750" ColumnDefinitions="Auto,Auto,Auto,*"
|
<Grid Width="750"
|
||||||
Margin="5">
|
Margin="5"
|
||||||
|
ColumnDefinitions="Auto,Auto,Auto,*"
|
||||||
|
Background="Transparent"
|
||||||
|
ToolTip.Tip="{Binding LocalizedLastUpdated}">
|
||||||
<TextBlock Grid.Column="0"
|
<TextBlock Grid.Column="0"
|
||||||
Text="{Binding GameName}"
|
Text="{Binding GameName}"
|
||||||
Width="320"
|
Width="320"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using Humanizer;
|
||||||
|
using Humanizer.Localisation;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@@ -31,7 +33,7 @@ namespace Ryujinx.Ava.Utilities
|
|||||||
Gigabytes = 9,
|
Gigabytes = 9,
|
||||||
Terabytes = 10,
|
Terabytes = 10,
|
||||||
Petabytes = 11,
|
Petabytes = 11,
|
||||||
Exabytes = 12,
|
Exabytes = 12
|
||||||
}
|
}
|
||||||
|
|
||||||
private const double SizeBase10 = 1000;
|
private const double SizeBase10 = 1000;
|
||||||
@@ -48,22 +50,24 @@ namespace Ryujinx.Ava.Utilities
|
|||||||
public static string FormatTimeSpan(TimeSpan? timeSpan)
|
public static string FormatTimeSpan(TimeSpan? timeSpan)
|
||||||
{
|
{
|
||||||
if (!timeSpan.HasValue || timeSpan.Value.TotalSeconds < 1)
|
if (!timeSpan.HasValue || timeSpan.Value.TotalSeconds < 1)
|
||||||
{
|
return string.Empty;
|
||||||
// Game was never played
|
|
||||||
return TimeSpan.Zero.ToString("c", CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeSpan.Value.TotalDays < 1)
|
if (timeSpan.Value.TotalSeconds < 60)
|
||||||
{
|
return timeSpan.Value.Humanize(1,
|
||||||
// Game was played for less than a day
|
countEmptyUnits: false,
|
||||||
return timeSpan.Value.ToString("c", CultureInfo.InvariantCulture);
|
maxUnit: TimeUnit.Second,
|
||||||
}
|
minUnit: TimeUnit.Second);
|
||||||
|
|
||||||
// Game was played for more than a day
|
if (timeSpan.Value.TotalMinutes < 60)
|
||||||
TimeSpan onlyTime = timeSpan.Value.Subtract(TimeSpan.FromDays(timeSpan.Value.Days));
|
return timeSpan.Value.Humanize(1,
|
||||||
string onlyTimeString = onlyTime.ToString("c", CultureInfo.InvariantCulture);
|
countEmptyUnits: false,
|
||||||
|
maxUnit: TimeUnit.Minute,
|
||||||
|
minUnit: TimeUnit.Minute);
|
||||||
|
|
||||||
return $"{timeSpan.Value.Days}d, {onlyTimeString}";
|
return timeSpan.Value.Humanize(1,
|
||||||
|
countEmptyUnits: false,
|
||||||
|
maxUnit: TimeUnit.Hour,
|
||||||
|
minUnit: TimeUnit.Hour);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user