Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Exports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,8 +514,12 @@ static void UpdateUIForFrameChange()
TALLY_PERFORMANCE(PerformanceCheckpoint::AssetEditorDoFrame);
pWindowManager.AssetEditor.DoFrame();

TALLY_PERFORMANCE(PerformanceCheckpoint::PointerFinderDoFrame);
pWindowManager.PointerFinder.DoFrame();

TALLY_PERFORMANCE(PerformanceCheckpoint::PointerInspectorDoFrame);
pWindowManager.PointerInspector.DoFrame();

auto& pFrameEventQueue = ra::services::ServiceLocator::GetMutable<ra::services::FrameEventQueue>();
pFrameEventQueue.DoFrame();
}
Expand Down
6 changes: 6 additions & 0 deletions src/RA_Integration.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
<ClCompile Include="ui\viewmodels\OverlaySettingsViewModel.cpp" />
<ClCompile Include="ui\viewmodels\OverlayViewModel.cpp" />
<ClCompile Include="ui\viewmodels\PointerFinderViewModel.cpp" />
<ClCompile Include="ui\viewmodels\PointerInspectorViewModel.cpp" />
<ClCompile Include="ui\viewmodels\PopupMessageViewModel.cpp" />
<ClCompile Include="ui\viewmodels\PopupViewModelBase.cpp" />
<ClCompile Include="ui\viewmodels\ProgressTrackerViewModel.cpp" />
Expand Down Expand Up @@ -169,6 +170,7 @@
<ClCompile Include="ui\win32\OverlaySettingsDialog.cpp" />
<ClCompile Include="ui\win32\OverlayWindow.cpp" />
<ClCompile Include="ui\win32\PointerFinderDialog.cpp" />
<ClCompile Include="ui\win32\PointerInspectorDialog.cpp" />
<ClCompile Include="ui\win32\ProgressDialog.cpp" />
<ClCompile Include="ui\win32\RichPresenceDialog.cpp" />
<ClCompile Include="ui\win32\UnknownGameDialog.cpp" />
Expand Down Expand Up @@ -309,6 +311,7 @@
<ClInclude Include="ui\viewmodels\OverlaySettingsViewModel.hh" />
<ClInclude Include="ui\viewmodels\OverlayViewModel.hh" />
<ClInclude Include="ui\viewmodels\PointerFinderViewModel.hh" />
<ClInclude Include="ui\viewmodels\PointerInspectorViewModel.hh" />
<ClInclude Include="ui\viewmodels\PopupMessageViewModel.hh" />
<ClInclude Include="ui\viewmodels\PopupViewModelBase.hh" />
<ClInclude Include="ui\viewmodels\ProgressTrackerViewModel.hh" />
Expand All @@ -327,6 +330,8 @@
<ClInclude Include="ui\win32\bindings\ControlBinding.hh" />
<ClInclude Include="ui\win32\bindings\GridAddressColumnBinding.hh" />
<ClInclude Include="ui\win32\bindings\GridBinding.hh" />
<ClInclude Include="ui\win32\bindings\GridBookmarkFormatColumnBinding.hh" />
<ClInclude Include="ui\win32\bindings\GridBookmarkValueColumnBinding.hh" />
<ClInclude Include="ui\win32\bindings\GridBooleanColumnBinding.hh" />
<ClInclude Include="ui\win32\bindings\GridCheckBoxColumnBinding.hh" />
<ClInclude Include="ui\win32\bindings\GridColumnBinding.hh" />
Expand Down Expand Up @@ -356,6 +361,7 @@
<ClInclude Include="ui\win32\OverlaySettingsDialog.hh" />
<ClInclude Include="ui\win32\OverlayWindow.hh" />
<ClInclude Include="ui\win32\PointerFinderDialog.hh" />
<ClInclude Include="ui\win32\PointerInspectorDialog.hh" />
<ClInclude Include="ui\win32\ProgressDialog.hh" />
<ClInclude Include="ui\win32\RichPresenceDialog.hh" />
<ClInclude Include="ui\win32\IDialogPresenter.hh" />
Expand Down
18 changes: 18 additions & 0 deletions src/RA_Integration.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,12 @@
<ClCompile Include="data\models\CodeNoteModel.cpp">
<Filter>Data\Models</Filter>
</ClCompile>
<ClCompile Include="ui\viewmodels\PointerInspectorViewModel.cpp">
<Filter>UI\ViewModels</Filter>
</ClCompile>
<ClCompile Include="ui\win32\PointerInspectorDialog.cpp">
<Filter>UI\Win32</Filter>
</ClCompile>
<ClCompile Include="services\AchievementLogicSerializer.cpp">
<Filter>Services</Filter>
</ClCompile>
Expand Down Expand Up @@ -980,6 +986,18 @@
<ClInclude Include="data\models\CodeNoteModel.hh">
<Filter>Data\Models</Filter>
</ClInclude>
<ClInclude Include="ui\viewmodels\PointerInspectorViewModel.hh">
<Filter>UI\ViewModels</Filter>
</ClInclude>
<ClInclude Include="ui\win32\PointerInspectorDialog.hh">
<Filter>UI\Win32</Filter>
</ClInclude>
<ClInclude Include="ui\win32\bindings\GridBookmarkFormatColumnBinding.hh">
<Filter>UI\Win32\Bindings</Filter>
</ClInclude>
<ClInclude Include="ui\win32\bindings\GridBookmarkValueColumnBinding.hh">
<Filter>UI\Win32\Bindings</Filter>
</ClInclude>
<ClInclude Include="services\AchievementLogicSerializer.hh">
<Filter>Services</Filter>
</ClInclude>
Expand Down
2 changes: 2 additions & 0 deletions src/RA_Resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
#define IDD_RA_PROGRESS 1512
#define IDD_RA_NEWASSET 1513
#define IDD_RA_POINTERFINDER 1514
#define IDD_RA_POINTERINSPECTOR 1515
#define IDC_RA_PASSWORD 1535
#define IDC_RA_SAVEPASSWORD 1536
#define IDC_RA_USERNAME 1549
Expand Down Expand Up @@ -209,6 +210,7 @@
#define IDM_RA_NON_HARDCORE_WARNING 1718
#define IDM_RA_FILES_OPENALL 1719
#define IDM_RA_FILES_POINTERFINDER 1720
#define IDM_RA_FILES_POINTERINSPECTOR 1721
#define IDM_RA_MENUEND 1739

// Next default values for new objects
Expand Down
19 changes: 19 additions & 0 deletions src/RA_Shared.rc
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,25 @@ BEGIN
PUSHBUTTON "Move Down",IDC_RA_MOVE_BOOKMARK_DOWN,290,137,50,14
END

IDD_RA_POINTERINSPECTOR DIALOGEX 0, 0, 341, 232
STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Pointer Inspector"
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
LTEXT "Root Address:",IDC_STATIC,6,5,63,11
EDITTEXT IDC_RA_ADDRESS,55,3,54,12,ES_AUTOHSCROLL,WS_EX_RIGHT
LTEXT "Viewing Node:",IDC_STATIC,120,5,83,11
COMBOBOX IDC_RA_FILTER_VALUE,170,3,168,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Description:",IDC_STATIC,6,20,63,11
EDITTEXT IDC_RA_DESCRIPTION,55,18,283,12,ES_AUTOHSCROLL
CONTROL "",IDC_RA_LBX_GROUPS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_CLIPCHILDREN | WS_BORDER,4,32,334,60
CONTROL "",IDC_RA_LBX_ADDRESSES,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_CLIPCHILDREN | WS_BORDER,4,95,334,118
PUSHBUTTON "Bookmark Selected",IDC_RA_ADDBOOKMARK,4,215,70,14,BS_MULTILINE
PUSHBUTTON "Copy Chain",IDC_RA_COPY_ALL,75,215,70,14
PUSHBUTTON "Pause",IDC_RA_PAUSE,236,215,50,14,BS_MULTILINE
PUSHBUTTON "Freeze",IDC_RA_FREEZE,288,215,50,14,BS_MULTILINE
END

IDD_RA_CODENOTES DIALOGEX 0, 0, 287, 230
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "Code Notes"
Expand Down
22 changes: 11 additions & 11 deletions src/RA_StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ std::wstring& NormalizeLineEndings(_Inout_ std::wstring& str);
// ----- ToString -----

template<typename T>
_NODISCARD inline const std::string ToString(_In_ const T& value)
_NODISCARD inline const std::string ToAString(_In_ const T& value)
{
if constexpr (std::is_arithmetic_v<T>)
{
Expand Down Expand Up @@ -75,44 +75,44 @@ _NODISCARD inline const std::string ToString(_In_ const T& value)
}

template<>
_NODISCARD inline const std::string ToString(_In_ const std::string& value)
_NODISCARD inline const std::string ToAString(_In_ const std::string& value)
{
return value;
}

template<>
_NODISCARD inline const std::string ToString(_In_ const std::wstring& value)
_NODISCARD inline const std::string ToAString(_In_ const std::wstring& value)
{
return ra::Narrow(value);
}

template<>
_NODISCARD inline const std::string ToString(_In_ const wchar_t* const& value)
_NODISCARD inline const std::string ToAString(_In_ const wchar_t* const& value)
{
return ra::Narrow(value);
}

template<>
_NODISCARD inline const std::string ToString(_In_ const char* const& value)
_NODISCARD inline const std::string ToAString(_In_ const char* const& value)
{
return std::string(value);
}

template<>
_NODISCARD inline const std::string ToString(_In_ char* const& value)
_NODISCARD inline const std::string ToAString(_In_ char* const& value)
{
return std::string(value);
}

template<>
_NODISCARD inline const std::string ToString(_In_ const char& value)
_NODISCARD inline const std::string ToAString(_In_ const char& value)
{
return std::string(1, value);
}

// literal strings can't be passed by reference, so won't call the templated methods
_NODISCARD inline const std::string ToString(_In_ const char* value) { return std::string(value); }
_NODISCARD inline const std::string ToString(_In_ const wchar_t* value) { return ra::Narrow(value); }
_NODISCARD inline const std::string ToAString(_In_ const char* value) { return std::string(value); }
_NODISCARD inline const std::string ToAString(_In_ const wchar_t* value) { return ra::Narrow(value); }

// ----- ToWString -----

Expand Down Expand Up @@ -201,7 +201,7 @@ class StringBuilder
if (m_bPrepareWide)
m_vPending.emplace_back(std::wstring{ra::ToWString(arg)});
else
m_vPending.emplace_back(std::string{ra::ToString(arg)});
m_vPending.emplace_back(std::string{ra::ToAString(arg)});
}

template<>
Expand Down Expand Up @@ -442,7 +442,7 @@ class StringBuilder
const char c = sFormat.back();
sFormat.pop_back(); // remove 's'/'x'
sFormat.pop_back(); // remove '*'
sFormat.append(ra::ToString(value));
sFormat.append(ra::ToAString(value));
sFormat.push_back(c); // replace 's'/'x'

if constexpr (sizeof...(args) > 0)
Expand Down
34 changes: 34 additions & 0 deletions src/data/ModelCollectionBase.hh
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,40 @@ public:
return -1;
}

/// <summary>
/// Finds the index of the first item where the specified property has the specified value.
/// </summary>
/// <param name="pProperty">The property to query.</param>
/// <param name="sValue">The value to find.</param>
/// <returns>Index of the first matching item, <c>-1</c> if not found.</returns>
gsl::index FindItemIndex(const StringModelProperty& pProperty, const std::wstring& sValue) const
{
for (gsl::index nIndex = 0; nIndex < gsl::narrow<gsl::index>(m_nSize); ++nIndex)
{
if (m_vItems.at(nIndex)->GetValue(pProperty) == sValue)
return nIndex;
}

return -1;
}

/// <summary>
/// Finds the index of the first item where the specified property has the specified value.
/// </summary>
/// <param name="pProperty">The property to query.</param>
/// <param name="bValue">The value to find.</param>
/// <returns>Index of the first matching item, <c>-1</c> if not found.</returns>
gsl::index FindItemIndex(const BoolModelProperty& pProperty, bool bValue) const
{
for (gsl::index nIndex = 0; nIndex < gsl::narrow<gsl::index>(m_nSize); ++nIndex)
{
if (m_vItems.at(nIndex)->GetValue(pProperty) == bValue)
return nIndex;
}

return -1;
}

/// <summary>
/// Calls the OnBeginModelCollectionUpdate method of any attached NotifyTargets.
/// </summary>
Expand Down
95 changes: 74 additions & 21 deletions src/data/models/CodeNoteModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ uint32_t CodeNoteModel::GetRawPointerValue() const noexcept
return m_pPointerData != nullptr ? m_pPointerData->RawPointerValue : 0xFFFFFFFF;
}

bool CodeNoteModel::HasNestedPointers() const noexcept
{
return m_pPointerData != nullptr && m_pPointerData->HasPointers;
}

static ra::ByteAddress ConvertPointer(ra::ByteAddress nAddress)
{
const auto& pConsoleContext = ra::services::ServiceLocator::Get<ra::data::context::ConsoleContext>();
Expand Down Expand Up @@ -300,7 +305,19 @@ bool CodeNoteModel::GetNextAddress(ra::ByteAddress nAfterAddress, ra::ByteAddres
return bResult;
}

void CodeNoteModel::SetNote(const std::wstring& sNote)
std::wstring CodeNoteModel::GetPrimaryNote() const
{
if (m_pPointerData != nullptr)
{
const auto nIndex = m_sNote.find(L"\n+");
if (nIndex != std::wstring::npos)
return m_sNote.substr(0, nIndex);
}

return m_sNote;
}

void CodeNoteModel::SetNote(const std::wstring& sNote, bool bImpliedPointer)
{
if (m_sNote == sNote)
return;
Expand All @@ -314,28 +331,53 @@ void CodeNoteModel::SetNote(const std::wstring& sNote)
const auto nNextIndex = sNote.find(L'\n', nIndex);
sLine = (nNextIndex == std::string::npos) ?
sNote.substr(nIndex) : sNote.substr(nIndex, nNextIndex - nIndex);
StringMakeLowercase(sLine);
ExtractSize(sLine);

if (sLine.find(L"pointer") != std::string::npos)
if (!sLine.empty())
{
if (m_nMemSize == MemSize::Unknown)
if (sLine.at(0) == '+' && bImpliedPointer)
{
// pointer size not specified. assume 32-bit
m_nMemSize = MemSize::ThirtyTwoBit;
m_nBytes = 4;

// found a line starting with a plus sign, bit no pointer annotation. bImpliedPointer
// must be true. assume the parent note is not described. pass -1 as the note size
// because we already skipped over the newline character
ProcessIndirectNotes(sNote, gsl::narrow_cast<size_t>(-1));
m_pPointerData->HeaderLength = 0;
break;
}

// if there are any lines starting with a plus sign, extract the indirect code notes
nIndex = sNote.find(L"\n+", nIndex + 1);
if (nIndex != std::string::npos)
ProcessIndirectNotes(sNote, nIndex);
StringMakeLowercase(sLine);
ExtractSize(sLine);

break;
}
if (sLine.find(L"pointer") != std::string::npos)
{
if (m_nMemSize == MemSize::Unknown)
{
// pointer size not specified. assume 32-bit
m_nMemSize = MemSize::ThirtyTwoBit;
m_nBytes = 4;
}

if (m_nMemSize != MemSize::Unknown) // found a size. stop processing.
break;
// if there are any lines starting with a plus sign, extract the indirect code notes
nIndex = sNote.find(L"\n+", nIndex + 1);
if (nIndex != std::string::npos)
ProcessIndirectNotes(sNote, nIndex);

// failed to find nested code notes. create a PointerData object so the note still
// gets treated as a pointer
if (!m_pPointerData)
{
m_pPointerData.reset(new PointerData());
m_pPointerData->HeaderLength = gsl::narrow_cast<unsigned>(sNote.length());
}

break;
}

if (m_nMemSize != MemSize::Unknown) // found a size. stop processing.
break;
}

if (nNextIndex == std::string::npos) // end of string
break;
Expand Down Expand Up @@ -664,16 +706,27 @@ void CodeNoteModel::ProcessIndirectNotes(const std::wstring& sNote, size_t nInde

// skip over [whitespace] [optional separator] [whitespace]
const wchar_t* pStop = sNextNote.c_str() + sNextNote.length();
while (pEnd < pStop && isspace(*pEnd))
pEnd++;
if (pEnd < pStop && !isalnum(*pEnd))
while (pEnd < pStop && isspace(*pEnd) && *pEnd != '\n')
++pEnd;

if (pEnd < pStop)
{
pEnd++;
while (pEnd < pStop && isspace(*pEnd))
pEnd++;
if (*pEnd == '\n')
{
// no separator. found an unannotated note
++pEnd;
}
else if (!isalnum(*pEnd))
{
// found a separator. skip it and any following whitespace
++pEnd;

while (pEnd < pStop && isspace(*pEnd))
++pEnd;
}
}

offsetNote.SetNote(sNextNote.substr(pEnd - sNextNote.c_str()));
offsetNote.SetNote(sNextNote.substr(pEnd - sNextNote.c_str()), true);
pointerData->HasPointers |= offsetNote.IsPointer();

offsetNote.SetAddress(gsl::narrow_cast<ra::ByteAddress>(nOffset));
Expand Down
Loading
Loading