Add debug display for ResidentResources.

This commit is contained in:
Ottermandias 2022-03-20 16:21:14 +01:00
parent ad55d178d4
commit 98b4b29ff5
8 changed files with 59 additions and 102 deletions

View file

@ -16,9 +16,9 @@ public unsafe class ResidentResourceManager
// A static pointer to the resident resource manager address.
[Signature( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05", ScanType = ScanType.StaticAddress )]
private readonly void** _residentResourceManagerAddress = null;
private readonly Structs.ResidentResourceManager** _residentResourceManagerAddress = null;
public void* Address
public Structs.ResidentResourceManager* Address
=> *_residentResourceManagerAddress;
public ResidentResourceManager()

View file

@ -107,6 +107,9 @@ public unsafe partial class PathResolver
? Penumbra.ModManager.Collections.DefaultCollection
: collection, path );
// Weapons have the characters DrawObject as a parent,
// but that may not be set yet when creating a new object, so we have to do the same detour
// as for Human DrawObjects that are just being created.
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
private IntPtr ResolveWeaponPathDetour( IntPtr drawObject, IntPtr path )
{

View file

@ -3,9 +3,9 @@ namespace Penumbra.Interop.Structs;
public enum FileMode : uint
{
LoadUnpackedResource = 0,
LoadFileResource = 1, // Shit in My Games uses this
LoadFileResource = 1, // The config files in MyGames use this.
// some shit here, the game does some jump if its < 0xA for other files for some reason but there's no impl, probs debug?
// Probably debug options only.
LoadIndexResource = 0xA, // load index/index2
LoadSqPackResource = 0xB,
}

View file

@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
namespace Penumbra.Interop.Structs;
[StructLayout(LayoutKind.Explicit)]
public unsafe struct ResidentResourceManager
{
[FieldOffset( 0x00 )]
public void** VTable;
[FieldOffset( 0x08 )]
public void** ResourceListVTable;
[FieldOffset( 0x14 )]
public uint NumResources;
[FieldOffset( 0x18 )]
public ResourceHandle** ResourceList;
}

View file

@ -79,8 +79,4 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Collection\" />
</ItemGroup>
</Project>

View file

@ -327,6 +327,36 @@ public partial class SettingsInterface
}
}
public unsafe void DrawDebugResidentResources()
{
if( !ImGui.CollapsingHeader( "Resident Resources##Debug" ) )
{
return;
}
if( Penumbra.ResidentResources.Address == null || Penumbra.ResidentResources.Address->NumResources == 0 )
{
return;
}
if( !ImGui.BeginTable( "##Resident ResourcesDebugList", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit, -Vector2.UnitX ) )
{
return;
}
using var end = ImGuiRaii.DeferredEnd( ImGui.EndTable );
for( var i = 0; i < Penumbra.ResidentResources.Address->NumResources; ++i )
{
var resource = Penumbra.ResidentResources.Address->ResourceList[ i ];
ImGui.TableNextColumn();
ImGui.Text( $"0x{( ulong )resource:X}" );
ImGui.TableNextColumn();
ImGuiNative.igTextUnformatted( resource->FileName(), resource->FileName() + resource->FileNameLength );
}
}
private unsafe void DrawPathResolverDebug()
{
if( !ImGui.CollapsingHeader( "Path Resolver##Debug" ) )
@ -404,6 +434,8 @@ public partial class SettingsInterface
ImGui.NewLine();
DrawDebugCharacterUtility();
ImGui.NewLine();
DrawDebugResidentResources();
ImGui.NewLine();
DrawDebugTabRedraw();
ImGui.NewLine();
DrawDebugTabIpc();

View file

@ -1,84 +0,0 @@
using System;
using System.IO;
using System.Linq;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Util;
namespace Penumbra.Util;
public readonly struct RelPath : IComparable
{
public const int MaxRelPathLength = 256;
private readonly string _path;
private RelPath( string path, bool _ )
=> _path = path;
private RelPath( string? path )
{
if( path != null && path.Length < MaxRelPathLength )
{
_path = Trim( ReplaceSlash( path ) );
}
else
{
_path = "";
}
}
public RelPath( FullPath file, DirectoryInfo baseDir )
=> _path = CheckPre( file.FullName, baseDir ) ? ReplaceSlash( Trim( Substring( file.FullName, baseDir ) ) ) : string.Empty;
public RelPath( FileInfo file, DirectoryInfo baseDir )
=> _path = CheckPre( file.FullName, baseDir ) ? Trim( Substring( file.FullName, baseDir ) ) : string.Empty;
public RelPath( GamePath gamePath )
=> _path = ReplaceSlash( gamePath );
public GamePath ToGamePath( int skipFolders = 0 )
{
string p = this;
if( skipFolders > 0 )
{
p = string.Join( "/", p.Split( '\\' ).Skip( skipFolders ) );
return GamePath.GenerateUncheckedLower( p );
}
return GamePath.GenerateUncheckedLower( p.Replace( '\\', '/' ) );
}
private static bool CheckPre( string file, DirectoryInfo baseDir )
=> file.StartsWith( baseDir.FullName ) && file.Length < MaxRelPathLength;
private static string Substring( string file, DirectoryInfo baseDir )
=> file.Substring( baseDir.FullName.Length );
private static string ReplaceSlash( string path )
=> path.Replace( '/', '\\' );
private static string Trim( string path )
=> path.TrimStart( '\\' );
public static implicit operator string( RelPath relPath )
=> relPath._path;
public static explicit operator RelPath( string relPath )
=> new(relPath);
public bool Empty
=> _path.Length == 0;
public int CompareTo( object? rhs )
{
return rhs switch
{
string path => string.Compare( _path, path, StringComparison.InvariantCulture ),
RelPath path => string.Compare( _path, path._path, StringComparison.InvariantCulture ),
_ => -1,
};
}
public override string ToString()
=> _path;
}

View file

@ -12,7 +12,7 @@ public static class TempFile
{
var name = Path.GetRandomFileName();
var path = new FileInfo( Path.Combine( baseDir.FullName,
suffix.Any() ? name.Substring( 0, name.LastIndexOf( '.' ) ) + suffix : name ) );
suffix.Length > 0 ? name[ ..name.LastIndexOf( '.' ) ] + suffix : name ) );
if( !path.Exists )
{
return path;
@ -21,13 +21,4 @@ public static class TempFile
throw new IOException();
}
public static FileInfo WriteNew( DirectoryInfo baseDir, byte[] data, string suffix = "" )
{
var fileName = TempFileName( baseDir, suffix );
using var stream = fileName.OpenWrite();
stream.Write( data, 0, data.Length );
fileName.Refresh();
return fileName;
}
}