Fix some stuff.

This commit is contained in:
Ottermandias 2022-08-23 17:49:14 +02:00
parent cfeb20a18e
commit 674dc03f46
11 changed files with 130 additions and 75 deletions

View file

@ -135,7 +135,7 @@ public partial class ModCollection
var settings = _settings[ idx ]; var settings = _settings[ idx ];
if( settings != null ) if( settings != null )
{ {
_unusedSettings.Add( mod.ModPath.Name, new ModSettings.SavedSettings( settings, mod ) ); _unusedSettings[mod.ModPath.Name] = new ModSettings.SavedSettings( settings, mod );
} }
_settings.RemoveAt( idx ); _settings.RemoveAt( idx );

View file

@ -46,6 +46,8 @@ public class DdsFile
ParseType.R8G8B8A8 => Header.Height * Header.Width * 4, ParseType.R8G8B8A8 => Header.Height * Header.Width * 4,
ParseType.B8G8R8A8 => Header.Height * Header.Width * 4, ParseType.B8G8R8A8 => Header.Height * Header.Width * 4,
ParseType.A16B16G16R16F => Header.Height * Header.Width * 8,
_ => throw new ArgumentOutOfRangeException( nameof( ParseType ), ParseType, null ), _ => throw new ArgumentOutOfRangeException( nameof( ParseType ), ParseType, null ),
}; };
@ -107,6 +109,7 @@ public class DdsFile
ParseType.B8G8R8 => ImageParsing.DecodeUncompressedB8G8R8( MipMap( 0 ), Header.Height, Header.Width ), ParseType.B8G8R8 => ImageParsing.DecodeUncompressedB8G8R8( MipMap( 0 ), Header.Height, Header.Width ),
ParseType.R8G8B8A8 => _data.Length == Header.Width * Header.Height * 4 ? _data : _data[ ..( Header.Width * Header.Height * 4 ) ], ParseType.R8G8B8A8 => _data.Length == Header.Width * Header.Height * 4 ? _data : _data[ ..( Header.Width * Header.Height * 4 ) ],
ParseType.B8G8R8A8 => ImageParsing.DecodeUncompressedB8G8R8A8( MipMap( 0 ), Header.Height, Header.Width ), ParseType.B8G8R8A8 => ImageParsing.DecodeUncompressedB8G8R8A8( MipMap( 0 ), Header.Height, Header.Width ),
ParseType.A16B16G16R16F => ImageParsing.DecodeUncompressedA16B16G16R16F( MipMap( 0 ), Header.Height, Header.Width ),
_ => throw new ArgumentOutOfRangeException(), _ => throw new ArgumentOutOfRangeException(),
}; };
} }
@ -126,6 +129,12 @@ public class DdsFile
var dxt10 = header.PixelFormat.FourCC == PixelFormat.FourCCType.DX10 ? ( DXT10Header? )br.ReadStructure< DXT10Header >() : null; var dxt10 = header.PixelFormat.FourCC == PixelFormat.FourCCType.DX10 ? ( DXT10Header? )br.ReadStructure< DXT10Header >() : null;
var type = header.PixelFormat.ToParseType( dxt10 ); var type = header.PixelFormat.ToParseType( dxt10 );
if( type == ParseType.Unsupported )
{
PluginLog.Error( "DDS format unsupported." );
return false;
}
file = new DdsFile( type, header, br.ReadBytes( ( int )( br.BaseStream.Length - br.BaseStream.Position ) ), dxt10 ); file = new DdsFile( type, header, br.ReadBytes( ( int )( br.BaseStream.Length - br.BaseStream.Position ) ), dxt10 );
return true; return true;
} }

View file

@ -577,4 +577,25 @@ public static partial class ImageParsing
return ret; return ret;
} }
public static unsafe byte[] DecodeUncompressedA16B16G16R16F( ReadOnlySpan< byte > data, int height, int width )
{
Verify( data, height, width, 1, 8 );
var ret = new byte[data.Length / 2];
fixed( byte* r = ret, d = data )
{
var ptr = r;
var input = ( Half* )d;
var end = (Half*) (d + data.Length);
while( input != end )
{
*ptr++ = ( byte )( byte.MaxValue * (float) *input++ );
*ptr++ = ( byte )( byte.MaxValue * (float) *input++ );
*ptr++ = ( byte )( byte.MaxValue * (float) *input++ );
*ptr++ = ( byte )( byte.MaxValue * (float) *input++ );
}
}
return ret;
}
} }

View file

@ -26,6 +26,8 @@ public enum ParseType
B8G8R8, B8G8R8,
R8G8B8A8, R8G8B8A8,
B8G8R8A8, B8G8R8A8,
A16B16G16R16F,
} }
[StructLayout( LayoutKind.Sequential )] [StructLayout( LayoutKind.Sequential )]
@ -67,10 +69,10 @@ public struct PixelFormat
ATI2 = 'A' | ( 'T' << 8 ) | ( 'I' << 16 ) | ( '2' << 24 ), ATI2 = 'A' | ( 'T' << 8 ) | ( 'I' << 16 ) | ( '2' << 24 ),
BC5U = 'B' | ( 'C' << 8 ) | ( '5' << 16 ) | ( 'U' << 24 ), BC5U = 'B' | ( 'C' << 8 ) | ( '5' << 16 ) | ( 'U' << 24 ),
BC55 = 'B' | ( 'C' << 8 ) | ( '5' << 16 ) | ( '5' << 24 ), BC55 = 'B' | ( 'C' << 8 ) | ( '5' << 16 ) | ( '5' << 24 ),
D3D_A16B16G16R16 = 113,
} }
public void Write( BinaryWriter bw ) public void Write( BinaryWriter bw )
{ {
bw.Write( Size ); bw.Write( Size );
@ -100,6 +102,7 @@ public struct PixelFormat
FourCCType.ATI2 => ParseType.BC5, FourCCType.ATI2 => ParseType.BC5,
FourCCType.BC5U => ParseType.BC5, FourCCType.BC5U => ParseType.BC5,
FourCCType.BC55 => ParseType.BC5, FourCCType.BC55 => ParseType.BC5,
FourCCType.D3D_A16B16G16R16 => ParseType.A16B16G16R16F,
_ => ParseType.Unsupported, _ => ParseType.Unsupported,
}; };
} }

View file

@ -8,7 +8,7 @@ namespace Penumbra.Interop;
public unsafe class CharacterUtility : IDisposable public unsafe class CharacterUtility : IDisposable
{ {
// A static pointer to the CharacterUtility address. // A static pointer to the CharacterUtility address.
[Signature( "48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2", ScanType = ScanType.StaticAddress )] [Signature( "48 8B 05 ?? ?? ?? ?? 83 B9", ScanType = ScanType.StaticAddress )]
private readonly Structs.CharacterUtility** _characterUtilityAddress = null; private readonly Structs.CharacterUtility** _characterUtilityAddress = null;
// Only required for migration anymore. // Only required for migration anymore.

View file

@ -173,7 +173,7 @@ public unsafe partial class PathResolver
// so we always keep track of the current GameObject to be able to link it to the DrawObject. // so we always keep track of the current GameObject to be able to link it to the DrawObject.
private delegate void EnableDrawDelegate( IntPtr gameObject, IntPtr b, IntPtr c, IntPtr d ); private delegate void EnableDrawDelegate( IntPtr gameObject, IntPtr b, IntPtr c, IntPtr d );
[Signature( "E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9 74 ?? 33 D2 E8 ?? ?? ?? ?? 84 C0", DetourName = nameof( EnableDrawDetour ) )] [Signature( "E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9 74 33 45 33 C0", DetourName = nameof( EnableDrawDetour ) )]
private readonly Hook< EnableDrawDelegate > _enableDrawHook = null!; private readonly Hook< EnableDrawDelegate > _enableDrawHook = null!;
private void EnableDrawDetour( IntPtr gameObject, IntPtr b, IntPtr c, IntPtr d ) private void EnableDrawDetour( IntPtr gameObject, IntPtr b, IntPtr c, IntPtr d )

View file

@ -1,10 +1,12 @@
using System; using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Dalamud.Logging; using Dalamud.Logging;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object; using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI; using FFXIVClientStructs.FFXIV.Component.GUI;
using Lumina.Excel.GeneratedSheets;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.GameData.ByteString; using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
@ -15,6 +17,9 @@ namespace Penumbra.Interop.Resolver;
public unsafe partial class PathResolver public unsafe partial class PathResolver
{ {
[Signature( "0F B7 0D ?? ?? ?? ?? C7 85", ScanType = ScanType.StaticAddress )]
private static ushort* _inspectTitleId = null!;
// Obtain the name of the current player, if one exists. // Obtain the name of the current player, if one exists.
private static string? GetPlayerName() private static string? GetPlayerName()
=> Dalamud.Objects[ 0 ]?.Name.ToString(); => Dalamud.Objects[ 0 ]?.Name.ToString();
@ -34,17 +39,14 @@ public unsafe partial class PathResolver
} }
var ui = ( AtkUnitBase* )addon; var ui = ( AtkUnitBase* )addon;
if( ui->UldManager.NodeListCount < 60 ) if( ui->UldManager.NodeListCount <= 60 )
{ {
return null; return null;
} }
var text = ( AtkTextNode* )ui->UldManager.NodeList[ 59 ]; var nodeId = Dalamud.GameData.GetExcelSheet< Title >()?.GetRow( *_inspectTitleId )?.IsPrefix == true ? 59 : 60;
if( text == null || !text->AtkResNode.IsVisible )
{
text = ( AtkTextNode* )ui->UldManager.NodeList[ 60 ];
}
var text = ( AtkTextNode* )ui->UldManager.NodeList[ nodeId ];
return text != null ? text->NodeText.ToString() : null; return text != null ? text->NodeText.ToString() : null;
} }

View file

@ -241,9 +241,16 @@ public partial class ModEditWindow
} }
if( data != null ) if( data != null )
{
try
{ {
wrap = Dalamud.PluginInterface.UiBuilder.LoadImageRaw( data, width, height, 4 ); wrap = Dalamud.PluginInterface.UiBuilder.LoadImageRaw( data, width, height, 4 );
} }
catch( Exception e )
{
PluginLog.Error( $"Could not load raw image:\n{e}" );
}
}
UpdateCenter(); UpdateCenter();
} }
@ -356,7 +363,10 @@ public partial class ModEditWindow
if( wrap != null ) if( wrap != null )
{ {
ImGui.TextUnformatted( $"Image Dimensions: {wrap.Width} x {wrap.Height}" ); ImGui.TextUnformatted( $"Image Dimensions: {wrap.Width} x {wrap.Height}" );
size = size with { Y = wrap.Height * size.X / wrap.Width }; size = size.X < wrap.Width
? size with { Y = wrap.Height * size.X / wrap.Width }
: new Vector2( wrap.Width, wrap.Height );
ImGui.Image( wrap.ImGuiHandle, size ); ImGui.Image( wrap.ImGuiHandle, size );
} }
else if( path.Length > 0 ) else if( path.Length > 0 )
@ -425,7 +435,9 @@ public partial class ModEditWindow
return; return;
} }
var leftRightWidth = new Vector2( ( ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X - ImGui.GetStyle().FramePadding.X * 4 ) / 3, -1 ); var leftRightWidth =
new Vector2(
( ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X - ImGui.GetStyle().FramePadding.X * 4 ) / 3, -1 );
var imageSize = new Vector2( leftRightWidth.X - ImGui.GetStyle().FramePadding.X * 2 ); var imageSize = new Vector2( leftRightWidth.X - ImGui.GetStyle().FramePadding.X * 2 );
using( var child = ImRaii.Child( "ImageLeft", leftRightWidth, true ) ) using( var child = ImRaii.Child( "ImageLeft", leftRightWidth, true ) )
{ {

View file

@ -202,7 +202,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
var button = ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.FileImport.ToIconString(), size, var button = ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.FileImport.ToIconString(), size,
"Import one or multiple mods from Tex Tools Mod Pack Files.", !Penumbra.ModManager.Valid, true ); "Import one or multiple mods from Tex Tools Mod Pack Files.", !Penumbra.ModManager.Valid, true );
ConfigWindow.OpenTutorial( ConfigWindow.BasicTutorialSteps.ModImport ); ConfigWindow.OpenTutorial( ConfigWindow.BasicTutorialSteps.ModImport );
if (!button) if( !button )
{ {
return; return;
} }
@ -212,7 +212,8 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
: Penumbra.Config.ModDirectory.Length > 0 ? Penumbra.Config.ModDirectory : null; : Penumbra.Config.ModDirectory.Length > 0 ? Penumbra.Config.ModDirectory : null;
_hasSetFolder = true; _hasSetFolder = true;
_fileManager.OpenFileDialog( "Import Mod Pack", "Mod Packs{.ttmp,.ttmp2,.zip,.7z,.rar},TexTools Mod Packs{.ttmp,.ttmp2},Archives{.zip,.7z,.rar}", ( s, f ) => _fileManager.OpenFileDialog( "Import Mod Pack",
"Mod Packs{.ttmp,.ttmp2,.zip,.7z,.rar},TexTools Mod Packs{.ttmp,.ttmp2},Archives{.zip,.7z,.rar}", ( s, f ) =>
{ {
if( s ) if( s )
{ {
@ -312,13 +313,20 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
{ {
ImGui.OpenPopup( "ExtendedHelp" ); ImGui.OpenPopup( "ExtendedHelp" );
} }
ConfigWindow.OpenTutorial( ConfigWindow.BasicTutorialSteps.AdvancedHelp ); ConfigWindow.OpenTutorial( ConfigWindow.BasicTutorialSteps.AdvancedHelp );
} }
// Helpers. // Helpers.
private static void SetDescendants( ModFileSystem.Folder folder, bool enabled, bool inherit = false ) private static void SetDescendants( ModFileSystem.Folder folder, bool enabled, bool inherit = false )
{ {
var mods = folder.GetAllDescendants( ISortMode< Mod >.Lexicographical ).OfType< ModFileSystem.Leaf >().Select( l => l.Value ); var mods = folder.GetAllDescendants( ISortMode< Mod >.Lexicographical ).OfType< ModFileSystem.Leaf >().Select( l =>
{
// Any mod handled here should not stay new.
Penumbra.ModManager.NewMods.Remove( l.Value );
return l.Value;
} );
if( inherit ) if( inherit )
{ {
Penumbra.CollectionManager.Current.SetMultipleModInheritances( mods, enabled ); Penumbra.CollectionManager.Current.SetMultipleModInheritances( mods, enabled );

View file

@ -126,8 +126,8 @@ public partial class ConfigWindow
_currentPriority = null; _currentPriority = null;
} }
ImGuiUtil.LabeledHelpMarker( "Priority", "Mods with higher priority take precedence before Mods with lower priority.\n" ImGuiUtil.LabeledHelpMarker( "Priority", "Mods with a higher number here take precedence before Mods with a lower number.\n"
+ "That means, if Mod A should overwrite changes from Mod B, Mod A should have higher priority than Mod B." ); + "That means, if Mod A should overwrite changes from Mod B, Mod A should have a higher priority number than Mod B." );
} }
// Draw a button to remove the current settings and inherit them instead // Draw a button to remove the current settings and inherit them instead

View file

@ -88,7 +88,7 @@ public partial class ConfigWindow
return; return;
} }
ImGui.TextWrapped( _mod.Description ); ImGuiUtil.TextWrapped( _mod.Description );
} }
// A simple clipped list of changed items. // A simple clipped list of changed items.