diff --git a/CUE4Parse b/CUE4Parse index 82c1f94f..2afe7e51 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 82c1f94f607446d02f8b6f559e6fd0124642259c +Subproject commit 2afe7e511319e20491d9e79ab0405b57252838ac diff --git a/FModel/Creator/Utils.cs b/FModel/Creator/Utils.cs index 966d50c4..e3510a4c 100644 --- a/FModel/Creator/Utils.cs +++ b/FModel/Creator/Utils.cs @@ -11,6 +11,7 @@ using CUE4Parse.Utils; using CUE4Parse_Conversion.Textures; using FModel.Framework; using FModel.Services; +using FModel.Settings; using FModel.ViewModels; using SkiaSharp; using SkiaSharp.HarfBuzz; @@ -105,7 +106,7 @@ namespace FModel.Creator public static SKBitmap GetB64Bitmap(string b64) => SKBitmap.Decode(new MemoryStream(Convert.FromBase64String(b64)) {Position = 0}); public static SKBitmap GetBitmap(FSoftObjectPath softObjectPath) => GetBitmap(softObjectPath.AssetPathName.Text); public static SKBitmap GetBitmap(string fullPath) => TryLoadObject(fullPath, out UTexture2D texture) ? GetBitmap(texture) : null; - public static SKBitmap GetBitmap(UTexture2D texture) => texture.IsVirtual ? null : texture.Decode(); + public static SKBitmap GetBitmap(UTexture2D texture) => texture.IsVirtual ? null : texture.Decode(UserSettings.Default.OverridedPlatform); public static SKBitmap GetBitmap(byte[] data) => SKBitmap.Decode(data); public static SKBitmap ResizeWithRatio(this SKBitmap me, double width, double height) diff --git a/FModel/Settings/UserSettings.cs b/FModel/Settings/UserSettings.cs index 28041f15..1fc8393e 100644 --- a/FModel/Settings/UserSettings.cs +++ b/FModel/Settings/UserSettings.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Windows; using System.Windows.Input; +using CUE4Parse.UE4.Assets.Exports.Texture; using CUE4Parse.UE4.Objects.Core.Serialization; using CUE4Parse.UE4.Versions; using CUE4Parse_Conversion.Meshes; @@ -251,6 +252,13 @@ namespace FModel.Settings set => SetProperty(ref _manualGames, value); } + private ETexturePlatform _overridedPlatform = ETexturePlatform.DesktopMobile; + public ETexturePlatform OverridedPlatform + { + get => _overridedPlatform; + set => SetProperty(ref _overridedPlatform, value); + } + private IDictionary _presets = new Dictionary { {FGame.Unknown, Constants._NO_PRESET_TRIGGER}, diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index 05129e35..55914359 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -28,7 +28,6 @@ using CUE4Parse.UE4.Versions; using CUE4Parse.UE4.Wwise; using CUE4Parse_Conversion; using CUE4Parse_Conversion.Sounds; -using CUE4Parse_Conversion.Textures; using EpicManifestParser.Objects; using FModel.Creator; using FModel.Extensions; @@ -72,7 +71,7 @@ namespace FModel.ViewModels public SearchViewModel SearchVm { get; } public TabControlViewModel TabControl { get; } public int LocalizedResourcesCount { get; set; } - public bool HotfixedResourcesDone { get; set; } = false; + public bool HotfixedResourcesDone { get; set; } public int VirtualPathCount { get; set; } public CUE4ParseViewModel(string gameDirectory) @@ -84,7 +83,7 @@ namespace FModel.ViewModels Game = FGame.FortniteGame; Provider = new StreamedFileProvider("FortniteLive", true, new VersionContainer( - UserSettings.Default.OverridedGame[Game], + UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform, customVersions: UserSettings.Default.OverridedCustomVersions[Game], optionOverrides: UserSettings.Default.OverridedOptions[Game])); break; @@ -94,7 +93,7 @@ namespace FModel.ViewModels Game = FGame.ShooterGame; Provider = new StreamedFileProvider("ValorantLive", true, new VersionContainer( - UserSettings.Default.OverridedGame[Game], + UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform, customVersions: UserSettings.Default.OverridedCustomVersions[Game], optionOverrides: UserSettings.Default.OverridedOptions[Game])); break; @@ -102,7 +101,7 @@ namespace FModel.ViewModels default: { Game = gameDirectory.SubstringBeforeLast("\\Content").SubstringAfterLast("\\").ToEnum(FGame.Unknown); - var versions = new VersionContainer(UserSettings.Default.OverridedGame[Game], + var versions = new VersionContainer(UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform, customVersions: UserSettings.Default.OverridedCustomVersions[Game], optionOverrides: UserSettings.Default.OverridedOptions[Game]); @@ -120,7 +119,7 @@ namespace FModel.ViewModels } case FGame.Unknown when UserSettings.Default.ManualGames.TryGetValue(gameDirectory, out var settings): { - versions = new VersionContainer(settings.OverridedGame, + versions = new VersionContainer(settings.OverridedGame, UserSettings.Default.OverridedPlatform, customVersions: settings.OverridedCustomVersions, optionOverrides: settings.OverridedOptions); goto default; @@ -764,7 +763,7 @@ namespace FModel.ViewModels private void SaveExport(UObject export) { - var toSave = new Exporter(export, UserSettings.Default.TextureExportFormat, UserSettings.Default.LodExportFormat, UserSettings.Default.MeshExportFormat); + var toSave = new Exporter(export, UserSettings.Default.TextureExportFormat, UserSettings.Default.LodExportFormat, UserSettings.Default.MeshExportFormat, UserSettings.Default.OverridedPlatform); var toSaveDirectory = new DirectoryInfo(UserSettings.Default.ModelDirectory); if (toSave.TryWriteToDir(toSaveDirectory, out var savedFileName)) { diff --git a/FModel/ViewModels/ModelViewerViewModel.cs b/FModel/ViewModels/ModelViewerViewModel.cs index bb02c1ad..9686b789 100644 --- a/FModel/ViewModels/ModelViewerViewModel.cs +++ b/FModel/ViewModels/ModelViewerViewModel.cs @@ -186,7 +186,7 @@ namespace FModel.ViewModels { foreach (var model in _loadedModels) { - var toSave = new CUE4Parse_Conversion.Exporter(model.Export, UserSettings.Default.TextureExportFormat, UserSettings.Default.LodExportFormat, UserSettings.Default.MeshExportFormat); + var toSave = new CUE4Parse_Conversion.Exporter(model.Export, UserSettings.Default.TextureExportFormat, UserSettings.Default.LodExportFormat, UserSettings.Default.MeshExportFormat, UserSettings.Default.OverridedPlatform); if (toSave.TryWriteToDir(new DirectoryInfo(folderBrowser.SelectedPath), out var savedFileName)) { Log.Information("Successfully saved {FileName}", savedFileName); @@ -419,19 +419,35 @@ namespace FModel.ViewModels } else if (parameters.Diffuse is UTexture2D diffuse) { - m.AlbedoMap = new TextureModel(diffuse.Decode()?.Encode(SKEncodedImageFormat.Png, 100).AsStream()); + m.AlbedoMap = new TextureModel(diffuse.Decode(UserSettings.Default.OverridedPlatform)?.Encode(SKEncodedImageFormat.Png, 100).AsStream()); } if (parameters.Normal is UTexture2D normal) { - m.NormalMap = new TextureModel(normal.Decode()?.Encode(SKEncodedImageFormat.Png, 100).AsStream()); + m.NormalMap = new TextureModel(normal.Decode(UserSettings.Default.OverridedPlatform)?.Encode(SKEncodedImageFormat.Png, 100).AsStream()); } if (parameters.Specular is UTexture2D specular) { var mip = specular.GetFirstMip(); - TextureDecoder.DecodeTexture(mip, specular.Format, specular.isNormalMap, - out var data, out var colorType); + byte[] data; + SKColorType colorType; + switch (UserSettings.Default.OverridedPlatform) + { + case ETexturePlatform.Playstation: + PlaystationDecoder.DecodeTexturePlaystation(mip, specular.Format, specular.isNormalMap, + out data, out colorType); + break; + case ETexturePlatform.NintendoSwitch: + NintendoSwitchDecoder.DecodeTextureNSW(mip, specular.Format, specular.isNormalMap, + out data, out colorType); + break; + default: + TextureDecoder.DecodeTexture(mip, specular.Format, specular.isNormalMap, + out data, out colorType); + break; + } + switch (_game) { @@ -540,7 +556,7 @@ namespace FModel.ViewModels if (parameters.HasTopEmissiveTexture && parameters.Emissive is UTexture2D emissive && parameters.EmissiveColor is { A: > 0 } emissiveColor) { m.EmissiveColor = new Color4(emissiveColor.R, emissiveColor.G, emissiveColor.B, emissiveColor.A); - m.EmissiveMap = new TextureModel(emissive.Decode()?.Encode(SKEncodedImageFormat.Png, 100).AsStream()); + m.EmissiveMap = new TextureModel(emissive.Decode(UserSettings.Default.OverridedPlatform)?.Encode(SKEncodedImageFormat.Png, 100).AsStream()); } } else diff --git a/FModel/ViewModels/SettingsViewModel.cs b/FModel/ViewModels/SettingsViewModel.cs index 984b0b2c..85fcca67 100644 --- a/FModel/ViewModels/SettingsViewModel.cs +++ b/FModel/ViewModels/SettingsViewModel.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading.Tasks; +using CUE4Parse.UE4.Assets.Exports.Texture; using CUE4Parse.UE4.Objects.Core.Misc; using CUE4Parse.UE4.Objects.Core.Serialization; using CUE4Parse.UE4.Versions; @@ -39,6 +40,13 @@ namespace FModel.ViewModels } } + private ETexturePlatform _selectedUePlatform; + public ETexturePlatform SelectedUePlatform + { + get => _selectedUePlatform; + set => SetProperty(ref _selectedUePlatform, value); + } + private EGame _selectedUeGame; public EGame SelectedUeGame { @@ -127,6 +135,7 @@ namespace FModel.ViewModels public ReadOnlyObservableCollection MeshExportFormats { get; private set; } public ReadOnlyObservableCollection LodExportFormats { get; private set; } public ReadOnlyObservableCollection TextureExportFormats { get; private set; } + public ReadOnlyObservableCollection Platforms { get; private set; } public bool EnableElements => SelectedPreset == Constants._NO_PRESET_TRIGGER; @@ -141,6 +150,7 @@ namespace FModel.ViewModels private string _gameSnapshot; private EUpdateMode _updateModeSnapshot; private string _presetSnapshot; + private ETexturePlatform _uePlatformSnapshot; private EGame _ueGameSnapshot; private List _customVersionsSnapshot; private Dictionary _optionsSnapshot; @@ -167,6 +177,7 @@ namespace FModel.ViewModels _gameSnapshot = UserSettings.Default.GameDirectory; _updateModeSnapshot = UserSettings.Default.UpdateMode; _presetSnapshot = UserSettings.Default.Presets[_game]; + _uePlatformSnapshot = UserSettings.Default.OverridedPlatform; if (_game == FGame.Unknown && UserSettings.Default.ManualGames.TryGetValue(_gameSnapshot, out var settings)) { _ueGameSnapshot = settings.OverridedGame; @@ -188,6 +199,7 @@ namespace FModel.ViewModels SelectedUpdateMode = _updateModeSnapshot; SelectedPreset = _presetSnapshot; + SelectedUePlatform = _uePlatformSnapshot; SelectedUeGame = _ueGameSnapshot; SelectedCustomVersions = _customVersionsSnapshot; SelectedOptions = _optionsSnapshot; @@ -211,6 +223,7 @@ namespace FModel.ViewModels MeshExportFormats = new ReadOnlyObservableCollection(new ObservableCollection(EnumerateMeshExportFormat())); LodExportFormats = new ReadOnlyObservableCollection(new ObservableCollection(EnumerateLodExportFormat())); TextureExportFormats = new ReadOnlyObservableCollection(new ObservableCollection(EnumerateTextureExportFormat())); + Platforms = new ReadOnlyObservableCollection(new ObservableCollection(EnumerateUePlatforms())); } public async Task InitPresets(string gameName) @@ -257,8 +270,8 @@ namespace FModel.ViewModels { var ret = SettingsOut.Nothing; - if (_ueGameSnapshot != SelectedUeGame || // combobox - _customVersionsSnapshot != SelectedCustomVersions || _optionsSnapshot != SelectedOptions || + if (_ueGameSnapshot != SelectedUeGame || _customVersionsSnapshot != SelectedCustomVersions || + _uePlatformSnapshot != SelectedUePlatform || _optionsSnapshot != SelectedOptions || // combobox _outputSnapshot != UserSettings.Default.OutputDirectory || // textbox _rawDataSnapshot != UserSettings.Default.RawDataDirectory || // textbox _propertiesSnapshot != UserSettings.Default.PropertiesDirectory || // textbox @@ -276,6 +289,7 @@ namespace FModel.ViewModels UserSettings.Default.UpdateMode = SelectedUpdateMode; UserSettings.Default.Presets[_game] = SelectedPreset; + UserSettings.Default.OverridedPlatform = SelectedUePlatform; if (_game == FGame.Unknown && UserSettings.Default.ManualGames.ContainsKey(UserSettings.Default.GameDirectory)) { UserSettings.Default.ManualGames[UserSettings.Default.GameDirectory].OverridedGame = SelectedUeGame; @@ -317,5 +331,6 @@ namespace FModel.ViewModels private IEnumerable EnumerateMeshExportFormat() => Enum.GetValues(); private IEnumerable EnumerateLodExportFormat() => Enum.GetValues(); private IEnumerable EnumerateTextureExportFormat() => Enum.GetValues(); + private IEnumerable EnumerateUePlatforms() => Enum.GetValues(); } } diff --git a/FModel/ViewModels/TabControlViewModel.cs b/FModel/ViewModels/TabControlViewModel.cs index 8701de51..759dd610 100644 --- a/FModel/ViewModels/TabControlViewModel.cs +++ b/FModel/ViewModels/TabControlViewModel.cs @@ -222,7 +222,7 @@ namespace FModel.ViewModels }); } - public void AddImage(UTexture2D texture) => AddImage(texture.Name, texture.bRenderNearestNeighbor, texture.Decode()); + public void AddImage(UTexture2D texture) => AddImage(texture.Name, texture.bRenderNearestNeighbor, texture.Decode(UserSettings.Default.OverridedPlatform)); public void AddImage(string name, bool rnn, SKBitmap[] img) { foreach (var i in img) AddImage(name, rnn, i); diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml index 2b33ae47..e0f89399 100644 --- a/FModel/Views/SettingsView.xaml +++ b/FModel/Views/SettingsView.xaml @@ -40,6 +40,7 @@ + @@ -129,8 +130,8 @@ DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" SelectionChanged="OnSelectionChanged" Margin="0 0 0 5"> - - + @@ -140,8 +141,19 @@ - - + + + + + + + + + + + @@ -152,8 +164,8 @@