From cd102a65c2482508201a2e98a18ded1537e88c21 Mon Sep 17 00:00:00 2001 From: King Bore haha <55667610+kingborehaha@users.noreply.github.com> Date: Thu, 11 Jan 2024 01:10:48 -0800 Subject: [PATCH] Fix AC6 param offsets and improve error detection (#820) * Fix AC6 param offsets and improve error detection * Add unique row testing code --- .../Assets/GameOffsets/AC6/ParamOffsets.txt | 70 ++++++++--------- src/StudioCore/MapStudioNew.cs | 6 ++ src/StudioCore/ParamEditor/ParamReloader.cs | 53 ++++++++----- src/StudioCore/Tests/ParamUniqueInserter.cs | 76 +++++++++++++++++++ 4 files changed, 151 insertions(+), 54 deletions(-) create mode 100644 src/StudioCore/Tests/ParamUniqueInserter.cs diff --git a/src/StudioCore/Assets/GameOffsets/AC6/ParamOffsets.txt b/src/StudioCore/Assets/GameOffsets/AC6/ParamOffsets.txt index cf37696ef..22b16cb3f 100644 --- a/src/StudioCore/Assets/GameOffsets/AC6/ParamOffsets.txt +++ b/src/StudioCore/Assets/GameOffsets/AC6/ParamOffsets.txt @@ -211,41 +211,41 @@ UnlockParam_Trophy:0x3F40 UnlockParam_OsPoint:0x3F88 UnlockParam_Archive_Logs:0x3FD0 UnlockParam_Archive_Tips:0x4018 -UnlockParam_DLC:0x4060 -WwiseValueToStrParam_Switch_Material:0x40A8 -WwiseValueToStrParam_Switch_BGMStatus:0x40F0 -WwiseValueToStrParam_Switch_Weapon_Type:0x4138 -WwiseValueToStrParam_Switch_BulletGenerateType:0x4180 -WwiseValueToStrParam_Switch_ShootSeCategory:0x41C8 -WwiseValueToStrParam_Switch_WeaponAtkAttribute:0x4210 -WwiseValueToStrParam_Switch_WeaponMaterial:0x4258 -WwiseValueToStrParam_Switch_AttackPowerType:0x42A0 -WwiseValueToStrParam_Switch_DestroyedSeType:0x42E8 -WwiseValueToStrParam_Switch_GeneratorType:0x4330 -WwiseValueToStrParam_ReverbAuxBusType:0x4378 -WwiseValueToStrParam_ReflectAuxBusType:0x43C0 -WwiseValueToStrParam_ReflectTextureType:0x4408 -WwiseValueToStrParam_RuntimeReflectTextureType:0x4450 -SoundIDSpatialSetting:0x4498 -SoundAutoReverbEvaluationDistParam:0x44E0 -SoundAutoReverbSelectParam:0x4528 -SoundCutsceneParam:0x4570 -SoundVoiceBankLoad:0x45B8 -RuntimeSoundParam_Npc:0x4600 -RuntimeSoundParam_Pc:0x4648 -RuntimeSoundExpressionParam_Npc:0x4690 -RuntimeSoundExpressionParam_Pc:0x46D8 -CutsceneGparamWeatherParam:0x4720 -CutsceneGparamTimeParam:0x4768 -CutsceneTimezoneConvertParam:0x47B0 -CutsceneReplaceSfxParam:0x47F8 -CutsceneMapIdParam:0x4840 -NpcMaterialParam:0x4888 -MapAreaParam:0x48D0 -SkydomeAssetParam:0x4918 -AssetTranscriptionParam:0x4960 -RuntimeSoundGlobalParam:0x49A8 -GamePresenceParam:0x49F0 +UnlockParam_NamePlate_Solo:0x4060 +UnlockParam_NamePlate_Team:0x40A8 +UnlockParam_DLC:0x40F0 +WwiseValueToStrParam_Switch_Material:0x4138 +WwiseValueToStrParam_Switch_BGMStatus:0x4180 +WwiseValueToStrParam_Switch_Weapon_Type:0x41C8 +WwiseValueToStrParam_Switch_BulletGenerateType:0x4210 +WwiseValueToStrParam_Switch_ShootSeCategory:0x4258 +WwiseValueToStrParam_Switch_WeaponAtkAttribute:0x42A0 +WwiseValueToStrParam_Switch_WeaponMaterial:0x42E8 +WwiseValueToStrParam_Switch_AttackPowerType:0x4330 +WwiseValueToStrParam_Switch_DestroyedSeType:0x4378 +WwiseValueToStrParam_Switch_GeneratorType:0x43C0 +WwiseValueToStrParam_ReverbAuxBusType:0x4408 +WwiseValueToStrParam_ReflectAuxBusType:0x4450 +WwiseValueToStrParam_ReflectTextureType:0x4498 +WwiseValueToStrParam_RuntimeReflectTextureType:0x44E0 +SoundIDSpatialSetting:0x4528 +SoundAutoReverbEvaluationDistParam:0x4570 +SoundAutoReverbSelectParam:0x45B8 +SoundCutsceneParam:0x4600 +SoundVoiceBankLoad:0x4648 +RuntimeSoundParam_Npc:0x4690 +RuntimeSoundExpressionParam_Npc:0x4720 +RuntimeSoundParam_Pc:0x46D8 +RuntimeSoundExpressionParam_Pc:0x4768 +CutsceneGparamWeatherParam:0x47B0 +CutsceneGparamTimeParam:0x47F8 +CutsceneTimezoneConvertParam:0x4840 +CutsceneReplaceSfxParam:0x4888 +CutsceneMapIdParam:0x48D0 +NpcMaterialParam:0x4918 +MapAreaParam:0x4960 +SkydomeAssetParam:0x49A8 +AssetTranscriptionParam:0x49F0 GraphicsConfig_RaytracingQuality_win64:0x4A38 AutoAssembleEvaluate:0x4A40 KeyAssignMenuItemParam:0x4A48 diff --git a/src/StudioCore/MapStudioNew.cs b/src/StudioCore/MapStudioNew.cs index 40d8547a6..23cf10e5f 100644 --- a/src/StudioCore/MapStudioNew.cs +++ b/src/StudioCore/MapStudioNew.cs @@ -935,6 +935,12 @@ private unsafe void Update(float deltaseconds) BTLReadWrite.Run(_assetLocator); } + if (ImGui.BeginMenu("Param unique row finder/inserter")) + { + ParamUniqueRowFinder.Display(); + ImGui.EndMenu(); + } + ImGui.EndMenu(); } diff --git a/src/StudioCore/ParamEditor/ParamReloader.cs b/src/StudioCore/ParamEditor/ParamReloader.cs index 22764e569..8a96e1e99 100644 --- a/src/StudioCore/ParamEditor/ParamReloader.cs +++ b/src/StudioCore/ParamEditor/ParamReloader.cs @@ -90,20 +90,41 @@ public static void ReloadMemoryParams(ParamBank bank, AssetLocator loc, string[] private static void ReloadMemoryParamsThreads(ParamBank bank, GameOffsets offsets, string[] paramNames, SoulsMemoryHandler handler) { + nint soloParamRepositoryPtr; + if (offsets.ParamBaseAobPattern != null) + { + if (!handler.TryFindOffsetFromAOB("ParamBase", offsets.ParamBaseAobPattern, offsets.ParamBaseAobRelativeOffsets, out int paramBase)) + { + return; + } + + soloParamRepositoryPtr = IntPtr.Add(handler.GetBaseAddress(), paramBase); + } + else + { + soloParamRepositoryPtr = IntPtr.Add(handler.GetBaseAddress(), offsets.ParamBaseOffset); + } + List tasks = new(); foreach (var param in paramNames) { + if (!offsets.paramOffsets.TryGetValue(param, out var pOffset) || param == null) + { + TaskLogs.AddLog($"Hot reload: cannot find param offset for {param}", LogLevel.Warning, TaskLogs.LogPriority.Normal); + continue; + } + if ((offsets.type is GameType.DarkSoulsPTDE or GameType.DarkSoulsRemastered) && - param == "ThrowParam" && offsets.paramOffsets.ContainsKey(param)) + param == "ThrowParam") { // DS1 ThrowParam requires an additional offset. tasks.Add(new Task(() => - WriteMemoryPARAM(offsets, bank.Params[param], offsets.paramOffsets[param], handler, 0x41C0))); + WriteMemoryPARAM(offsets, bank.Params[param], pOffset, handler, IntPtr.Add(soloParamRepositoryPtr, 0x41C0)))); } - else if (param != null && offsets.paramOffsets.ContainsKey(param)) + else { tasks.Add(new Task(() => - WriteMemoryPARAM(offsets, bank.Params[param], offsets.paramOffsets[param], handler))); + WriteMemoryPARAM(offsets, bank.Params[param], pOffset, handler, soloParamRepositoryPtr))); } } @@ -183,23 +204,10 @@ private static void GiveItem(GameOffsets offsets, List rowsToGib, str } private static void WriteMemoryPARAM(GameOffsets offsets, Param param, int paramOffset, - SoulsMemoryHandler memoryHandler, int paramBaseExtraOffset = 0) + SoulsMemoryHandler memoryHandler, nint soloParamRepositoryPtr) { - if (offsets.ParamBaseAobPattern != null) - { - if (memoryHandler.TryFindOffsetFromAOB("ParamBase", offsets.ParamBaseAobPattern, offsets.ParamBaseAobRelativeOffsets, out int paramBase)) - { - var soloParamRepositoryPtr = IntPtr.Add(memoryHandler.GetBaseAddress(), paramBase + paramBaseExtraOffset); - var BasePtr = memoryHandler.GetParamPtr(soloParamRepositoryPtr, offsets, paramOffset); - WriteMemoryPARAM(offsets, param, BasePtr, memoryHandler); - } - } - else - { - var soloParamRepositoryPtr = IntPtr.Add(memoryHandler.GetBaseAddress(), offsets.ParamBaseOffset + paramBaseExtraOffset); var BasePtr = memoryHandler.GetParamPtr(soloParamRepositoryPtr, offsets, paramOffset); WriteMemoryPARAM(offsets, param, BasePtr, memoryHandler); - } } private static void WriteMemoryPARAM(GameOffsets offsets, Param param, IntPtr BasePtr, @@ -208,6 +216,12 @@ private static void WriteMemoryPARAM(GameOffsets offsets, Param param, IntPtr Ba var BaseDataPtr = memoryHandler.GetToRowPtr(offsets, BasePtr); var RowCount = memoryHandler.GetRowCount(offsets, BasePtr); + if (RowCount <= 0) + { + TaskLogs.AddLog($"Hot reload: ParamType {param.ParamType} has invalid offset or no rows", LogLevel.Warning, TaskLogs.LogPriority.Low); + return; + } + IntPtr DataSectionPtr; var RowId = 0; @@ -237,7 +251,8 @@ private static void WriteMemoryPARAM(GameOffsets offsets, Param param, IntPtr Ba } else { - throw new InvalidOperationException("Param row in memory cannot be found in editor. Try saving params and restarting game."); + TaskLogs.AddLog($"Hot reload: ParamType {param.ParamType}: row {RowId} index {i} is in memory but not in editor. Try saving params and restarting game.", LogLevel.Warning, TaskLogs.LogPriority.Normal); + return; } } } diff --git a/src/StudioCore/Tests/ParamUniqueInserter.cs b/src/StudioCore/Tests/ParamUniqueInserter.cs new file mode 100644 index 000000000..c34271334 --- /dev/null +++ b/src/StudioCore/Tests/ParamUniqueInserter.cs @@ -0,0 +1,76 @@ +using ImGuiNET; +using SoulsFormats; +using StudioCore.ParamEditor; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; + +namespace StudioCore.Tests; + +public static class ParamUniqueRowFinder +{ + private static int _searchID = 0; + private static int _searchIndex = -1; + + public static void Display() + { + ImGui.InputInt("id", ref _searchID); + ImGui.InputInt("index", ref _searchIndex); + if (ImGui.Button("Search##ParamUniqueInserter")) + { + Find(_searchID, _searchIndex); + } + if (ImGui.Button("Insert unique row ID into every param")) + { + var baseID = ParamBank.PrimaryBank.Params.Values.Max(p => p.Rows.Max(r => r.ID)) + 1; + var i = baseID; + foreach (var p in ParamBank.PrimaryBank.Params.Values) + { + Andre.Formats.Param.Row row = new(p.Rows.First()); + row.ID = i; + i++; + p.AddRow(row); + } + TaskLogs.AddLog($"Added rows to all params with IDs {baseID}-{i-1} ", + Microsoft.Extensions.Logging.LogLevel.Debug, TaskLogs.LogPriority.High); + } + } + + + public static bool Find(int id, int index) + { + List output = new(); + foreach (var p in ParamBank.PrimaryBank.Params) + { + for (var i = 0; i < p.Value.Rows.Count; i++) + { + var r = p.Value.Rows[i]; + if (r.ID == id + && (index == -1 || index == i)) + { + output.Add(p.Key); + } + } + } + if (output.Count > 0) + { + string message = ""; + foreach (var line in output) + { + message += $"{line}\n"; + } + TaskLogs.AddLog(message, + Microsoft.Extensions.Logging.LogLevel.Debug, TaskLogs.LogPriority.High); + } + else + { + TaskLogs.AddLog("No row IDs found", + Microsoft.Extensions.Logging.LogLevel.Debug, TaskLogs.LogPriority.High); + } + + + return true; + } +}