From 09bf1c3a7cdc235b4b5f925734fb012041315fc1 Mon Sep 17 00:00:00 2001 From: Jamiras Date: Sat, 3 Jan 2026 12:33:28 -0700 Subject: [PATCH 1/5] move ConsoleContext to devkit --- src/Exports.cpp | 7 +- src/RA_Integration.vcxproj | 2 - src/RA_Integration.vcxproj.filters | 6 - src/data/context/ConsoleContext.hh | 137 ----------------- src/data/context/GameContext.cpp | 4 +- src/data/models/CodeNoteModel.cpp | 7 +- src/data/models/CodeNotesModel.cpp | 1 - src/data/models/MemoryRegionsModel.cpp | 13 +- src/data/models/MemoryRegionsModel.hh | 9 +- src/data/models/TriggerValidation.cpp | 14 +- src/devkit/RADevKit.vcxproj | 4 + src/devkit/RADevKit.vcxproj.filters | 12 ++ src/devkit/context/IConsoleContext.hh | 99 +++++++++++++ src/devkit/context/IRcClient.hh | 2 +- .../context/impl}/ConsoleContext.cpp | 78 +++++----- src/devkit/context/impl/ConsoleContext.hh | 32 ++++ src/devkit/context/impl/RcClient.cpp | 8 +- src/devkit/context/impl/RcClient.hh | 4 +- src/devkit/data/AsyncObject.hh | 2 +- src/devkit/data/Memory.cpp | 4 +- src/devkit/data/MemoryRegion.hh | 140 ++++++++++++++++++ src/devkit/data/ModelCollectionBase.hh | 2 +- src/devkit/data/ModelPropertyContainer.hh | 2 +- src/devkit/data/NotifyTargetSet.hh | 2 +- src/devkit/services/Http.cpp | 10 +- src/devkit/services/IHttpRequester.hh | 4 +- src/devkit/services/ServiceLocator.hh | 6 +- src/devkit/services/impl/FileTextReader.hh | 6 +- src/devkit/services/impl/FileTextWriter.hh | 6 +- src/devkit/services/impl/StringTextReader.hh | 4 +- src/devkit/services/impl/StringTextWriter.hh | 4 +- src/devkit/util/EnumOps.hh | 6 +- src/devkit/util/GSL.cpp | 10 +- src/devkit/util/GSL.hh | 36 ++++- src/devkit/util/Log.hh | 6 +- src/services/AchievementLogicSerializer.cpp | 7 +- src/services/AchievementRuntime.cpp | 6 +- src/services/AchievementRuntimeExports.cpp | 14 +- src/services/GameIdentifier.cpp | 7 +- src/services/Initialization.cpp | 8 +- .../viewmodels/IntegrationMenuViewModel.cpp | 7 +- src/ui/viewmodels/LookupItemViewModel.hh | 4 +- src/ui/viewmodels/MemoryRegionsViewModel.cpp | 28 ++-- src/ui/viewmodels/MemorySearchViewModel.cpp | 64 ++++---- src/ui/viewmodels/MemoryViewerViewModel.cpp | 11 +- src/ui/viewmodels/MemoryWatchViewModel.cpp | 4 +- .../viewmodels/PointerInspectorViewModel.cpp | 8 +- src/ui/viewmodels/UnknownGameViewModel.cpp | 10 +- tests/RA_Integration.Tests.vcxproj | 2 - tests/RA_Integration.Tests.vcxproj.filters | 6 - tests/data/context/ConsoleContext_Tests.cpp | 71 ++++----- tests/data/context/GameContext_Tests.cpp | 4 +- .../data/models/CapturedTriggerHits_Tests.cpp | 2 +- tests/data/models/CodeNoteModel_Tests.cpp | 8 +- tests/data/models/CodeNotesModel_Tests.cpp | 24 +-- .../data/models/MemoryRegionsModel_Tests.cpp | 4 +- tests/data/models/TriggerValidation_Tests.cpp | 6 +- tests/devkit/RADevKit.Tests.vcxproj.vcxproj | 3 + .../RADevKit.Tests.vcxproj.vcxproj.filters | 9 ++ .../context}/mocks/MockConsoleContext.hh | 29 ++-- tests/devkit/testutil/MemoryRegionAsserts.hh | 54 +++++++ .../AchievementLogicSerializer_Tests.cpp | 16 +- .../AchievementRuntimeExports_Tests.cpp | 8 +- tests/services/AchievementRuntime_Tests.cpp | 2 +- tests/services/GameIdentifier_Tests.cpp | 6 +- .../viewmodels/CodeNotesViewModel_Tests.cpp | 4 +- .../IntegrationMenuViewModel_Tests.cpp | 4 +- .../MemoryBookmarksViewModel_Tests.cpp | 8 +- .../MemoryInspectorViewModel_Tests.cpp | 4 +- .../MemoryRegionsViewModel_Tests.cpp | 10 +- .../MemorySearchViewModel_Tests.cpp | 76 +++++----- .../MemoryViewerViewModel_Tests.cpp | 8 +- .../MemoryWatchListViewModel_Tests.cpp | 4 +- .../PointerInspectorViewModel_Tests.cpp | 12 +- .../TriggerConditionViewModel_Tests.cpp | 12 +- .../ui/viewmodels/TriggerViewModel_Tests.cpp | 4 +- .../viewmodels/UnknownGameViewModel_Tests.cpp | 4 +- 77 files changed, 742 insertions(+), 529 deletions(-) delete mode 100644 src/data/context/ConsoleContext.hh create mode 100644 src/devkit/context/IConsoleContext.hh rename src/{data/context => devkit/context/impl}/ConsoleContext.cpp (73%) create mode 100644 src/devkit/context/impl/ConsoleContext.hh create mode 100644 src/devkit/data/MemoryRegion.hh rename tests/{ => devkit/context}/mocks/MockConsoleContext.hh (54%) create mode 100644 tests/devkit/testutil/MemoryRegionAsserts.hh diff --git a/src/Exports.cpp b/src/Exports.cpp index 9577806d0..03ad55e4c 100644 --- a/src/Exports.cpp +++ b/src/Exports.cpp @@ -8,9 +8,10 @@ #include "api\IServer.hh" #include "api\impl\OfflineServer.hh" +#include "context\IConsoleContext.hh" #include "context\IRcClient.hh" +#include "context\impl\ConsoleContext.hh" -#include "data\context\ConsoleContext.hh" #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" #include "data\context\SessionTracker.hh" @@ -411,9 +412,9 @@ API const char* CCONV _RA_UserName() API void CCONV _RA_SetConsoleID(unsigned int nConsoleId) { - auto pContext = std::make_unique(ra::itoe(nConsoleId)); + auto pContext = std::make_unique(ra::itoe(nConsoleId)); RA_LOG_INFO("Console set to %u (%s)", pContext->Id(), pContext->Name()); - ra::services::ServiceLocator::Provide(std::move(pContext)); + ra::services::ServiceLocator::Provide(std::move(pContext)); if (IsExternalRcheevosClient()) ResetEmulatorMemoryRegionsForRcheevosClient(); diff --git a/src/RA_Integration.vcxproj b/src/RA_Integration.vcxproj index 4cf62937f..1b3f1580c 100644 --- a/src/RA_Integration.vcxproj +++ b/src/RA_Integration.vcxproj @@ -73,7 +73,6 @@ - @@ -220,7 +219,6 @@ - diff --git a/src/RA_Integration.vcxproj.filters b/src/RA_Integration.vcxproj.filters index f27658c0f..f87f1e472 100644 --- a/src/RA_Integration.vcxproj.filters +++ b/src/RA_Integration.vcxproj.filters @@ -420,9 +420,6 @@ Services\Impl - - Data\Context - @@ -1037,9 +1034,6 @@ Services\Impl - - Data\Context - diff --git a/src/data/context/ConsoleContext.hh b/src/data/context/ConsoleContext.hh deleted file mode 100644 index c5d3e6059..000000000 --- a/src/data/context/ConsoleContext.hh +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef RA_DATA_CONSOLECONTEXT_HH -#define RA_DATA_CONSOLECONTEXT_HH -#pragma once - -#include "RAInterface\RA_Consoles.h" -#include "data\Memory.hh" -#include "util\GSL.hh" - -#include - -namespace ra { -namespace data { -namespace context { - -class ConsoleContext -{ -public: - GSL_SUPPRESS_F6 ConsoleContext(ConsoleID nId) noexcept; - virtual ~ConsoleContext() noexcept = default; - ConsoleContext(const ConsoleContext&) noexcept = delete; - ConsoleContext& operator=(const ConsoleContext&) noexcept = delete; - ConsoleContext(ConsoleContext&&) noexcept = delete; - ConsoleContext& operator=(ConsoleContext&&) noexcept = delete; - - /// - /// Gets the unique identifier of the console. - /// - ConsoleID Id() const noexcept { GSL_SUPPRESS_ENUM3 return m_nId; } - - /// - /// Gets a descriptive name for the console. - /// - const std::wstring& Name() const noexcept { return m_sName; } - - enum class AddressType - { - /// - /// Address use is unknown. - /// - Unknown, - - /// - /// RAM that persists between sessions. Typically found on a cratridge backed up by a battery. - /// - SaveRAM, - - /// - /// Generic RAM available for temporary storage. - /// - SystemRAM, - - /// - /// Secondary address space that maps to real memory in SystemRAM. Also known as Echo RAM or Mirror RAM. - /// - VirtualRAM, - - /// - /// RAM reserved for graphical processing. - /// - VideoRAM, - - /// - /// Address reserved for interacting with system components. - /// - HardwareController, - - /// - /// Address space that maps to some segment of read only memory (typically ROM chips on the loaded cartridge) - /// - ReadOnlyMemory, - - /// - /// Address space that doesn't actually map to memory. - /// - Unused, - }; - - struct MemoryRegion - { - ra::data::ByteAddress StartAddress = 0U; - ra::data::ByteAddress EndAddress = 0U; - ra::data::ByteAddress RealAddress = 0U; - AddressType Type = AddressType::Unknown; - std::string Description; - }; - - /// - /// Gets the list of memory regions mapped for the system. - /// - const std::vector& MemoryRegions() const noexcept { return m_vRegions; } - - /// - /// Gets the memory region containing the specified address. - /// - /// Matching , nullptr if not found. - const MemoryRegion* GetMemoryRegion(ra::data::ByteAddress nAddress) const; - - /// - /// Converts a real address into the "RetroAchievements" address where the data should be. - /// - /// Converted address, or 0xFFFFFFFF if conversion could not be completed. - ra::data::ByteAddress ByteAddressFromRealAddress(ra::data::ByteAddress nRealAddress) const noexcept; - - /// - /// Converts an "RetroAchievements" address into a real address where the data might be found. - /// - /// Converted address, or 0xFFFFFFFF if conversion could not be completed. - ra::data::ByteAddress RealAddressFromByteAddress(ra::data::ByteAddress nRealAddress) const noexcept; - - /// - /// Gets the read size and mask to use for reading a pointer from memory and converting it to - /// a RetroAchievements address. - /// - /// [out] the size to read. - /// [out] the mask to apply (if 0xFFFFFFFF, no mask is necessary). - /// [out] the offset to apply (if 0, no offset is necessary). - /// true if a mapping was found, false if not. - bool GetRealAddressConversion(Memory::Size* nReadSize, uint32_t* nMask, uint32_t* nOffset) const; - - /// - /// Gets the maximum valid address for the console. - /// - ra::data::ByteAddress MaxAddress() const noexcept { return m_nMaxAddress; } - -protected: - ConsoleID m_nId{}; - std::wstring m_sName; - - std::vector m_vRegions; - ra::data::ByteAddress m_nMaxAddress = 0; -}; - -} // namespace context -} // namespace data -} // namespace ra - -#endif // !RA_DATA_CONSOLECONTEXT_HH diff --git a/src/data/context/GameContext.cpp b/src/data/context/GameContext.cpp index fb429db87..9be644dc3 100644 --- a/src/data/context/GameContext.cpp +++ b/src/data/context/GameContext.cpp @@ -7,9 +7,9 @@ #include "util\Log.hh" #include "util\Strings.hh" +#include "context\IConsoleContext.hh" #include "context\IRcClient.hh" -#include "data\context\ConsoleContext.hh" #include "data\context\EmulatorContext.hh" #include "data\context\SessionTracker.hh" #include "data\context\UserContext.hh" @@ -44,7 +44,7 @@ namespace context { static bool ValidateConsole(int nServerConsoleId) { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); if (ra::etoi(pConsoleContext.Id()) != nServerConsoleId) { switch (nServerConsoleId) diff --git a/src/data/models/CodeNoteModel.cpp b/src/data/models/CodeNoteModel.cpp index 8c03c8eb2..75aa56a2e 100644 --- a/src/data/models/CodeNoteModel.cpp +++ b/src/data/models/CodeNoteModel.cpp @@ -1,6 +1,7 @@ #include "CodeNoteModel.hh" -#include "data\context\ConsoleContext.hh" +#include "context\IConsoleContext.hh" + #include "data\context\EmulatorContext.hh" #include "services\ServiceLocator.hh" @@ -83,7 +84,7 @@ bool CodeNoteModel::HasNestedPointers() const noexcept static ra::data::ByteAddress ConvertPointer(ra::data::ByteAddress nAddress) { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); const auto nConvertedAddress = pConsoleContext.ByteAddressFromRealAddress(nAddress); if (nConvertedAddress != 0xFFFFFFFF) nAddress = nConvertedAddress; @@ -580,7 +581,7 @@ void CodeNoteModel::SetNote(const std::wstring& sNote, bool bImpliedPointer) Memory::Size CodeNoteModel::GetImpliedPointerSize() { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); Memory::Size nSize; uint32_t nMask; diff --git a/src/data/models/CodeNotesModel.cpp b/src/data/models/CodeNotesModel.cpp index 2449a8775..183e41a77 100644 --- a/src/data/models/CodeNotesModel.cpp +++ b/src/data/models/CodeNotesModel.cpp @@ -6,7 +6,6 @@ #include "api\FetchCodeNotes.hh" #include "api\UpdateCodeNote.hh" -#include "data\context\ConsoleContext.hh" #include "data\context\EmulatorContext.hh" #include "data\context\UserContext.hh" diff --git a/src/data/models/MemoryRegionsModel.cpp b/src/data/models/MemoryRegionsModel.cpp index d63fb94ad..cd14984fb 100644 --- a/src/data/models/MemoryRegionsModel.cpp +++ b/src/data/models/MemoryRegionsModel.cpp @@ -34,10 +34,10 @@ void MemoryRegionsModel::Serialize(ra::services::TextWriter& pWriter) const pWriter.Write("M0:"); } - pWriter.Write(ra::ByteAddressToString(pIter.nStartAddress)); + pWriter.Write(ra::ByteAddressToString(pIter.GetStartAddress())); pWriter.Write("-"); - pWriter.Write(ra::ByteAddressToString(pIter.nEndAddress)); - WriteQuoted(pWriter, pIter.sLabel); + pWriter.Write(ra::ByteAddressToString(pIter.GetEndAddress())); + WriteQuoted(pWriter, pIter.GetDescription()); } } @@ -61,12 +61,7 @@ bool MemoryRegionsModel::Deserialize(ra::Tokenizer& pTokenizer) void MemoryRegionsModel::AddCustomRegion(ra::data::ByteAddress nStartAddress, ra::data::ByteAddress nEndAddress, const std::wstring& sLabel) { - MemoryRegion pRegion; - pRegion.sLabel = sLabel; - pRegion.nStartAddress = nStartAddress; - pRegion.nEndAddress = nEndAddress; - - m_vRegions.push_back(pRegion); + m_vRegions.emplace_back(nStartAddress, nEndAddress, sLabel); // setting changes to Unpublished forces a write without attempting to consolidate modifications SetValue(ChangesProperty, ra::etoi(AssetChanges::Unpublished)); diff --git a/src/data/models/MemoryRegionsModel.hh b/src/data/models/MemoryRegionsModel.hh index e5f2f17e5..d16da7d93 100644 --- a/src/data/models/MemoryRegionsModel.hh +++ b/src/data/models/MemoryRegionsModel.hh @@ -4,7 +4,7 @@ #include "AssetModelBase.hh" -#include "data/Memory.hh" +#include "data/MemoryRegion.hh" namespace ra { namespace data { @@ -25,13 +25,6 @@ public: void Serialize(ra::services::TextWriter&) const override; bool Deserialize(ra::Tokenizer&) override; - struct MemoryRegion - { - std::wstring sLabel; - ra::data::ByteAddress nStartAddress = 0; - ra::data::ByteAddress nEndAddress = 0; - }; - const std::vector& CustomRegions() const noexcept { return m_vRegions; } void ResetCustomRegions(); diff --git a/src/data/models/TriggerValidation.cpp b/src/data/models/TriggerValidation.cpp index b6862ae1c..a94873f0f 100644 --- a/src/data/models/TriggerValidation.cpp +++ b/src/data/models/TriggerValidation.cpp @@ -1,14 +1,16 @@ #include "TriggerValidation.hh" -#include "util\Strings.hh" +#include "context/IConsoleContext.hh" + +#include "services/ServiceLocator.hh" + +#include "util/Strings.hh" + #include "RA_Defs.h" -#include "data/context/ConsoleContext.hh" #include "data/context/GameContext.hh" #include "data/context/EmulatorContext.hh" -#include "services/ServiceLocator.hh" - #include #include @@ -225,9 +227,9 @@ bool TriggerValidation::Validate(const std::string& sTrigger, std::wstring& sErr char sErrorBuffer[256] = ""; int nResult = 1; - if (ra::services::ServiceLocator::Exists()) + if (ra::services::ServiceLocator::Exists()) { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); unsigned nMaxAddress = pConsoleContext.MaxAddress(); if (nMaxAddress == 0) diff --git a/src/devkit/RADevKit.vcxproj b/src/devkit/RADevKit.vcxproj index 868d26dee..47a914585 100644 --- a/src/devkit/RADevKit.vcxproj +++ b/src/devkit/RADevKit.vcxproj @@ -57,6 +57,7 @@ + @@ -68,12 +69,15 @@ + + + diff --git a/src/devkit/RADevKit.vcxproj.filters b/src/devkit/RADevKit.vcxproj.filters index f55b15350..f6d63ddcd 100644 --- a/src/devkit/RADevKit.vcxproj.filters +++ b/src/devkit/RADevKit.vcxproj.filters @@ -117,6 +117,15 @@ data + + context + + + context\impl + + + data + @@ -152,5 +161,8 @@ data + + context\impl + \ No newline at end of file diff --git a/src/devkit/context/IConsoleContext.hh b/src/devkit/context/IConsoleContext.hh new file mode 100644 index 000000000..1ab857d8a --- /dev/null +++ b/src/devkit/context/IConsoleContext.hh @@ -0,0 +1,99 @@ +#ifndef RA_CONTEXT_ICONSOLECONTEXT_HH +#define RA_CONTEXT_ICONSOLECONTEXT_HH +#pragma once + +#include "RAInterface/RA_Consoles.h" +#include "data/MemoryRegion.hh" +#include "util/GSL.hh" + +#include + +namespace ra { +namespace context { + +class IConsoleContext +{ +public: + IConsoleContext() noexcept = default; + virtual ~IConsoleContext() noexcept = default; + IConsoleContext(const IConsoleContext&) noexcept = delete; + IConsoleContext& operator=(const IConsoleContext&) noexcept = delete; + IConsoleContext(IConsoleContext&&) noexcept = delete; + IConsoleContext& operator=(IConsoleContext&&) noexcept = delete; + + /// + /// Gets the unique identifier of the console. + /// + ConsoleID Id() const noexcept { GSL_SUPPRESS_ENUM3 return m_nId; } + + /// + /// Gets a descriptive name for the console. + /// + const std::wstring& Name() const noexcept { return m_sName; } + + /// + /// Gets the list of memory regions mapped for the system. + /// + const std::vector& MemoryRegions() const noexcept { return m_vRegions; } + + /// + /// Gets the memory region containing the specified address. + /// + /// Matching , nullptr if not found. + virtual const ra::data::MemoryRegion* GetMemoryRegion(ra::data::ByteAddress nAddress) const = 0; + + /// + /// Converts a real address into the "RetroAchievements" address where the data should be. + /// + /// Converted address, or 0xFFFFFFFF if conversion could not be completed. + virtual ra::data::ByteAddress ByteAddressFromRealAddress(ra::data::ByteAddress nByteAddress) const noexcept + { + return nByteAddress; + } + + /// + /// Converts an "RetroAchievements" address into a real address where the data might be found. + /// + /// Converted address, or 0xFFFFFFFF if conversion could not be completed. + virtual ra::data::ByteAddress RealAddressFromByteAddress(ra::data::ByteAddress nRealAddress) const noexcept + { + return nRealAddress; + } + + /// + /// Gets the read size and mask to use for reading a pointer from memory and converting it to + /// a RetroAchievements address. + /// + /// [out] the size to read. + /// [out] the mask to apply (if 0xFFFFFFFF, no mask is necessary). + /// [out] the offset to apply (if 0, no offset is necessary). + /// true if a mapping was found, false if not. + virtual bool GetRealAddressConversion(ra::data::Memory::Size* nReadSize, uint32_t* nMask, uint32_t* nOffset) const + { + Expects(nReadSize != nullptr); + Expects(nMask != nullptr); + Expects(nOffset != nullptr); + + *nReadSize = ra::data::Memory::Size::ThirtyTwoBit; + *nMask = 0xFFFFFFFF; + *nOffset = 0; + return false; + } + + /// + /// Gets the maximum valid address for the console. + /// + ra::data::ByteAddress MaxAddress() const noexcept { return m_nMaxAddress; } + +protected: + ConsoleID m_nId{}; + std::wstring m_sName; + + std::vector m_vRegions; + ra::data::ByteAddress m_nMaxAddress = 0; +}; + +} // namespace context +} // namespace ra + +#endif // !RA_CONTEXT_ICONSOLECONTEXT_HH diff --git a/src/devkit/context/IRcClient.hh b/src/devkit/context/IRcClient.hh index e14ccd3a4..c5d82360f 100644 --- a/src/devkit/context/IRcClient.hh +++ b/src/devkit/context/IRcClient.hh @@ -2,7 +2,7 @@ #define RA_CONTEXT_IRCCLIENT_H #pragma once -#include +#include #include #include diff --git a/src/data/context/ConsoleContext.cpp b/src/devkit/context/impl/ConsoleContext.cpp similarity index 73% rename from src/data/context/ConsoleContext.cpp rename to src/devkit/context/impl/ConsoleContext.cpp index 5d5165985..4cc81da3a 100644 --- a/src/data/context/ConsoleContext.cpp +++ b/src/devkit/context/impl/ConsoleContext.cpp @@ -1,13 +1,12 @@ #include "ConsoleContext.hh" -#include "util\Log.hh" -#include "util\Strings.hh" +#include "util/Strings.hh" #include namespace ra { -namespace data { namespace context { +namespace impl { ConsoleContext::ConsoleContext(ConsoleID nId) noexcept { @@ -22,37 +21,34 @@ ConsoleContext::ConsoleContext(ConsoleID nId) noexcept { const auto& pRegion = pRegions->region[i]; - auto& pMemoryRegion = m_vRegions.emplace_back(); - pMemoryRegion.StartAddress = pRegion.start_address; - pMemoryRegion.EndAddress = pRegion.end_address; - pMemoryRegion.RealAddress = pRegion.real_address; - pMemoryRegion.Description = pRegion.description; + auto& pMemoryRegion = m_vRegions.emplace_back(pRegion.start_address, pRegion.end_address, ra::Widen(pRegion.description)); + pMemoryRegion.SetRealStartAddress(pRegion.real_address); switch (pRegion.type) { case RC_MEMORY_TYPE_HARDWARE_CONTROLLER: - pMemoryRegion.Type = AddressType::HardwareController; + pMemoryRegion.SetType(ra::data::MemoryRegion::Type::HardwareController); break; case RC_MEMORY_TYPE_READONLY: - pMemoryRegion.Type = AddressType::ReadOnlyMemory; + pMemoryRegion.SetType(ra::data::MemoryRegion::Type::ReadOnlyMemory); break; case RC_MEMORY_TYPE_SAVE_RAM: - pMemoryRegion.Type = AddressType::SaveRAM; + pMemoryRegion.SetType(ra::data::MemoryRegion::Type::SaveRAM); break; case RC_MEMORY_TYPE_SYSTEM_RAM: - pMemoryRegion.Type = AddressType::SystemRAM; + pMemoryRegion.SetType(ra::data::MemoryRegion::Type::SystemRAM); break; case RC_MEMORY_TYPE_UNUSED: - pMemoryRegion.Type = AddressType::Unused; + pMemoryRegion.SetType(ra::data::MemoryRegion::Type::Unused); break; case RC_MEMORY_TYPE_VIDEO_RAM: - pMemoryRegion.Type = AddressType::VideoRAM; + pMemoryRegion.SetType(ra::data::MemoryRegion::Type::VideoRAM); break; case RC_MEMORY_TYPE_VIRTUAL_RAM: - pMemoryRegion.Type = AddressType::VirtualRAM; + pMemoryRegion.SetType(ra::data::MemoryRegion::Type::VirtualRAM); break; default: - pMemoryRegion.Type = AddressType::Unknown; + pMemoryRegion.SetType(ra::data::MemoryRegion::Type::Unknown); break; } @@ -61,7 +57,7 @@ ConsoleContext::ConsoleContext(ConsoleID nId) noexcept } } -const ConsoleContext::MemoryRegion* ConsoleContext::GetMemoryRegion(ra::data::ByteAddress nAddress) const +const ra::data::MemoryRegion* ConsoleContext::GetMemoryRegion(ra::data::ByteAddress nAddress) const { const auto& vRegions = MemoryRegions(); gsl::index nStart = 0; @@ -70,9 +66,9 @@ const ConsoleContext::MemoryRegion* ConsoleContext::GetMemoryRegion(ra::data::By { const gsl::index nMid = (nStart + nEnd) / 2; const auto& pRegion = vRegions.at(nMid); - if (pRegion.StartAddress > nAddress) + if (pRegion.GetStartAddress() > nAddress) nEnd = nMid - 1; - else if (pRegion.EndAddress < nAddress) + else if (pRegion.GetEndAddress() < nAddress) nStart = nMid + 1; else return &pRegion; @@ -85,16 +81,12 @@ ra::data::ByteAddress ConsoleContext::ByteAddressFromRealAddress(ra::data::ByteA { for (const auto& pRegion : m_vRegions) { - if (pRegion.RealAddress < nRealAddress) + if (pRegion.ContainsRealAddress(nRealAddress)) { - const auto nRegionSize = pRegion.EndAddress - pRegion.StartAddress; - if (nRealAddress < pRegion.RealAddress + nRegionSize) - { - if (pRegion.Type == ConsoleContext::AddressType::Unused) - break; + if (pRegion.GetType() == ra::data::MemoryRegion::Type::Unused) + break; - return (nRealAddress - pRegion.RealAddress) + pRegion.StartAddress; - } + return (nRealAddress - pRegion.GetRealStartAddress()) + pRegion.GetStartAddress(); } } @@ -156,14 +148,14 @@ ra::data::ByteAddress ConsoleContext::RealAddressFromByteAddress(ra::data::ByteA { for (const auto& pRegion : m_vRegions) { - if (pRegion.EndAddress >= nByteAddress && pRegion.StartAddress <= nByteAddress) - return nByteAddress + pRegion.RealAddress; + if (pRegion.ContainsAddress(nByteAddress)) + return pRegion.GetRealStartAddress() + nByteAddress; } return 0xFFFFFFFF; } -bool ConsoleContext::GetRealAddressConversion(Memory::Size* nReadSize, uint32_t* nMask, uint32_t* nOffset) const +bool ConsoleContext::GetRealAddressConversion(ra::data::Memory::Size* nReadSize, uint32_t* nMask, uint32_t* nOffset) const { Expects(nReadSize != nullptr); Expects(nMask != nullptr); @@ -175,26 +167,26 @@ bool ConsoleContext::GetRealAddressConversion(Memory::Size* nReadSize, uint32_t* case ConsoleID::DSi: case ConsoleID::N64: case ConsoleID::PlayStation: - *nReadSize = Memory::Size::TwentyFourBit; + *nReadSize = ra::data::Memory::Size::TwentyFourBit; *nMask = 0xFFFFFFFF; *nOffset = 0; return true; case ConsoleID::GameCube: - *nReadSize = Memory::Size::ThirtyTwoBitBigEndian; + *nReadSize = ra::data::Memory::Size::ThirtyTwoBitBigEndian; *nMask = 0x01FFFFFF; *nOffset = 0; return true; case ConsoleID::WII: - *nReadSize = Memory::Size::ThirtyTwoBitBigEndian; + *nReadSize = ra::data::Memory::Size::ThirtyTwoBitBigEndian; *nMask = 0x1FFFFFFF; *nOffset = 0; return true; case ConsoleID::PlayStation2: case ConsoleID::PSP: - *nReadSize = Memory::Size::ThirtyTwoBit; + *nReadSize = ra::data::Memory::Size::ThirtyTwoBit; *nMask = 0x01FFFFFF; *nOffset = 0; return true; @@ -206,7 +198,7 @@ bool ConsoleContext::GetRealAddressConversion(Memory::Size* nReadSize, uint32_t* // However, most developers who have implemented sets just do a 24-bit // read _and_ use a +0x8000 offset when necessary. As these offsets are // encoded in the code notes, we shouldn't provide an explicit offset here. - *nReadSize = Memory::Size::TwentyFourBit; + *nReadSize = ra::data::Memory::Size::TwentyFourBit; *nMask = 0x00FFFFFF; *nOffset = 0; return true; @@ -214,41 +206,41 @@ bool ConsoleContext::GetRealAddressConversion(Memory::Size* nReadSize, uint32_t* default: for (const auto& pRegion : m_vRegions) { - if (pRegion.Type == AddressType::SystemRAM) + if (pRegion.GetType() == ra::data::MemoryRegion::Type::SystemRAM) { if (m_nMaxAddress > 0x00FFFFFF) { - *nReadSize = Memory::Size::ThirtyTwoBit; + *nReadSize = ra::data::Memory::Size::ThirtyTwoBit; *nMask = 0xFFFFFFFF; } else if (m_nMaxAddress > 0x0000FFFF) { - *nReadSize = Memory::Size::TwentyFourBit; + *nReadSize = ra::data::Memory::Size::TwentyFourBit; *nMask = 0x00FFFFFF; } else if (m_nMaxAddress > 0x000000FF) { - *nReadSize = Memory::Size::SixteenBit; + *nReadSize = ra::data::Memory::Size::SixteenBit; *nMask = 0x0000FFFF; } else { - *nReadSize = Memory::Size::EightBit; + *nReadSize = ra::data::Memory::Size::EightBit; *nMask = 0x000000FF; } - *nOffset = (pRegion.RealAddress - pRegion.StartAddress) & *nMask; + *nOffset = (pRegion.GetRealStartAddress() - pRegion.GetStartAddress()) & *nMask; return true; } } - *nReadSize = Memory::Size::ThirtyTwoBit; + *nReadSize = ra::data::Memory::Size::ThirtyTwoBit; *nMask = 0xFFFFFFFF; *nOffset = 0; return false; } } +} // namespace impl } // namespace context -} // namespace data } // namespace ra diff --git a/src/devkit/context/impl/ConsoleContext.hh b/src/devkit/context/impl/ConsoleContext.hh new file mode 100644 index 000000000..65513fdd2 --- /dev/null +++ b/src/devkit/context/impl/ConsoleContext.hh @@ -0,0 +1,32 @@ +#ifndef RA_CONTEXT_IMPL_CONSOLECONTEXT_HH +#define RA_CONTEXT_IMPL_CONSOLECONTEXT_HH +#pragma once + +#include "context/IConsoleContext.hh" + +namespace ra { +namespace context { +namespace impl { + +class ConsoleContext : public IConsoleContext +{ +public: + GSL_SUPPRESS_F6 ConsoleContext(ConsoleID nId) noexcept; + virtual ~ConsoleContext() noexcept = default; + ConsoleContext(const ConsoleContext&) noexcept = delete; + ConsoleContext& operator=(const ConsoleContext&) noexcept = delete; + ConsoleContext(ConsoleContext&&) noexcept = delete; + ConsoleContext& operator=(ConsoleContext&&) noexcept = delete; + + const ra::data::MemoryRegion* GetMemoryRegion(ra::data::ByteAddress nAddress) const override; + + ra::data::ByteAddress ByteAddressFromRealAddress(ra::data::ByteAddress nRealAddress) const noexcept override; + ra::data::ByteAddress RealAddressFromByteAddress(ra::data::ByteAddress nRealAddress) const noexcept override; + bool GetRealAddressConversion(ra::data::Memory::Size* nReadSize, uint32_t* nMask, uint32_t* nOffset) const override; +}; + +} // namespace impl +} // namespace context +} // namespace ra + +#endif // !RA_CONTEXT_IMPL_CONSOLECONTEXT_HH diff --git a/src/devkit/context/impl/RcClient.cpp b/src/devkit/context/impl/RcClient.cpp index 7742b762a..07cac1029 100644 --- a/src/devkit/context/impl/RcClient.cpp +++ b/src/devkit/context/impl/RcClient.cpp @@ -1,11 +1,11 @@ #include "RcClient.hh" -#include "services\IHttpRequester.hh" -#include "services\ServiceLocator.hh" +#include "services/IHttpRequester.hh" +#include "services/ServiceLocator.hh" -#include "util\Log.hh" +#include "util/Log.hh" -#include +#include namespace ra { namespace context { diff --git a/src/devkit/context/impl/RcClient.hh b/src/devkit/context/impl/RcClient.hh index 6f91655eb..d3c95ced8 100644 --- a/src/devkit/context/impl/RcClient.hh +++ b/src/devkit/context/impl/RcClient.hh @@ -2,9 +2,9 @@ #define RA_CONTEXT_IMPL_RCCLIENT_H #pragma once -#include "context\IRcClient.hh" +#include "context/IRcClient.hh" -#include "services\Http.hh" +#include "services/Http.hh" namespace ra { namespace context { diff --git a/src/devkit/data/AsyncObject.hh b/src/devkit/data/AsyncObject.hh index c1897a2a6..24c5801d2 100644 --- a/src/devkit/data/AsyncObject.hh +++ b/src/devkit/data/AsyncObject.hh @@ -2,7 +2,7 @@ #define RA_DATA_ASYNCOBJECT_HH #pragma once -#include "util\GSL.hh" +#include "util/GSL.hh" namespace ra { namespace data { diff --git a/src/devkit/data/Memory.cpp b/src/devkit/data/Memory.cpp index ef93901b5..92842aab1 100644 --- a/src/devkit/data/Memory.cpp +++ b/src/devkit/data/Memory.cpp @@ -1,9 +1,9 @@ #include "Memory.hh" -#include "util\Strings.hh" +#include "util/Strings.hh" #include -#include +#include namespace ra { namespace data { diff --git a/src/devkit/data/MemoryRegion.hh b/src/devkit/data/MemoryRegion.hh new file mode 100644 index 000000000..eb63da901 --- /dev/null +++ b/src/devkit/data/MemoryRegion.hh @@ -0,0 +1,140 @@ +#ifndef RA_DATA_MEMORYREGION_H +#define RA_DATA_MEMORYREGION_H +#pragma once + +#include "Memory.hh" + +namespace ra { +namespace data { + +class MemoryRegion +{ +public: + MemoryRegion(ra::data::ByteAddress nStartAddress, ra::data::ByteAddress nEndAddress, const std::wstring& sDescription) + : m_sDescription(sDescription), m_nStartAddress(nStartAddress), m_nEndAddress(nEndAddress) + { + } + + ~MemoryRegion() = default; + MemoryRegion(const MemoryRegion&) noexcept = default; + MemoryRegion& operator=(const MemoryRegion&) noexcept = default; + MemoryRegion(MemoryRegion&&) noexcept = default; + MemoryRegion& operator=(MemoryRegion&&) noexcept = default; + + enum class Type + { + /// + /// Address use is unknown. + /// + Unknown, + + /// + /// RAM that persists between sessions. Typically found on a cratridge backed up by a battery. + /// + SaveRAM, + + /// + /// Generic RAM available for temporary storage. + /// + SystemRAM, + + /// + /// Secondary address space that maps to real memory in SystemRAM. Also known as Echo RAM or Mirror RAM. + /// + VirtualRAM, + + /// + /// RAM reserved for graphical processing. + /// + VideoRAM, + + /// + /// Address reserved for interacting with system components. + /// + HardwareController, + + /// + /// Address space that maps to some segment of read only memory (typically ROM chips on the loaded cartridge) + /// + ReadOnlyMemory, + + /// + /// Address space that doesn't actually map to memory. + /// + Unused, + }; + + /// + /// Gets the description of the region. + /// + const std::wstring& GetDescription() const noexcept { return m_sDescription; } + + /// + /// Gets the first RetroAchievements address of the region. + /// + const ra::data::ByteAddress GetStartAddress() const noexcept { return m_nStartAddress; } + + /// + /// Gets the last RetroAchievements address of the region. + /// + const ra::data::ByteAddress GetEndAddress() const noexcept { return m_nEndAddress; } + + /// + /// Sets the last RetroAchievements address of the region. + /// + void SetEndAddress(ra::data::ByteAddress nAddress) noexcept { m_nEndAddress = nAddress; } + + /// + /// Gets the number of addresses in the region. + /// + const uint32_t GetSize() const noexcept { return m_nEndAddress - m_nStartAddress + 1; } + + /// + /// Determines if an RetroAchievements address is in the region. + /// + bool ContainsAddress(ra::data::ByteAddress nAddress) const noexcept + { + return (nAddress >= m_nStartAddress && nAddress <= m_nEndAddress); + } + + /// + /// Gets the type of the region. + /// + const Type GetType() const noexcept { return m_nType; } + + /// + /// Gets the type of the region. + /// + void SetType(Type nType) noexcept { m_nType = nType; } + + /// + /// Gets the first real address of the region. + /// + const ra::data::ByteAddress GetRealStartAddress() const noexcept { return m_nRealStartAddress; } + + /// + /// Sets the first real address of the region. + /// + void SetRealStartAddress(ra::data::ByteAddress nAddress) noexcept { m_nRealStartAddress = nAddress; } + + /// + /// Determines if a real address is in the region. + /// + bool ContainsRealAddress(ra::data::ByteAddress nAddress) const noexcept + { + return (nAddress >= m_nRealStartAddress && + nAddress <= m_nRealStartAddress + (m_nEndAddress - m_nStartAddress)); + } + +private: + std::wstring m_sDescription; + ra::data::ByteAddress m_nStartAddress = 0U; + ra::data::ByteAddress m_nEndAddress = 0U; + ra::data::ByteAddress m_nRealStartAddress = 0U; + Type m_nType = Type::Unknown; +}; + +} // namespace data +} // namespace ra + +#endif RA_DATA_MEMORYREGION_H diff --git a/src/devkit/data/ModelCollectionBase.hh b/src/devkit/data/ModelCollectionBase.hh index b78264169..4acd0d6cc 100644 --- a/src/devkit/data/ModelCollectionBase.hh +++ b/src/devkit/data/ModelCollectionBase.hh @@ -4,7 +4,7 @@ #include "ModelBase.hh" -#include "util\TypeCasts.hh" +#include "util/TypeCasts.hh" namespace ra { namespace data { diff --git a/src/devkit/data/ModelPropertyContainer.hh b/src/devkit/data/ModelPropertyContainer.hh index f57427a81..b19a4768d 100644 --- a/src/devkit/data/ModelPropertyContainer.hh +++ b/src/devkit/data/ModelPropertyContainer.hh @@ -2,7 +2,7 @@ #define RA_DATA_MODEL_PROPERTY_CONTAINER_H #pragma once -#include "data\ModelProperty.hh" +#include "data/ModelProperty.hh" #include diff --git a/src/devkit/data/NotifyTargetSet.hh b/src/devkit/data/NotifyTargetSet.hh index fa675ca6b..81c66aa5c 100644 --- a/src/devkit/data/NotifyTargetSet.hh +++ b/src/devkit/data/NotifyTargetSet.hh @@ -2,7 +2,7 @@ #define RA_DATA_NOTIFYTARGET_SET_H #pragma once -#include "util\GSL.hh" +#include "util/GSL.hh" namespace ra { namespace data { diff --git a/src/devkit/services/Http.cpp b/src/devkit/services/Http.cpp index d527f0d1e..1a0f15983 100644 --- a/src/devkit/services/Http.cpp +++ b/src/devkit/services/Http.cpp @@ -1,11 +1,11 @@ #include "Http.hh" -#include "services\IFileSystem.hh" -#include "services\IHttpRequester.hh" -#include "services\IThreadPool.hh" -#include "services\ServiceLocator.hh" +#include "services/IFileSystem.hh" +#include "services/IHttpRequester.hh" +#include "services/IThreadPool.hh" +#include "services/ServiceLocator.hh" -#include "services\impl\StringTextWriter.hh" +#include "services/impl/StringTextWriter.hh" namespace ra { namespace services { diff --git a/src/devkit/services/IHttpRequester.hh b/src/devkit/services/IHttpRequester.hh index 6eb656f81..9607fc985 100644 --- a/src/devkit/services/IHttpRequester.hh +++ b/src/devkit/services/IHttpRequester.hh @@ -2,8 +2,8 @@ #define RA_SERVICES_IHTTP_REQUESTER_H #pragma once -#include "services\Http.hh" -#include "services\TextWriter.hh" +#include "services/Http.hh" +#include "services/TextWriter.hh" namespace ra { namespace services { diff --git a/src/devkit/services/ServiceLocator.hh b/src/devkit/services/ServiceLocator.hh index 30d3592d2..90bdfa8cd 100644 --- a/src/devkit/services/ServiceLocator.hh +++ b/src/devkit/services/ServiceLocator.hh @@ -2,10 +2,10 @@ #define RA_SERVICE_LOCATOR_HH #pragma once -#include "services\ILogger.hh" +#include "services/ILogger.hh" #ifndef NDEBUG -#include "util\Strings.hh" +#include "util/Strings.hh" #endif #include @@ -62,10 +62,8 @@ public: template static void Provide(std::unique_ptr pInstance) noexcept { -#ifdef RA_UTEST if (!Service::s_bDestroy) Service::s_pInstance.release(); -#endif Service::s_pInstance = std::move(pInstance); } diff --git a/src/devkit/services/impl/FileTextReader.hh b/src/devkit/services/impl/FileTextReader.hh index deb6486b6..29ef3db4d 100644 --- a/src/devkit/services/impl/FileTextReader.hh +++ b/src/devkit/services/impl/FileTextReader.hh @@ -2,9 +2,11 @@ #define RA_SERVICES_FILETEXTREADER #pragma once -#include "services\TextReader.hh" +#include "services/TextReader.hh" -#include "util\Strings.hh" +#include "util/Strings.hh" + +#include namespace ra { namespace services { diff --git a/src/devkit/services/impl/FileTextWriter.hh b/src/devkit/services/impl/FileTextWriter.hh index 716ab46e1..48484b4be 100644 --- a/src/devkit/services/impl/FileTextWriter.hh +++ b/src/devkit/services/impl/FileTextWriter.hh @@ -2,9 +2,11 @@ #define RA_SERVICES_FILETEXTWRITER #pragma once -#include "services\TextWriter.hh" +#include "services/TextWriter.hh" -#include "util\Strings.hh" +#include "util/Strings.hh" + +#include namespace ra { namespace services { diff --git a/src/devkit/services/impl/StringTextReader.hh b/src/devkit/services/impl/StringTextReader.hh index c9c359002..d3d1b32ee 100644 --- a/src/devkit/services/impl/StringTextReader.hh +++ b/src/devkit/services/impl/StringTextReader.hh @@ -2,9 +2,9 @@ #define RA_SERVICES_STRINGTEXTREADER #pragma once -#include "services\TextReader.hh" +#include "services/TextReader.hh" -#include "util\Strings.hh" +#include "util/Strings.hh" namespace ra { namespace services { diff --git a/src/devkit/services/impl/StringTextWriter.hh b/src/devkit/services/impl/StringTextWriter.hh index 6070f23b4..1bbb1878b 100644 --- a/src/devkit/services/impl/StringTextWriter.hh +++ b/src/devkit/services/impl/StringTextWriter.hh @@ -2,9 +2,9 @@ #define RA_SERVICES_STRINGTEXTWRITER #pragma once -#include "services\TextWriter.hh" +#include "services/TextWriter.hh" -#include "util\Strings.hh" +#include "util/Strings.hh" namespace ra { namespace services { diff --git a/src/devkit/util/EnumOps.hh b/src/devkit/util/EnumOps.hh index c443cf42f..8c216d8d8 100644 --- a/src/devkit/util/EnumOps.hh +++ b/src/devkit/util/EnumOps.hh @@ -2,9 +2,9 @@ #define RA_ENUM_OPS_H #pragma once -#include "util\Compat.hh" -#include "util\TypeCasts.hh" -#include "util\TypeTraits.hh" +#include "util/Compat.hh" +#include "util/TypeCasts.hh" +#include "util/TypeTraits.hh" namespace ra { diff --git a/src/devkit/util/GSL.cpp b/src/devkit/util/GSL.cpp index f26edbc2b..b45a4a162 100644 --- a/src/devkit/util/GSL.cpp +++ b/src/devkit/util/GSL.cpp @@ -1,11 +1,11 @@ #include "gsl.hh" -#include "services\ILogger.hh" -#include "services\IMessageDispatcher.hh" -#include "services\ServiceLocator.hh" +#include "services/ILogger.hh" +#include "services/IMessageDispatcher.hh" +#include "services/ServiceLocator.hh" -#include "util\Log.hh" -#include "util\Strings.hh" +#include "util/Log.hh" +#include "util/Strings.hh" static inline constexpr const char* __gsl_filename(const char* const str) { diff --git a/src/devkit/util/GSL.hh b/src/devkit/util/GSL.hh index c780490f2..0b38b2515 100644 --- a/src/devkit/util/GSL.hh +++ b/src/devkit/util/GSL.hh @@ -3,7 +3,7 @@ #pragma once #define GSL_THROW_ON_CONTRACT_VIOLATION -#include +#include // the default GSL Expects() macro throws an exception, which we don't try to catch anywhere. // replace it with our custom handler, which will log and report the error before throwing it. @@ -21,23 +21,53 @@ /* Use these for code analysis suppressions if needed */ /* clang-format off */ + +// prefer gsl::at() instead of unchecked subscript operator #define GSL_SUPPRESS_BOUNDS4 GSL_SUPPRESS(bounds.4) + +// method hides a non-virtual method #define GSL_SUPPRESS_C128 GSL_SUPPRESS(c.128) + +// pointer parameter can be marked const #define GSL_SUPPRESS_CON3 GSL_SUPPRESS(con.3) + +// variable is assigned only once, mark it as const #define GSL_SUPPRESS_CON4 GSL_SUPPRESS(con.4) + +// prefer enum class over plain enum #define GSL_SUPPRESS_ENUM3 GSL_SUPPRESS(enum.3) + +// use nullptr rather than 0 or NULL #define GSL_SUPPRESS_ES47 GSL_SUPPRESS(es.47) -#define GSL_SUPPRESS_F4 GSL_SUPPRESS(f.4) + +// function can be declared 'noexcept' or +// function is declared 'noexcept' but calls function which may throw exceptions #define GSL_SUPPRESS_F6 GSL_SUPPRESS(f.6) + +// variable is never tested for nullness, it can be marked as not_null #define GSL_SUPPRESS_F23 GSL_SUPPRESS(f.23) -#define GSL_SUPPRESS_IO5 GSL_SUPPRESS(io.5) + +// non-smart pointer #define GSL_SUPPRESS_R3 GSL_SUPPRESS(r.3) + +// don't pass smart pointer to function; pass object pointer or object reference #define GSL_SUPPRESS_R30 GSL_SUPPRESS(r.30) + +// don't pass smart pointer to function; pass object pointer or object reference #define GSL_SUPPRESS_R32 GSL_SUPPRESS(r.32) + +// don't use reinterpret_cast or unneccessary cast #define GSL_SUPPRESS_TYPE1 GSL_SUPPRESS(type.1) + +// don't use const_cast to cast away const #define GSL_SUPPRESS_TYPE3 GSL_SUPPRESS(type.3) + +// don't use c-style casts #define GSL_SUPPRESS_TYPE4 GSL_SUPPRESS(type.4) + +// always initialize a variable #define GSL_SUPPRESS_TYPE6 GSL_SUPPRESS(type.6) + /* clang-format on */ #endif /* !RA_GSL_HH */ diff --git a/src/devkit/util/Log.hh b/src/devkit/util/Log.hh index abf694a6d..e8ef742c7 100644 --- a/src/devkit/util/Log.hh +++ b/src/devkit/util/Log.hh @@ -2,7 +2,7 @@ #define RA_LOG_HH #pragma once -#include "services\ILogger.hh" +#include "services/ILogger.hh" #ifdef RA_UTEST @@ -10,8 +10,8 @@ #else -#include "services\ServiceLocator.hh" -#include "util\Strings.hh" +#include "services/ServiceLocator.hh" +#include "util/Strings.hh" #define RA_LOG_LEVEL(lvl, ...) \ { \ diff --git a/src/services/AchievementLogicSerializer.cpp b/src/services/AchievementLogicSerializer.cpp index 7666838ba..b185bd6d0 100644 --- a/src/services/AchievementLogicSerializer.cpp +++ b/src/services/AchievementLogicSerializer.cpp @@ -1,12 +1,13 @@ #include "AchievementLogicSerializer.hh" #include "RA_Defs.h" -#include "util\Strings.hh" -#include "data\context\ConsoleContext.hh" +#include "context\IConsoleContext.hh" #include "services\ServiceLocator.hh" +#include "util\Strings.hh" + namespace ra { namespace services { @@ -307,7 +308,7 @@ std::string AchievementLogicSerializer::BuildMemRefChain(const ra::data::models: uint32_t nMask = 0xFFFFFFFF; uint32_t nOffset = 0; - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); if (!pConsoleContext.GetRealAddressConversion(&nSize, &nMask, &nOffset)) { nSize = pRootNote.GetMemSize(); diff --git a/src/services/AchievementRuntime.cpp b/src/services/AchievementRuntime.cpp index f32df786c..2ff6cd441 100644 --- a/src/services/AchievementRuntime.cpp +++ b/src/services/AchievementRuntime.cpp @@ -11,9 +11,9 @@ #include "RA_md5factory.h" +#include "context\IConsoleContext.hh" #include "context\IRcClient.hh" -#include "data\context\ConsoleContext.hh" #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" #include "data\context\SessionTracker.hh" @@ -162,7 +162,7 @@ static uint32_t IdentifyUnknownHash(uint32_t console_id, const char* hash, rc_cl auto sEstimatedGameTitle = ra::Widen(pEmulatorContext.GetGameTitle()); if (console_id == RC_CONSOLE_UNKNOWN) - console_id = ra::services::ServiceLocator::Get().Id(); + console_id = ra::services::ServiceLocator::Get().Id(); ra::ui::viewmodels::UnknownGameViewModel vmUnknownGame; vmUnknownGame.InitializeGameTitles(ra::itoe(console_id)); @@ -1264,7 +1264,7 @@ void AchievementRuntime::LoadGameCallback(int nResult, const char* sErrorMessage // doesn't flag every achievement as invalid. if (IsExternalRcheevosClient() && pClient->game) { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); if (pConsoleContext.Id() != ra::itoe(pClient->game->public_.console_id) && pClient->game->public_.console_id != 0) { diff --git a/src/services/AchievementRuntimeExports.cpp b/src/services/AchievementRuntimeExports.cpp index 231d6f9a1..6c21c3569 100644 --- a/src/services/AchievementRuntimeExports.cpp +++ b/src/services/AchievementRuntimeExports.cpp @@ -4,9 +4,9 @@ #include "util\Log.hh" #include "RA_Resource.h" +#include "context\IConsoleContext.hh" #include "context\IRcClient.hh" -#include "data\context\ConsoleContext.hh" #include "data\context\GameContext.hh" #include "services\IConfiguration.hh" @@ -81,7 +81,7 @@ class AchievementRuntimeExports : private AchievementRuntime public: static void ResetMemory() { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); pEmulatorContext.ClearMemoryBlocks(); @@ -90,9 +90,9 @@ class AchievementRuntimeExports : private AchievementRuntime uint32_t nBytes = 0; for (const auto& pRegion : pConsoleContext.MemoryRegions()) { - const auto nSize = pRegion.EndAddress - pRegion.StartAddress + 1; + const auto nSize = pRegion.GetSize(); - if (pRegion.Type == ra::data::context::ConsoleContext::AddressType::Unused) + if (pRegion.GetType() == ra::data::MemoryRegion::Type::Unused) { if (nBytes > 0) { @@ -104,13 +104,13 @@ class AchievementRuntimeExports : private AchievementRuntime nBytes = 0; ++nIndex; - s_memoryBlockWrappers.at(nIndex).nOffset = pRegion.StartAddress; + s_memoryBlockWrappers.at(nIndex).nOffset = pRegion.GetStartAddress(); } pEmulatorContext.AddMemoryBlock(nIndex++, nSize, nullptr, nullptr); Expects(gsl::narrow_cast(nIndex) < s_memoryBlockWrappers.size()); - s_memoryBlockWrappers.at(nIndex).nOffset = pRegion.EndAddress + 1; + s_memoryBlockWrappers.at(nIndex).nOffset = pRegion.GetEndAddress() + 1; } else { @@ -338,7 +338,7 @@ class AchievementRuntimeExports : private AchievementRuntime auto& pGameContext = ra::services::ServiceLocator::GetMutable(); pGameContext.SetGameHash(hash); - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); pClient->game->public_.console_id = ra::etoi(pConsoleContext.Id()); } diff --git a/src/services/GameIdentifier.cpp b/src/services/GameIdentifier.cpp index 9a0089399..e9f304003 100644 --- a/src/services/GameIdentifier.cpp +++ b/src/services/GameIdentifier.cpp @@ -7,7 +7,8 @@ #include "api\ResolveHash.hh" -#include "data\context\ConsoleContext.hh" +#include "context\IConsoleContext.hh" + #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" #include "data\context\UserContext.hh" @@ -32,7 +33,7 @@ unsigned int GameIdentifier::IdentifyGame(const BYTE* pROM, size_t nROMSize) { m_nPendingMode = ra::data::context::GameContext::Mode::Normal; - const auto nConsoleId = ra::services::ServiceLocator::Get().Id(); + const auto nConsoleId = ra::services::ServiceLocator::Get().Id(); if (nConsoleId == 0) { ra::ui::viewmodels::MessageBoxViewModel::ShowErrorMessage(L"Cannot identify game for unknown console."); @@ -128,7 +129,7 @@ unsigned int GameIdentifier::IdentifyHash(const std::string& sHash) ra::ui::viewmodels::UnknownGameViewModel vmUnknownGame; vmUnknownGame.InitializeGameTitles(); - vmUnknownGame.SetSystemName(ra::services::ServiceLocator::Get().Name()); + vmUnknownGame.SetSystemName(ra::services::ServiceLocator::Get().Name()); vmUnknownGame.SetChecksum(ra::Widen(sHash)); vmUnknownGame.SetEstimatedGameName(ra::Widen(sEstimatedGameTitle)); vmUnknownGame.SetNewGameName(vmUnknownGame.GetEstimatedGameName()); diff --git a/src/services/Initialization.cpp b/src/services/Initialization.cpp index fbf43f3cd..f9e5ee542 100644 --- a/src/services/Initialization.cpp +++ b/src/services/Initialization.cpp @@ -2,9 +2,9 @@ #include "api\impl\DisconnectedServer.hh" +#include "context\impl\ConsoleContext.hh" #include "context\impl\RcClient.hh" -#include "data\context\ConsoleContext.hh" #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" #include "data\context\SessionTracker.hh" @@ -123,10 +123,10 @@ void Initialization::RegisterServices(EmulatorID nEmulatorId, const char* sClien ra::services::ServiceLocator::Provide(std::move(pEmulatorContext)); // if EmulatorContext->Initialize doesn't specify the ConsoleContext, initialize a default ConsoleContext - if (!ra::services::ServiceLocator::Exists()) + if (!ra::services::ServiceLocator::Exists()) { - auto pConsoleContext = std::make_unique(ConsoleID::UnknownConsoleID); - ra::services::ServiceLocator::Provide(std::move(pConsoleContext)); + auto pConsoleContext = std::make_unique(ConsoleID::UnknownConsoleID); + ra::services::ServiceLocator::Provide(std::move(pConsoleContext)); } auto* pConfiguration = dynamic_cast( diff --git a/src/ui/viewmodels/IntegrationMenuViewModel.cpp b/src/ui/viewmodels/IntegrationMenuViewModel.cpp index 7bce7103c..fbf384ec0 100644 --- a/src/ui/viewmodels/IntegrationMenuViewModel.cpp +++ b/src/ui/viewmodels/IntegrationMenuViewModel.cpp @@ -3,7 +3,8 @@ #include "util\Log.hh" #include "RA_Resource.h" -#include "data/context/ConsoleContext.hh" +#include "context\IConsoleContext.hh" + #include "data/context/GameContext.hh" #include "data/context/UserContext.hh" @@ -391,7 +392,7 @@ void IntegrationMenuViewModel::ShowGameHash() auto sEstimatedGameTitle = ra::services::ServiceLocator::Get().GetGameTitle(); vmUnknownGame.SetEstimatedGameName(ra::Widen(sEstimatedGameTitle)); - vmUnknownGame.SetSystemName(ra::services::ServiceLocator::Get().Name()); + vmUnknownGame.SetSystemName(ra::services::ServiceLocator::Get().Name()); if (vmUnknownGame.ShowModal() == ra::ui::DialogResult::OK) { @@ -405,7 +406,7 @@ void IntegrationMenuViewModel::ShowGameHash() { if (pGameContext.GameId() == 0 && !pGameContext.GameHash().empty()) { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); const auto nConsoleId = pConsoleContext.Id(); if (nConsoleId != ConsoleID::UnknownConsoleID) { diff --git a/src/ui/viewmodels/LookupItemViewModel.hh b/src/ui/viewmodels/LookupItemViewModel.hh index d7af7d8d8..9308e47d2 100644 --- a/src/ui/viewmodels/LookupItemViewModel.hh +++ b/src/ui/viewmodels/LookupItemViewModel.hh @@ -77,7 +77,7 @@ public: /// /// Adds an item to the end of the collection. /// - GSL_SUPPRESS_C128 LookupItemViewModel& Add(int nId, const std::wstring& sLabel) + LookupItemViewModel& Add(int nId, const std::wstring& sLabel) { auto pItem = std::make_unique(nId, sLabel); return dynamic_cast(ViewModelCollectionBase::AddItem(std::move(pItem))); @@ -87,7 +87,7 @@ public: /// Adds an item to the end of the collection. /// template - GSL_SUPPRESS_C128 T& Add(Args&&... args) + T& Add(Args&&... args) { static_assert(std::is_base_of::value, "T not derived from base class LookupItemViewModel"); diff --git a/src/ui/viewmodels/MemoryRegionsViewModel.cpp b/src/ui/viewmodels/MemoryRegionsViewModel.cpp index 8ed521620..7e8509cab 100644 --- a/src/ui/viewmodels/MemoryRegionsViewModel.cpp +++ b/src/ui/viewmodels/MemoryRegionsViewModel.cpp @@ -3,7 +3,7 @@ #include "RA_Defs.h" #include "util\Strings.hh" -#include "data\context\ConsoleContext.hh" +#include "context\IConsoleContext.hh" #include "services\IConfiguration.hh" #include "services\ServiceLocator.hh" @@ -148,24 +148,24 @@ void MemoryRegionsViewModel::RemoveRegion() void MemoryRegionsViewModel::InitializeRegions() { - for (const auto& pRegion : ra::services::ServiceLocator::Get().MemoryRegions()) + for (const auto& pRegion : ra::services::ServiceLocator::Get().MemoryRegions()) { - switch (pRegion.Type) + switch (pRegion.GetType()) { - case ra::data::context::ConsoleContext::AddressType::Unused: - case ra::data::context::ConsoleContext::AddressType::VirtualRAM: - case ra::data::context::ConsoleContext::AddressType::ReadOnlyMemory: - case ra::data::context::ConsoleContext::AddressType::HardwareController: - case ra::data::context::ConsoleContext::AddressType::VideoRAM: + case ra::data::MemoryRegion::Type::Unused: + case ra::data::MemoryRegion::Type::VirtualRAM: + case ra::data::MemoryRegion::Type::ReadOnlyMemory: + case ra::data::MemoryRegion::Type::HardwareController: + case ra::data::MemoryRegion::Type::VideoRAM: continue; } auto pItem = std::make_unique(); pItem->SetId(gsl::narrow_cast(m_vRegions.Count())); - pItem->SetLabel(ra::Widen(pRegion.Description)); + pItem->SetLabel(ra::Widen(pRegion.GetDescription())); pItem->SetRange(ra::StringPrintf(L"%s-%s", - ra::ByteAddressToString(pRegion.StartAddress), - ra::ByteAddressToString(pRegion.EndAddress))); + ra::ByteAddressToString(pRegion.GetStartAddress()), + ra::ByteAddressToString(pRegion.GetEndAddress()))); m_vRegions.Append(std::move(pItem)); } @@ -177,10 +177,10 @@ void MemoryRegionsViewModel::InitializeRegions() { auto pItem = std::make_unique(); pItem->SetId(gsl::narrow_cast(m_vRegions.Count())); - pItem->SetLabel(ra::Widen(pRegion.sLabel)); + pItem->SetLabel(pRegion.GetDescription()); pItem->SetRange(ra::StringPrintf(L"%s-%s", - ra::ByteAddressToString(pRegion.nStartAddress), - ra::ByteAddressToString(pRegion.nEndAddress))); + ra::ByteAddressToString(pRegion.GetStartAddress()), + ra::ByteAddressToString(pRegion.GetEndAddress()))); pItem->SetCustom(true); m_vRegions.Append(std::move(pItem)); diff --git a/src/ui/viewmodels/MemorySearchViewModel.cpp b/src/ui/viewmodels/MemorySearchViewModel.cpp index a29a31784..784c2d57c 100644 --- a/src/ui/viewmodels/MemorySearchViewModel.cpp +++ b/src/ui/viewmodels/MemorySearchViewModel.cpp @@ -1,6 +1,7 @@ #include "MemorySearchViewModel.hh" -#include "data\context\ConsoleContext.hh" +#include "context\IConsoleContext.hh" + #include "data\context\EmulatorContext.hh" #include "services\IClock.hh" @@ -106,11 +107,11 @@ void MemorySearchViewModel::SearchResultViewModel::UpdateCodeNote(const std::wst { bHasCodeNote = false; - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); const auto* pRegion = pConsoleContext.GetMemoryRegion(nAddress); if (pRegion) { - SetDescription(ra::Widen(pRegion->Description)); + SetDescription(pRegion->GetDescription()); SetDescriptionColor(ra::ui::Color(0xFFA0A0A0)); } else @@ -207,59 +208,56 @@ void MemorySearchViewModel::RebuildPredefinedFilterRanges() ra::data::ByteAddress nSystemRamEnd = 0U; ra::data::ByteAddress nAllRamEnd = 0U; - std::vector vmRanges; - auto nPreviousAddressType = ra::data::context::ConsoleContext::AddressType::Unused; + std::vector vmRanges; + auto nPreviousAddressType = ra::data::MemoryRegion::Type::Unused; - for (const auto& pRegion : ra::services::ServiceLocator::Get().MemoryRegions()) + for (const auto& pRegion : ra::services::ServiceLocator::Get().MemoryRegions()) { - nAllRamEnd = pRegion.EndAddress; + nAllRamEnd = pRegion.GetEndAddress(); - switch (pRegion.Type) + switch (pRegion.GetType()) { - case ra::data::context::ConsoleContext::AddressType::Unused: - case ra::data::context::ConsoleContext::AddressType::VirtualRAM: - case ra::data::context::ConsoleContext::AddressType::ReadOnlyMemory: - case ra::data::context::ConsoleContext::AddressType::HardwareController: - case ra::data::context::ConsoleContext::AddressType::VideoRAM: + case ra::data::MemoryRegion::Type::Unused: + case ra::data::MemoryRegion::Type::VirtualRAM: + case ra::data::MemoryRegion::Type::ReadOnlyMemory: + case ra::data::MemoryRegion::Type::HardwareController: + case ra::data::MemoryRegion::Type::VideoRAM: // don't create filter regions for these. // reset the previous type to ensure the next block doesn't get merged to the last one. - nPreviousAddressType = ra::data::context::ConsoleContext::AddressType::Unused; + nPreviousAddressType = ra::data::MemoryRegion::Type::Unused; continue; - case ra::data::context::ConsoleContext::AddressType::SystemRAM: + case ra::data::MemoryRegion::Type::SystemRAM: if (nSystemRamEnd == 0) - nSystemRamStart = pRegion.StartAddress; - nSystemRamEnd = pRegion.EndAddress; + nSystemRamStart = pRegion.GetStartAddress(); + nSystemRamEnd = pRegion.GetEndAddress(); break; - case ra::data::context::ConsoleContext::AddressType::SaveRAM: + case ra::data::MemoryRegion::Type::SaveRAM: if (nExtraRamEnd == 0) - nExtraRamStart = pRegion.StartAddress; - nExtraRamEnd = pRegion.EndAddress; + nExtraRamStart = pRegion.GetStartAddress(); + nExtraRamEnd = pRegion.GetEndAddress(); break; } - if (pRegion.Type == nPreviousAddressType && vmRanges.back().Description == pRegion.Description) + if (pRegion.GetType() == nPreviousAddressType && vmRanges.back().GetDescription() == pRegion.GetDescription()) { - vmRanges.back().EndAddress = pRegion.EndAddress; + vmRanges.back().SetEndAddress(pRegion.GetEndAddress()); continue; } - nPreviousAddressType = pRegion.Type; - auto& vmRange = vmRanges.emplace_back(); - vmRange.Description = pRegion.Description; - vmRange.StartAddress = pRegion.StartAddress; - vmRange.EndAddress = pRegion.EndAddress; + nPreviousAddressType = pRegion.GetType(); + vmRanges.emplace_back(pRegion.GetStartAddress(), pRegion.GetEndAddress(), pRegion.GetDescription()); } for (const auto& vmRange : vmRanges) { - if (vmRange.EndAddress == nSystemRamEnd && vmRange.StartAddress == nSystemRamStart) + if (vmRange.GetEndAddress() == nSystemRamEnd && vmRange.GetStartAddress() == nSystemRamStart) { // system defined range already exists for "All System RAM" nSystemRamEnd = 0U; } - else if (vmRange.EndAddress == nExtraRamEnd && vmRange.StartAddress == nExtraRamStart) + else if (vmRange.GetEndAddress() == nExtraRamEnd && vmRange.GetStartAddress() == nExtraRamStart) { // system defined range already exists for "All Game RAM" nExtraRamEnd = 0U; @@ -272,8 +270,8 @@ void MemorySearchViewModel::RebuildPredefinedFilterRanges() DefinePredefinedFilterRange(nIndex++, MEMORY_RANGE_ALL, L"All", 0U, nAllRamEnd, false); if (vmRanges.size() == 1 && - vmRanges.front().EndAddress == nAllRamEnd && - vmRanges.front().StartAddress == 0) + vmRanges.front().GetEndAddress() == nAllRamEnd && + vmRanges.front().GetStartAddress() == 0) { // single defined range is "All Memory". don't list it separately. } @@ -288,7 +286,7 @@ void MemorySearchViewModel::RebuildPredefinedFilterRanges() for (const auto& vmRange : vmRanges) { DefinePredefinedFilterRange(nIndex, gsl::narrow_cast(nIndex), - ra::Widen(vmRange.Description), vmRange.StartAddress, vmRange.EndAddress, true); + vmRange.GetDescription(), vmRange.GetStartAddress(), vmRange.GetEndAddress(), true); ++nIndex; } } @@ -300,7 +298,7 @@ void MemorySearchViewModel::RebuildPredefinedFilterRanges() for (const auto& pRegion : pMemoryRegions->CustomRegions()) { DefinePredefinedFilterRange(nIndex, gsl::narrow_cast(nIndex), - pRegion.sLabel, pRegion.nStartAddress, pRegion.nEndAddress, true); + pRegion.GetDescription(), pRegion.GetStartAddress(), pRegion.GetEndAddress(), true); ++nIndex; } } diff --git a/src/ui/viewmodels/MemoryViewerViewModel.cpp b/src/ui/viewmodels/MemoryViewerViewModel.cpp index 2d1b4bffe..6abecb6f4 100644 --- a/src/ui/viewmodels/MemoryViewerViewModel.cpp +++ b/src/ui/viewmodels/MemoryViewerViewModel.cpp @@ -2,7 +2,8 @@ #include "RA_Defs.h" -#include "data\context\ConsoleContext.hh" +#include "context\IConsoleContext.hh" + #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" @@ -863,15 +864,15 @@ void MemoryViewerViewModel::OnTotalMemorySizeChanged() } else { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); const auto* pCurrentRegion = pConsoleContext.GetMemoryRegion(nAddress); - if (!pCurrentRegion || pCurrentRegion->Type == ra::data::context::ConsoleContext::AddressType::Unused) + if (!pCurrentRegion || pCurrentRegion->GetType() == ra::data::MemoryRegion::Type::Unused) { for (const auto& pRegion : pConsoleContext.MemoryRegions()) { - if (pRegion.Type != ra::data::context::ConsoleContext::AddressType::Unused) + if (pRegion.GetType() != ra::data::MemoryRegion::Type::Unused) { - SetValue(AddressProperty, gsl::narrow_cast(pRegion.StartAddress)); + SetValue(AddressProperty, gsl::narrow_cast(pRegion.GetStartAddress())); break; } } diff --git a/src/ui/viewmodels/MemoryWatchViewModel.cpp b/src/ui/viewmodels/MemoryWatchViewModel.cpp index 439e6cbdf..5f2d6b43c 100644 --- a/src/ui/viewmodels/MemoryWatchViewModel.cpp +++ b/src/ui/viewmodels/MemoryWatchViewModel.cpp @@ -4,10 +4,10 @@ #include "RA_Json.h" #include "util\Strings.hh" +#include "context\IConsoleContext.hh" #include "context\IRcClient.hh" #include "data\Types.hh" -#include "data\context\ConsoleContext.hh" #include "data\context\EmulatorContext.hh" #include "data\models\TriggerValidation.hh" @@ -394,7 +394,7 @@ bool MemoryWatchViewModel::UpdateCurrentAddressFromIndirectAddress() if (!m_pValue) return true; - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); m_bIndirectAddressValid = true; for (const auto* pCondition = m_pValue->conditions->conditions; pCondition; pCondition = pCondition->next) diff --git a/src/ui/viewmodels/PointerInspectorViewModel.cpp b/src/ui/viewmodels/PointerInspectorViewModel.cpp index 2807cffb1..0aa3eeef8 100644 --- a/src/ui/viewmodels/PointerInspectorViewModel.cpp +++ b/src/ui/viewmodels/PointerInspectorViewModel.cpp @@ -2,7 +2,7 @@ #include "RA_Defs.h" -#include "data\context\ConsoleContext.hh" +#include "context\IConsoleContext.hh" #include "services\AchievementLogicSerializer.hh" #include "services\IClipboard.hh" @@ -805,7 +805,7 @@ void PointerInspectorViewModel::UpdatePointerChainValues() ra::data::ByteAddress nAddress = 0; - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); m_vPointerChain.BeginUpdate(); @@ -839,7 +839,7 @@ void PointerInspectorViewModel::UpdatePointerChainRowColor(PointerInspectorViewM return; } - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); bool bValid = false; auto nMemSize = ra::data::Memory::Size::Unknown; @@ -1101,7 +1101,7 @@ void PointerInspectorViewModel::NewField() // TODO: ConsoleContext should return an architecture size auto nReadSize = ra::data::Memory::Size::ThirtyTwoBit; uint32_t nMask = 0, nOffset = 0; - auto& pConsoleContext = ra::services::ServiceLocator::Get(); + auto& pConsoleContext = ra::services::ServiceLocator::Get(); pConsoleContext.GetRealAddressConversion(&nReadSize, &nMask, &nOffset); switch (nReadSize) diff --git a/src/ui/viewmodels/UnknownGameViewModel.cpp b/src/ui/viewmodels/UnknownGameViewModel.cpp index 24bcc14be..1dae26883 100644 --- a/src/ui/viewmodels/UnknownGameViewModel.cpp +++ b/src/ui/viewmodels/UnknownGameViewModel.cpp @@ -5,9 +5,9 @@ #include "api\FetchGamesList.hh" #include "api\SubmitNewTitle.hh" +#include "context\IConsoleContext.hh" #include "context\IRcClient.hh" -#include "data\context\ConsoleContext.hh" #include "data\context\GameContext.hh" #include "data\context\UserContext.hh" @@ -42,7 +42,7 @@ UnknownGameViewModel::UnknownGameViewModel() noexcept void UnknownGameViewModel::InitializeGameTitles() { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); InitializeGameTitles(pConsoleContext.Id()); } @@ -130,7 +130,7 @@ unsigned int UnknownGameViewModel::GetPreviousAssociation(const std::wstring& sH std::string sLine; if (sMapping && sMapping->GetLine(sLine)) { - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); const unsigned nId = DecodeID(sLine, sHash, pConsoleContext.Id()); if (nId > 0) return nId; @@ -211,7 +211,7 @@ bool UnknownGameViewModel::Associate() return false; } - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); request.ConsoleId = pConsoleContext.Id(); request.Hash = ra::Narrow(GetChecksum()); request.Description = GetEstimatedGameName(); @@ -246,7 +246,7 @@ bool UnknownGameViewModel::BeginTest() if (vmMessageBox.ShowModal(*this) == DialogResult::No) return false; - const auto& pConsoleContext = ra::services::ServiceLocator::Get(); + const auto& pConsoleContext = ra::services::ServiceLocator::Get(); auto sValue = EncodeID(nGameId, GetChecksum(), pConsoleContext.Id()); auto& pLocalStorage = ra::services::ServiceLocator::GetMutable(); auto sMapping = pLocalStorage.WriteText(ra::services::StorageItemType::HashMapping, GetChecksum()); diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj index 24181e136..c760d7ed3 100644 --- a/tests/RA_Integration.Tests.vcxproj +++ b/tests/RA_Integration.Tests.vcxproj @@ -79,7 +79,6 @@ - @@ -161,7 +160,6 @@ - diff --git a/tests/RA_Integration.Tests.vcxproj.filters b/tests/RA_Integration.Tests.vcxproj.filters index d112921e0..18e67caf4 100644 --- a/tests/RA_Integration.Tests.vcxproj.filters +++ b/tests/RA_Integration.Tests.vcxproj.filters @@ -297,9 +297,6 @@ Code - - Code - Code @@ -399,9 +396,6 @@ Code - - Tests\Data\Context - Code diff --git a/tests/data/context/ConsoleContext_Tests.cpp b/tests/data/context/ConsoleContext_Tests.cpp index 84f4aaffe..1eaf32936 100644 --- a/tests/data/context/ConsoleContext_Tests.cpp +++ b/tests/data/context/ConsoleContext_Tests.cpp @@ -1,21 +1,22 @@ -#include "CppUnitTest.h" +#include "context/impl/ConsoleContext.hh" -#include "data\context\ConsoleContext.hh" +#include "testutil/CppUnitTest.hh" +#include "testutil/MemoryRegionAsserts.hh" -#include "tests\data\DataAsserts.hh" +#include "util/Strings.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; namespace ra { -namespace data { namespace context { +namespace impl { namespace tests { TEST_CLASS(ConsoleContext_Tests) { private: static void AssertRegion(const ConsoleContext& context, ra::data::ByteAddress nAddress, - const ConsoleContext::MemoryRegion* pExpectedRegion) + const ra::data::MemoryRegion* pExpectedRegion) { const auto* pFoundRegion = context.GetMemoryRegion(nAddress); if (pFoundRegion != pExpectedRegion) @@ -40,11 +41,11 @@ TEST_CLASS(ConsoleContext_Tests) const auto& vRegions = context.MemoryRegions(); Assert::AreEqual({1}, vRegions.size()); - Assert::AreEqual(0x00U, vRegions.at(0).StartAddress); - Assert::AreEqual(0x7FU, vRegions.at(0).EndAddress); - Assert::AreEqual(0x80U, vRegions.at(0).RealAddress); - Assert::AreEqual((int)ConsoleContext::AddressType::SystemRAM, (int)vRegions.at(0).Type); - Assert::AreEqual(std::string("System RAM"), vRegions.at(0).Description); + Assert::AreEqual(0x00U, vRegions.at(0).GetStartAddress()); + Assert::AreEqual(0x7FU, vRegions.at(0).GetEndAddress()); + Assert::AreEqual(0x80U, vRegions.at(0).GetRealStartAddress()); + Assert::AreEqual(ra::data::MemoryRegion::Type::SystemRAM, vRegions.at(0).GetType()); + Assert::AreEqual(std::wstring(L"System RAM"), vRegions.at(0).GetDescription()); AssertRegion(context, 0x00U, &vRegions.at(0)); AssertRegion(context, 0x7FU, &vRegions.at(0)); @@ -64,21 +65,21 @@ TEST_CLASS(ConsoleContext_Tests) const auto& vRegions = context.MemoryRegions(); Assert::AreEqual({3}, vRegions.size()); - Assert::AreEqual(0x00000000U, vRegions.at(0).StartAddress); - Assert::AreEqual(0x00007FFFU, vRegions.at(0).EndAddress); - Assert::AreEqual(0x03000000U, vRegions.at(0).RealAddress); - Assert::AreEqual((int)ConsoleContext::AddressType::SystemRAM, (int)vRegions.at(0).Type); - Assert::AreEqual(std::string("System RAM"), vRegions.at(0).Description); - Assert::AreEqual(0x00008000U, vRegions.at(1).StartAddress); - Assert::AreEqual(0x00047FFFU, vRegions.at(1).EndAddress); - Assert::AreEqual(0x02000000U, vRegions.at(1).RealAddress); - Assert::AreEqual((int)ConsoleContext::AddressType::SystemRAM, (int)vRegions.at(1).Type); - Assert::AreEqual(std::string("System RAM"), vRegions.at(1).Description); - Assert::AreEqual(0x00048000U, vRegions.at(2).StartAddress); - Assert::AreEqual(0x00057FFFU, vRegions.at(2).EndAddress); - Assert::AreEqual(0x0E000000U, vRegions.at(2).RealAddress); - Assert::AreEqual((int)ConsoleContext::AddressType::SaveRAM, (int)vRegions.at(2).Type); - Assert::AreEqual(std::string("Save RAM"), vRegions.at(2).Description); + Assert::AreEqual(0x00000000U, vRegions.at(0).GetStartAddress()); + Assert::AreEqual(0x00007FFFU, vRegions.at(0).GetEndAddress()); + Assert::AreEqual(0x03000000U, vRegions.at(0).GetRealStartAddress()); + Assert::AreEqual(ra::data::MemoryRegion::Type::SystemRAM, vRegions.at(0).GetType()); + Assert::AreEqual(std::wstring(L"System RAM"), vRegions.at(0).GetDescription()); + Assert::AreEqual(0x00008000U, vRegions.at(1).GetStartAddress()); + Assert::AreEqual(0x00047FFFU, vRegions.at(1).GetEndAddress()); + Assert::AreEqual(0x02000000U, vRegions.at(1).GetRealStartAddress()); + Assert::AreEqual(ra::data::MemoryRegion::Type::SystemRAM, vRegions.at(1).GetType()); + Assert::AreEqual(std::wstring(L"System RAM"), vRegions.at(1).GetDescription()); + Assert::AreEqual(0x00048000U, vRegions.at(2).GetStartAddress()); + Assert::AreEqual(0x00057FFFU, vRegions.at(2).GetEndAddress()); + Assert::AreEqual(0x0E000000U, vRegions.at(2).GetRealStartAddress()); + Assert::AreEqual(ra::data::MemoryRegion::Type::SaveRAM, vRegions.at(2).GetType()); + Assert::AreEqual(std::wstring(L"Save RAM"), vRegions.at(2).GetDescription()); AssertRegion(context, 0x00000000U, &vRegions.at(0)); AssertRegion(context, 0x00007FFFU, &vRegions.at(0)); @@ -101,16 +102,16 @@ TEST_CLASS(ConsoleContext_Tests) const auto& vRegions = context.MemoryRegions(); Assert::AreEqual({2}, vRegions.size()); - Assert::AreEqual(0x00000000U, vRegions.at(0).StartAddress); - Assert::AreEqual(0x007FFFFFU, vRegions.at(0).EndAddress); - Assert::AreEqual(0x08000000U, vRegions.at(0).RealAddress); - Assert::AreEqual((int)ConsoleContext::AddressType::SystemRAM, (int)vRegions.at(0).Type); - Assert::AreEqual(std::string("Kernel RAM"), vRegions.at(0).Description); - Assert::AreEqual(0x00800000U, vRegions.at(1).StartAddress); - Assert::AreEqual(0x01FFFFFFU, vRegions.at(1).EndAddress); - Assert::AreEqual(0x08800000U, vRegions.at(1).RealAddress); - Assert::AreEqual((int)ConsoleContext::AddressType::SystemRAM, (int)vRegions.at(1).Type); - Assert::AreEqual(std::string("System RAM"), vRegions.at(1).Description); + Assert::AreEqual(0x00000000U, vRegions.at(0).GetStartAddress()); + Assert::AreEqual(0x007FFFFFU, vRegions.at(0).GetEndAddress()); + Assert::AreEqual(0x08000000U, vRegions.at(0).GetRealStartAddress()); + Assert::AreEqual(ra::data::MemoryRegion::Type::SystemRAM, vRegions.at(0).GetType()); + Assert::AreEqual(std::wstring(L"Kernel RAM"), vRegions.at(0).GetDescription()); + Assert::AreEqual(0x00800000U, vRegions.at(1).GetStartAddress()); + Assert::AreEqual(0x01FFFFFFU, vRegions.at(1).GetEndAddress()); + Assert::AreEqual(0x08800000U, vRegions.at(1).GetRealStartAddress()); + Assert::AreEqual(ra::data::MemoryRegion::Type::SystemRAM, vRegions.at(1).GetType()); + Assert::AreEqual(std::wstring(L"System RAM"), vRegions.at(1).GetDescription()); AssertRegion(context, 0x00000000U, &vRegions.at(0)); AssertRegion(context, 0x007FFFFFU, &vRegions.at(0)); diff --git a/tests/data/context/GameContext_Tests.cpp b/tests/data/context/GameContext_Tests.cpp index 312f49069..eac3bc8c0 100644 --- a/tests/data/context/GameContext_Tests.cpp +++ b/tests/data/context/GameContext_Tests.cpp @@ -15,11 +15,11 @@ #include "tests\data\DataAsserts.hh" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockAudioSystem.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" @@ -72,7 +72,7 @@ TEST_CLASS(GameContext_Tests) ra::services::mocks::MockAchievementRuntime mockAchievementRuntime; ra::services::mocks::MockFrameEventQueue mockFrameEventQueue; ra::ui::viewmodels::mocks::MockOverlayManager mockOverlayManager; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulator; ra::data::context::mocks::MockSessionTracker mockSessionTracker; ra::data::context::mocks::MockUserContext mockUser; diff --git a/tests/data/models/CapturedTriggerHits_Tests.cpp b/tests/data/models/CapturedTriggerHits_Tests.cpp index dd82d4f4a..76db15fb3 100644 --- a/tests/data/models/CapturedTriggerHits_Tests.cpp +++ b/tests/data/models/CapturedTriggerHits_Tests.cpp @@ -2,7 +2,7 @@ #include "data\models\CapturedTriggerHits.hh" -#include "tests\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\mocks\MockEmulatorContext.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; diff --git a/tests/data/models/CodeNoteModel_Tests.cpp b/tests/data/models/CodeNoteModel_Tests.cpp index 3667082ac..6e84c2a17 100644 --- a/tests/data/models/CodeNoteModel_Tests.cpp +++ b/tests/data/models/CodeNoteModel_Tests.cpp @@ -7,9 +7,9 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\data\DataAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockServer.hh" @@ -28,7 +28,7 @@ TEST_CLASS(CodeNoteModel_Tests) class CodeNoteModelHarness : public CodeNoteModel { public: - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; }; @@ -638,7 +638,7 @@ TEST_CLASS(CodeNoteModel_Tests) TEST_METHOD(TestPointerOverflow) { CodeNoteModelHarness note; - note.mockConsoleContext.AddMemoryRegion(0, 0x7F, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80000000); + note.mockConsoleContext.AddMemoryRegion(0, 0x7F, ra::data::MemoryRegion::Type::SystemRAM, 0x80000000); std::array memory{}; memory.at(0x04) = 0x10; // pointer@0x04 = 0x80000010 memory.at(0x07) = 0x80; @@ -668,7 +668,7 @@ TEST_CLASS(CodeNoteModel_Tests) TEST_METHOD(TestPointerNegative) { CodeNoteModelHarness note; - note.mockConsoleContext.AddMemoryRegion(0, 0x7F, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80000000); + note.mockConsoleContext.AddMemoryRegion(0, 0x7F, ra::data::MemoryRegion::Type::SystemRAM, 0x80000000); std::array memory{}; memory.at(0x04) = 0x10; // pointer@0x04 = 0x80000010 memory.at(0x07) = 0x80; diff --git a/tests/data/models/CodeNotesModel_Tests.cpp b/tests/data/models/CodeNotesModel_Tests.cpp index 05793b662..ca444c3e2 100644 --- a/tests/data/models/CodeNotesModel_Tests.cpp +++ b/tests/data/models/CodeNotesModel_Tests.cpp @@ -7,9 +7,9 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\data\DataAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockServer.hh" @@ -29,7 +29,7 @@ TEST_CLASS(CodeNotesModel_Tests) { public: ra::api::mocks::MockServer mockServer; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockThreadPool mockThreadPool; @@ -643,7 +643,7 @@ TEST_CLASS(CodeNotesModel_Tests) TEST_METHOD(TestFindCodeNoteSizedPointerOverflow) { CodeNotesModelHarness notes; - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; notes.mockEmulatorContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) @@ -693,7 +693,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"+8 | Count"; notes.AddCodeNote(4U, "Author", sNote); - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; memory.at(4) = 8; // pointer = 8 memory.at(8) = 20; // obj1 pointer = 20 @@ -874,7 +874,7 @@ TEST_CLASS(CodeNotesModel_Tests) TEST_METHOD(TestEnumerateCodeNotesWithIndirectOverflow) { CodeNotesModelHarness notes; - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; notes.mockEmulatorContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) @@ -1013,7 +1013,7 @@ TEST_CLASS(CodeNotesModel_Tests) { CodeNotesModelHarness notes; notes.MonitorCodeNoteChanges(); - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; for (uint8_t i = 4; i < memory.size(); i++) @@ -1061,7 +1061,7 @@ TEST_CLASS(CodeNotesModel_Tests) { CodeNotesModelHarness notes; notes.MonitorCodeNoteChanges(); - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; for (uint8_t i = 4; i < memory.size(); i++) @@ -1109,7 +1109,7 @@ TEST_CLASS(CodeNotesModel_Tests) { CodeNotesModelHarness notes; notes.MonitorCodeNoteChanges(); - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; for (uint8_t i = 4; i < memory.size(); i++) @@ -1187,7 +1187,7 @@ TEST_CLASS(CodeNotesModel_Tests) TEST_METHOD(TestFindCodeNoteStartPointerOverflow) { CodeNotesModelHarness notes; - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; notes.mockEmulatorContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) @@ -1253,7 +1253,7 @@ TEST_CLASS(CodeNotesModel_Tests) TEST_METHOD(TestGetIndirectSourceOverflow) { CodeNotesModelHarness notes; - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; notes.mockEmulatorContext.MockMemory(memory); memory.at(4) = 0x90; // start with initial value for pointer (real address = 0x90, RA address = 0x10) @@ -1439,7 +1439,7 @@ TEST_CLASS(CodeNotesModel_Tests) TEST_METHOD(TestGetNextNoteAddressOverflow) { CodeNotesModelHarness notes; - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; notes.mockEmulatorContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) @@ -1502,7 +1502,7 @@ TEST_CLASS(CodeNotesModel_Tests) TEST_METHOD(TestGetPreviousNoteAddressOverflow) { CodeNotesModelHarness notes; - notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::context::ConsoleContext::AddressType::SystemRAM, 0x80); + notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; notes.mockEmulatorContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) diff --git a/tests/data/models/MemoryRegionsModel_Tests.cpp b/tests/data/models/MemoryRegionsModel_Tests.cpp index 80a9041b9..cc3495d79 100644 --- a/tests/data/models/MemoryRegionsModel_Tests.cpp +++ b/tests/data/models/MemoryRegionsModel_Tests.cpp @@ -35,9 +35,9 @@ TEST_CLASS(MemoryRegionsModel_Tests) { for (const auto& pRegion : CustomRegions()) { - if (pRegion.nStartAddress == nStartAddress && pRegion.nEndAddress == nEndAddress) + if (pRegion.GetStartAddress() == nStartAddress && pRegion.GetEndAddress() == nEndAddress) { - Assert::AreEqual(sLabel, pRegion.sLabel); + Assert::AreEqual(sLabel, pRegion.GetDescription()); return; } } diff --git a/tests/data/models/TriggerValidation_Tests.cpp b/tests/data/models/TriggerValidation_Tests.cpp index d10ad1fb3..2eee3657c 100644 --- a/tests/data/models/TriggerValidation_Tests.cpp +++ b/tests/data/models/TriggerValidation_Tests.cpp @@ -2,7 +2,7 @@ #include "data\models\TriggerValidation.hh" -#include "tests\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockUserContext.hh" @@ -131,7 +131,7 @@ TEST_CLASS(TriggerValidation_Tests) TEST_METHOD(TestAddressRange) { // basic checks for each side - ra::data::context::mocks::MockConsoleContext mockConsoleContext(NES, L"NES"); + ra::context::mocks::MockConsoleContext mockConsoleContext(NES, L"NES"); Assert::AreEqual(0xFFFFU, mockConsoleContext.MaxAddress()); AssertValidation("0xH0234>0xH0235", L""); AssertValidation("0xH1234>0xH1235", L"Condition 1: Mirror RAM may not be exposed by emulator (address 1234)"); @@ -154,7 +154,7 @@ TEST_CLASS(TriggerValidation_Tests) { // arcade doesn't provide a max address as each game can have a different amount of memory // instead, max valid address is determined by how much memory the emulator/core exposes - ra::data::context::mocks::MockConsoleContext mockConsoleContext(Arcade, L"Arcade"); + ra::context::mocks::MockConsoleContext mockConsoleContext(Arcade, L"Arcade"); Assert::AreEqual(0U, mockConsoleContext.MaxAddress()); ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; unsigned char pMemory[256]; diff --git a/tests/devkit/RADevKit.Tests.vcxproj.vcxproj b/tests/devkit/RADevKit.Tests.vcxproj.vcxproj index 23fbb9fac..56b44fba7 100644 --- a/tests/devkit/RADevKit.Tests.vcxproj.vcxproj +++ b/tests/devkit/RADevKit.Tests.vcxproj.vcxproj @@ -61,11 +61,13 @@ + + @@ -79,6 +81,7 @@ + \ No newline at end of file diff --git a/tests/devkit/RADevKit.Tests.vcxproj.vcxproj.filters b/tests/devkit/RADevKit.Tests.vcxproj.vcxproj.filters index 84055e295..309e96a6a 100644 --- a/tests/devkit/RADevKit.Tests.vcxproj.vcxproj.filters +++ b/tests/devkit/RADevKit.Tests.vcxproj.vcxproj.filters @@ -31,6 +31,9 @@ context\impl + + context\impl + @@ -86,5 +89,11 @@ testutil + + testutil + + + context\mocks + \ No newline at end of file diff --git a/tests/mocks/MockConsoleContext.hh b/tests/devkit/context/mocks/MockConsoleContext.hh similarity index 54% rename from tests/mocks/MockConsoleContext.hh rename to tests/devkit/context/mocks/MockConsoleContext.hh index 423d9515a..a80015934 100644 --- a/tests/mocks/MockConsoleContext.hh +++ b/tests/devkit/context/mocks/MockConsoleContext.hh @@ -1,17 +1,16 @@ -#ifndef RA_DATA_MOCK_CONSOLECONTEXT_HH -#define RA_DATA_MOCK_CONSOLECONTEXT_HH +#ifndef RA_CONTEXT_MOCK_CONSOLECONTEXT_HH +#define RA_CONTEXT_MOCK_CONSOLECONTEXT_HH #pragma once -#include "data\context\ConsoleContext.hh" +#include "context/impl/ConsoleContext.hh" -#include "services\ServiceLocator.hh" +#include "services/ServiceLocator.hh" namespace ra { -namespace data { namespace context { namespace mocks { -class MockConsoleContext : public ConsoleContext +class MockConsoleContext : public impl::ConsoleContext { public: GSL_SUPPRESS_F6 MockConsoleContext() noexcept @@ -32,29 +31,25 @@ public: void ResetMemoryRegions() noexcept { m_vRegions.clear(); } void AddMemoryRegion(ra::data::ByteAddress nStartAddress, ra::data::ByteAddress nEndAddress, - AddressType nAddressType, const std::string& sDescription = "") + ra::data::MemoryRegion::Type nAddressType, const std::wstring& sDescription = L"") { AddMemoryRegion(nStartAddress, nEndAddress, nAddressType, nStartAddress, sDescription); } void AddMemoryRegion(ra::data::ByteAddress nStartAddress, ra::data::ByteAddress nEndAddress, - AddressType nAddressType, ra::data::ByteAddress nRealAddress, const std::string& sDescription = "") + ra::data::MemoryRegion::Type nAddressType, ra::data::ByteAddress nRealAddress, const std::wstring& sDescription = L"") { - auto& pRegion = m_vRegions.emplace_back(); - pRegion.StartAddress = nStartAddress; - pRegion.EndAddress = nEndAddress; - pRegion.RealAddress = nRealAddress; - pRegion.Type = nAddressType; - pRegion.Description = sDescription; + auto& pRegion = m_vRegions.emplace_back(nStartAddress, nEndAddress, sDescription); + pRegion.SetRealStartAddress(nRealAddress); + pRegion.SetType(nAddressType); } private: - ra::services::ServiceLocator::ServiceOverride m_Override; + ra::services::ServiceLocator::ServiceOverride m_Override; }; } // namespace mocks } // namespace context -} // namespace data } // namespace ra -#endif // !RA_DATA_MOCK_CONSOLECONTEXT_HH +#endif // !RA_CONTEXT_MOCK_CONSOLECONTEXT_HH diff --git a/tests/devkit/testutil/MemoryRegionAsserts.hh b/tests/devkit/testutil/MemoryRegionAsserts.hh new file mode 100644 index 000000000..7a11431e0 --- /dev/null +++ b/tests/devkit/testutil/MemoryRegionAsserts.hh @@ -0,0 +1,54 @@ +#ifndef RA_MEMORYREGION_ASSERTS_H +#define RA_MEMORYREGION_ASSERTS_H +#pragma once + +#include "CppUnitTest.hh" + +#include "data\MemoryRegion.hh" +#include "util\TypeCasts.hh" + +// The rcheevos nameless struct warning is only affecting the test project, for now we have +// to disable the warning in the project or pragmatically in rcheevos. Careful not to use nameless structs here. + +namespace Microsoft { +namespace VisualStudio { +namespace CppUnitTestFramework { + +// converters for asserting enum values + +#pragma warning(push) +#pragma warning(disable : 4505) // unreferenced inline functions, they are referenced. Must be a bug. + +template<> +std::wstring ToString(const ra::data::MemoryRegion::Type& t) +{ + switch (t) + { + case ra::data::MemoryRegion::Type::Unknown: + return L"Unknown"; + case ra::data::MemoryRegion::Type::SaveRAM: + return L"SaveRAM"; + case ra::data::MemoryRegion::Type::SystemRAM: + return L"SystemRAM"; + case ra::data::MemoryRegion::Type::VirtualRAM: + return L"VirtualRAM"; + case ra::data::MemoryRegion::Type::VideoRAM: + return L"VideoRAM"; + case ra::data::MemoryRegion::Type::HardwareController: + return L"HardwareController"; + case ra::data::MemoryRegion::Type::ReadOnlyMemory: + return L"ReadOnlyMemory"; + case ra::data::MemoryRegion::Type::Unused: + return L"Unused"; + default: + return std::to_wstring(ra::etoi(t)); + } +} + +#pragma warning(pop) + +} // namespace CppUnitTestFramework +} // namespace VisualStudio +} // namespace Microsoft + +#endif /* !RA_MEMORYREGION_ASSERTS_H */ diff --git a/tests/services/AchievementLogicSerializer_Tests.cpp b/tests/services/AchievementLogicSerializer_Tests.cpp index 1e3e7c73d..d9b2cb3a0 100644 --- a/tests/services/AchievementLogicSerializer_Tests.cpp +++ b/tests/services/AchievementLogicSerializer_Tests.cpp @@ -5,7 +5,7 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\data\DataAsserts.hh" -#include "tests\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\mocks\MockEmulatorContext.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -19,7 +19,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) public: TEST_METHOD(TestBuildMemRefChain) { - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::models::CodeNoteModel note; @@ -48,7 +48,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain24Bit) { - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; mockConsoleContext.SetId(ConsoleID::PlayStation); // 24-bit read @@ -72,7 +72,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain25Bit) { - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; mockConsoleContext.SetId(ConsoleID::PSP); // 25-bit read @@ -96,7 +96,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain25BitBE) { - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; mockConsoleContext.SetId(ConsoleID::GameCube); // 25-bit BE read @@ -120,7 +120,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain25BitOverflowOffset) { - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; mockConsoleContext.SetId(ConsoleID::GameCube); // 25-bit BE read @@ -144,7 +144,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChainGBA) { - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; mockConsoleContext.SetId(ConsoleID::GBA); // 24-bit read with explicit offset in note @@ -168,7 +168,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChainNegativeOffset) { - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; mockConsoleContext.SetId(ConsoleID::GameCube); // 29-bit BE read diff --git a/tests/services/AchievementRuntimeExports_Tests.cpp b/tests/services/AchievementRuntimeExports_Tests.cpp index 22afdce0b..e1c05f1b6 100644 --- a/tests/services/AchievementRuntimeExports_Tests.cpp +++ b/tests/services/AchievementRuntimeExports_Tests.cpp @@ -4,9 +4,9 @@ #include "tests\RA_UnitTestHelpers.h" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -472,7 +472,7 @@ TEST_CLASS(AchievementRuntimeExports_Tests) TEST_METHOD(TestReadWriteMemory) { AchievementRuntimeExportsHarness runtime; - ra::data::context::mocks::MockConsoleContext mockConsole(NES, L"NES"); + ra::context::mocks::MockConsoleContext mockConsole(NES, L"NES"); runtime.InitializeMemoryFunctions(); Assert::AreEqual({0}, runtime.GetMemoryByte(1)); @@ -542,7 +542,7 @@ TEST_CLASS(AchievementRuntimeExports_Tests) { AchievementRuntimeExportsHarness runtime; ra::data::context::mocks::MockGameContext mockGameContext; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; rc_client_external_t pClient; memset(&pClient, 0, sizeof(pClient)); @@ -564,7 +564,7 @@ TEST_CLASS(AchievementRuntimeExports_Tests) { AchievementRuntimeExportsHarness runtime; ra::data::context::mocks::MockGameContext mockGameContext; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; rc_client_external_t pClient; memset(&pClient, 0, sizeof(pClient)); diff --git a/tests/services/AchievementRuntime_Tests.cpp b/tests/services/AchievementRuntime_Tests.cpp index c33145514..ca9958f15 100644 --- a/tests/services/AchievementRuntime_Tests.cpp +++ b/tests/services/AchievementRuntime_Tests.cpp @@ -2,6 +2,7 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\data\DataAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\services\mocks\MockHttpRequester.hh" @@ -9,7 +10,6 @@ #include "tests\mocks\MockAudioSystem.hh" #include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockFrameEventQueue.hh" diff --git a/tests/services/GameIdentifier_Tests.cpp b/tests/services/GameIdentifier_Tests.cpp index 84b2df40d..1df0526a3 100644 --- a/tests/services/GameIdentifier_Tests.cpp +++ b/tests/services/GameIdentifier_Tests.cpp @@ -5,13 +5,13 @@ #include "tests\data\DataAsserts.hh" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockAudioSystem.hh" #include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -75,7 +75,7 @@ class GameIdentifierHarness : public GameIdentifier ra::api::mocks::MockServer mockServer; ra::context::mocks::MockRcClient mockRcClient; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockSessionTracker mockSessionTracker; @@ -171,7 +171,7 @@ TEST_CLASS(GameIdentifier_Tests) TEST_METHOD(TestIdentifyGameUnhashable) { GameIdentifierHarness identifier; - ra::data::context::mocks::MockConsoleContext n64Context(N64, L"N64"); + ra::context::mocks::MockConsoleContext n64Context(N64, L"N64"); bool bDialogShown = false; identifier.mockDesktop.ExpectWindow([&bDialogShown](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox) diff --git a/tests/ui/viewmodels/CodeNotesViewModel_Tests.cpp b/tests/ui/viewmodels/CodeNotesViewModel_Tests.cpp index 8408d6653..a17602a77 100644 --- a/tests/ui/viewmodels/CodeNotesViewModel_Tests.cpp +++ b/tests/ui/viewmodels/CodeNotesViewModel_Tests.cpp @@ -6,10 +6,10 @@ #include "tests\ui\UIAsserts.hh" #include "tests\RA_UnitTestHelpers.h" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -32,7 +32,7 @@ TEST_CLASS(CodeNotesViewModel_Tests) { public: ra::api::mocks::MockServer mockServer; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; diff --git a/tests/ui/viewmodels/IntegrationMenuViewModel_Tests.cpp b/tests/ui/viewmodels/IntegrationMenuViewModel_Tests.cpp index ed927802a..2dec8b356 100644 --- a/tests/ui/viewmodels/IntegrationMenuViewModel_Tests.cpp +++ b/tests/ui/viewmodels/IntegrationMenuViewModel_Tests.cpp @@ -17,11 +17,11 @@ #include "tests\data\DataAsserts.hh" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -46,7 +46,7 @@ TEST_CLASS(IntegrationMenuViewModel_Tests) public: ra::api::mocks::MockServer mockServer; ra::context::mocks::MockRcClient mockRcClient; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; diff --git a/tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp index ee24841d0..bb64af75d 100644 --- a/tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp @@ -6,12 +6,12 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockFrameEventQueue.hh" @@ -62,7 +62,7 @@ TEST_CLASS(MemoryBookmarksViewModel_Tests) public: ra::context::mocks::MockRcClient mockRcClient; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockAchievementRuntime mockAchievementRuntime; @@ -1950,7 +1950,7 @@ TEST_CLASS(MemoryBookmarksViewModel_Tests) std::array memory{}; bookmarks.mockEmulatorContext.MockMemory(memory); bookmarks.mockConsoleContext.AddMemoryRegion(0U, 16, - ra::data::context::ConsoleContext::AddressType::SystemRAM); + ra::data::MemoryRegion::Type::SystemRAM); bookmarks.AddBookmark("I:0xX0004_M:0xH0008"); auto* pBookmark = bookmarks.GetBookmark(0); @@ -2010,7 +2010,7 @@ TEST_CLASS(MemoryBookmarksViewModel_Tests) std::array memory{}; bookmarks.mockEmulatorContext.MockMemory(memory); bookmarks.mockConsoleContext.AddMemoryRegion(0U, 16, - ra::data::context::ConsoleContext::AddressType::SystemRAM); + ra::data::MemoryRegion::Type::SystemRAM); memory.at(4) = 4; memory.at(8) = pMemory[0]; diff --git a/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp index 19a987caa..a8e2e5e52 100644 --- a/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp @@ -8,12 +8,12 @@ #include "tests\ui\UIAsserts.hh" #include "tests\RA_UnitTestHelpers.h" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -37,7 +37,7 @@ TEST_CLASS(MemoryInspectorViewModel_Tests) public: ra::api::mocks::MockServer mockServer; ra::context::mocks::MockRcClient mockRcClient; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; diff --git a/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp index 06e47ae31..8212947d9 100644 --- a/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp @@ -3,10 +3,10 @@ #include "ui\EditorTheme.hh" #include "ui\viewmodels\MemoryRegionsViewModel.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\ui\UIAsserts.hh" #include "tests\RA_UnitTestHelpers.h" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -26,7 +26,7 @@ TEST_CLASS(MemoryRegionsViewModel_Tests) class MemoryRegionsViewModelHarness : public MemoryRegionsViewModel { public: - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::services::mocks::MockConfiguration mockConfiguration; @@ -47,9 +47,9 @@ TEST_CLASS(MemoryRegionsViewModel_Tests) void MockRegions() { - mockConsoleContext.AddMemoryRegion(0x0000, 0x1FFF, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM"); - mockConsoleContext.AddMemoryRegion(0x2000, 0x3FFF, ra::data::context::ConsoleContext::AddressType::VideoRAM, "Video RAM"); - mockConsoleContext.AddMemoryRegion(0x4000, 0x7FFF, ra::data::context::ConsoleContext::AddressType::SaveRAM, "Cartridge RAM"); + mockConsoleContext.AddMemoryRegion(0x0000, 0x1FFF, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); + mockConsoleContext.AddMemoryRegion(0x2000, 0x3FFF, ra::data::MemoryRegion::Type::VideoRAM, L"Video RAM"); + mockConsoleContext.AddMemoryRegion(0x4000, 0x7FFF, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM"); InitializeRegions(); } }; diff --git a/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp b/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp index 4563a68e2..726351e31 100644 --- a/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp @@ -6,11 +6,11 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -89,7 +89,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) mockGameContext.InitializeCodeNotes(); } - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; @@ -1392,7 +1392,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) { // only system range defined MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0U, 0xFFFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM"); + search.mockConsoleContext.AddMemoryRegion(0U, 0xFFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 2U }, search.PredefinedFilterRanges().Count()); @@ -1406,8 +1406,8 @@ TEST_CLASS(MemorySearchViewModel_Tests) { // system and game ranges defined MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0U, 0xBFFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM"); - search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM, "Cartridge RAM"); + search.mockConsoleContext.AddMemoryRegion(0U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); + search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM"); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 4U }, search.PredefinedFilterRanges().Count()); @@ -1425,10 +1425,10 @@ TEST_CLASS(MemorySearchViewModel_Tests) { // multiple similar system and game ranges defined MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM"); - search.mockConsoleContext.AddMemoryRegion(0x8000U, 0xBFFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM"); - search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM, "Cartridge RAM"); - search.mockConsoleContext.AddMemoryRegion(0xF000U, 0xFFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM, "Cartridge RAM"); + search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); + search.mockConsoleContext.AddMemoryRegion(0x8000U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); + search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM"); + search.mockConsoleContext.AddMemoryRegion(0xF000U, 0xFFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM"); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 4U }, search.PredefinedFilterRanges().Count()); @@ -1446,10 +1446,10 @@ TEST_CLASS(MemorySearchViewModel_Tests) { // multiple distinct system and game ranges defined MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM 1"); - search.mockConsoleContext.AddMemoryRegion(0x8000U, 0xBFFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM 2"); - search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM, "Cartridge RAM 1"); - search.mockConsoleContext.AddMemoryRegion(0xF000U, 0xFFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM, "Cartridge RAM 2"); + search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM 1"); + search.mockConsoleContext.AddMemoryRegion(0x8000U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM 2"); + search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM 1"); + search.mockConsoleContext.AddMemoryRegion(0xF000U, 0xFFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM 2"); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 8U }, search.PredefinedFilterRanges().Count()); @@ -1475,22 +1475,22 @@ TEST_CLASS(MemorySearchViewModel_Tests) { // non-system/cartridge memory regions should be ignored MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0x0000U, 0x00FFU, ra::data::context::ConsoleContext::AddressType::HardwareController, "Interrupt Vector"); - search.mockConsoleContext.AddMemoryRegion(0x0100U, 0x014FU, ra::data::context::ConsoleContext::AddressType::ReadOnlyMemory, "Cartridge Header"); - search.mockConsoleContext.AddMemoryRegion(0x0150U, 0x3FFFU, ra::data::context::ConsoleContext::AddressType::ReadOnlyMemory, "Cartridge ROM (fixed)"); - search.mockConsoleContext.AddMemoryRegion(0x4000U, 0x7FFFU, ra::data::context::ConsoleContext::AddressType::ReadOnlyMemory, "Cartridge ROM (paged)"); - search.mockConsoleContext.AddMemoryRegion(0x8000U, 0x97FFU, ra::data::context::ConsoleContext::AddressType::VideoRAM, "Title RAM"); - search.mockConsoleContext.AddMemoryRegion(0x9800U, 0x9BFFU, ra::data::context::ConsoleContext::AddressType::VideoRAM, "BG1 map data"); - search.mockConsoleContext.AddMemoryRegion(0x9C00U, 0x9FFFU, ra::data::context::ConsoleContext::AddressType::VideoRAM, "MD2 map data"); - search.mockConsoleContext.AddMemoryRegion(0xA000U, 0xBFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM, "Cartridge RAM (bank 0)"); - search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM (fixed)"); - search.mockConsoleContext.AddMemoryRegion(0xD000U, 0xDFFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM (fixed)"); - search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xFDFFU, ra::data::context::ConsoleContext::AddressType::VirtualRAM, "Echo RAM"); - search.mockConsoleContext.AddMemoryRegion(0xFE00U, 0xFE9FU, ra::data::context::ConsoleContext::AddressType::VideoRAM, "Sprite RAM"); - search.mockConsoleContext.AddMemoryRegion(0xFEA0U, 0xFEFFU, ra::data::context::ConsoleContext::AddressType::Unused, ""); - search.mockConsoleContext.AddMemoryRegion(0xFF00U, 0xFF7FU, ra::data::context::ConsoleContext::AddressType::HardwareController, "Hardware I/O"); - search.mockConsoleContext.AddMemoryRegion(0xFF80U, 0xFFFEU, ra::data::context::ConsoleContext::AddressType::SystemRAM, "Quick RAM"); - search.mockConsoleContext.AddMemoryRegion(0xFFFFU, 0xFFFFU, ra::data::context::ConsoleContext::AddressType::HardwareController, "Interrupt Enable"); + search.mockConsoleContext.AddMemoryRegion(0x0000U, 0x00FFU, ra::data::MemoryRegion::Type::HardwareController, L"Interrupt Vector"); + search.mockConsoleContext.AddMemoryRegion(0x0100U, 0x014FU, ra::data::MemoryRegion::Type::ReadOnlyMemory, L"Cartridge Header"); + search.mockConsoleContext.AddMemoryRegion(0x0150U, 0x3FFFU, ra::data::MemoryRegion::Type::ReadOnlyMemory, L"Cartridge ROM (fixed)"); + search.mockConsoleContext.AddMemoryRegion(0x4000U, 0x7FFFU, ra::data::MemoryRegion::Type::ReadOnlyMemory, L"Cartridge ROM (paged)"); + search.mockConsoleContext.AddMemoryRegion(0x8000U, 0x97FFU, ra::data::MemoryRegion::Type::VideoRAM, L"Title RAM"); + search.mockConsoleContext.AddMemoryRegion(0x9800U, 0x9BFFU, ra::data::MemoryRegion::Type::VideoRAM, L"BG1 map data"); + search.mockConsoleContext.AddMemoryRegion(0x9C00U, 0x9FFFU, ra::data::MemoryRegion::Type::VideoRAM, L"MD2 map data"); + search.mockConsoleContext.AddMemoryRegion(0xA000U, 0xBFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM (bank 0)"); + search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM (fixed)"); + search.mockConsoleContext.AddMemoryRegion(0xD000U, 0xDFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM (fixed)"); + search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xFDFFU, ra::data::MemoryRegion::Type::VirtualRAM, L"Echo RAM"); + search.mockConsoleContext.AddMemoryRegion(0xFE00U, 0xFE9FU, ra::data::MemoryRegion::Type::VideoRAM, L"Sprite RAM"); + search.mockConsoleContext.AddMemoryRegion(0xFEA0U, 0xFEFFU, ra::data::MemoryRegion::Type::Unused, L""); + search.mockConsoleContext.AddMemoryRegion(0xFF00U, 0xFF7FU, ra::data::MemoryRegion::Type::HardwareController, L"Hardware I/O"); + search.mockConsoleContext.AddMemoryRegion(0xFF80U, 0xFFFEU, ra::data::MemoryRegion::Type::SystemRAM, L"Quick RAM"); + search.mockConsoleContext.AddMemoryRegion(0xFFFFU, 0xFFFFU, ra::data::MemoryRegion::Type::HardwareController, L"Interrupt Enable"); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 6U }, search.PredefinedFilterRanges().Count()); @@ -1511,8 +1511,8 @@ TEST_CLASS(MemorySearchViewModel_Tests) TEST_METHOD(TestPredefinedFilterRangeAll) { MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM); - search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM); + search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM); + search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); search.SetFilterRange(L"0x0000-0x1FFF"); @@ -1523,8 +1523,8 @@ TEST_CLASS(MemorySearchViewModel_Tests) TEST_METHOD(TestPredefinedFilterRangeSystem) { MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM); - search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM); + search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM); + search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); search.SetFilterRange(L"0x0000-0x1FFF"); @@ -1535,8 +1535,8 @@ TEST_CLASS(MemorySearchViewModel_Tests) TEST_METHOD(TestPredefinedFilterRangeGame) { MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM); - search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM); + search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM); + search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); search.SetFilterRange(L"0x0000-0x1FFF"); @@ -1547,8 +1547,8 @@ TEST_CLASS(MemorySearchViewModel_Tests) TEST_METHOD(TestPredefinedFilterRangeCustom) { MemorySearchViewModelHarness search; - search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::context::ConsoleContext::AddressType::SystemRAM); - search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::context::ConsoleContext::AddressType::SaveRAM); + search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM); + search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM); search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); search.SetFilterRange(L"0x0000-0x1FFF"); @@ -1776,7 +1776,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) { MemorySearchViewModelHarness search; search.InitializeMemory(); - search.mockConsoleContext.AddMemoryRegion({ 0U }, { 0xFFU }, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System RAM"); + search.mockConsoleContext.AddMemoryRegion({ 0U }, { 0xFFU }, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); search.BeginNewSearch(); search.SetComparisonType(ComparisonType::Equals); diff --git a/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp index 423206826..65bc8d297 100644 --- a/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp @@ -5,8 +5,8 @@ #include "services\ServiceLocator.hh" #include "tests\RA_UnitTestHelpers.h" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockWindowManager.hh" @@ -33,7 +33,7 @@ TEST_CLASS(MemoryViewerViewModel_Tests) class MemoryViewerViewModelHarness : public MemoryViewerViewModel { public: - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::ui::viewmodels::mocks::MockWindowManager mockWindowManager; @@ -1730,8 +1730,8 @@ TEST_CLASS(MemoryViewerViewModel_Tests) viewer.SetAddress(0); viewer.mockConsoleContext.ResetMemoryRegions(); - viewer.mockConsoleContext.AddMemoryRegion(0, 0x3F, ra::data::context::ConsoleContext::AddressType::Unused, "Unused"); - viewer.mockConsoleContext.AddMemoryRegion(0x40, 0xFF, ra::data::context::ConsoleContext::AddressType::SystemRAM, "System"); + viewer.mockConsoleContext.AddMemoryRegion(0, 0x3F, ra::data::MemoryRegion::Type::Unused, L"Unused"); + viewer.mockConsoleContext.AddMemoryRegion(0x40, 0xFF, ra::data::MemoryRegion::Type::SystemRAM, L"System"); // initial address should skip over the unused region viewer.mockEmulatorContext.MockTotalMemorySizeChanged(256); diff --git a/tests/ui/viewmodels/MemoryWatchListViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryWatchListViewModel_Tests.cpp index a34ac0696..b1ae67cfb 100644 --- a/tests/ui/viewmodels/MemoryWatchListViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryWatchListViewModel_Tests.cpp @@ -5,12 +5,12 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockFrameEventQueue.hh" @@ -34,7 +34,7 @@ TEST_CLASS(MemoryWatchListViewModel_Tests) public: ra::context::mocks::MockRcClient mockRcClient; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockAchievementRuntime mockAchievementRuntime; diff --git a/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp b/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp index 65a7e7fca..561fc3378 100644 --- a/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp +++ b/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp @@ -8,11 +8,11 @@ #include "tests\ui\UIAsserts.hh" #include "tests\RA_UnitTestHelpers.h" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockClipboard.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -34,7 +34,7 @@ TEST_CLASS(PointerInspectorViewModel_Tests) class PointerInspectorViewModelHarness : public PointerInspectorViewModel { public: - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; @@ -956,7 +956,7 @@ TEST_CLASS(PointerInspectorViewModel_Tests) inspector.mockGameContext.NotifyActiveGameChanged(); // enable note support std::array memory = {}; - inspector.mockConsoleContext.AddMemoryRegion(0x00, 0x3F, ra::data::context::ConsoleContext::AddressType::SystemRAM); + inspector.mockConsoleContext.AddMemoryRegion(0x00, 0x3F, ra::data::MemoryRegion::Type::SystemRAM); inspector.mockEmulatorContext.MockMemory(memory); inspector.mockGameContext.Assets().FindCodeNotes()->SetCodeNote({4U}, @@ -1041,7 +1041,7 @@ TEST_CLASS(PointerInspectorViewModel_Tests) inspector.mockGameContext.NotifyActiveGameChanged(); // enable note support std::array memory = {}; - inspector.mockConsoleContext.AddMemoryRegion(0x00, 0x3F, ra::data::context::ConsoleContext::AddressType::SystemRAM); + inspector.mockConsoleContext.AddMemoryRegion(0x00, 0x3F, ra::data::MemoryRegion::Type::SystemRAM); inspector.mockEmulatorContext.MockMemory(memory); inspector.mockGameContext.Assets().FindCodeNotes()->SetCodeNote({ 4U }, @@ -1078,7 +1078,7 @@ TEST_CLASS(PointerInspectorViewModel_Tests) inspector.mockGameContext.NotifyActiveGameChanged(); // enable note support std::array memory = {}; - inspector.mockConsoleContext.AddMemoryRegion(0x00, 0x3F, ra::data::context::ConsoleContext::AddressType::SystemRAM); + inspector.mockConsoleContext.AddMemoryRegion(0x00, 0x3F, ra::data::MemoryRegion::Type::SystemRAM); inspector.mockEmulatorContext.MockMemory(memory); inspector.mockGameContext.Assets().FindCodeNotes()->SetCodeNote({ 4U }, @@ -1112,7 +1112,7 @@ TEST_CLASS(PointerInspectorViewModel_Tests) inspector.mockGameContext.NotifyActiveGameChanged(); // enable note support std::array memory = {}; - inspector.mockConsoleContext.AddMemoryRegion(0x00, 0x3F, ra::data::context::ConsoleContext::AddressType::SystemRAM); + inspector.mockConsoleContext.AddMemoryRegion(0x00, 0x3F, ra::data::MemoryRegion::Type::SystemRAM); inspector.mockEmulatorContext.MockMemory(memory); inspector.mockGameContext.Assets().FindCodeNotes()->SetCodeNote({ 4U }, diff --git a/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp b/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp index 9dcea1dac..458823778 100644 --- a/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp +++ b/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp @@ -7,9 +7,9 @@ #include "ui\viewmodels\TriggerViewModel.hh" #include "tests\RA_UnitTestHelpers.h" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockUserContext.hh" @@ -959,7 +959,7 @@ TEST_CLASS(TriggerConditionViewModel_Tests) TEST_METHOD(TestTooltipIndirectAddressCodeNoteOverflow) { IndirectAddressTriggerViewModelHarness vmTrigger; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; vmTrigger.Parse("I:0xX0000_0xH80000002=6"); vmTrigger.mockConfiguration.SetFeatureEnabled(ra::services::Feature::PreferDecimal, true); vmTrigger.mockGameContext.SetCodeNote({0U}, L"[32-bit pointer]\n+0x80000002=This is a note."); @@ -987,7 +987,7 @@ TEST_CLASS(TriggerConditionViewModel_Tests) TEST_METHOD(TestTooltipIndirectAddressCodeNoteMasked) { IndirectAddressTriggerViewModelHarness vmTrigger; - ra::data::context::mocks::MockConsoleContext mockConsoleContext(ConsoleID::PSP, L"PSP"); + ra::context::mocks::MockConsoleContext mockConsoleContext(ConsoleID::PSP, L"PSP"); vmTrigger.Parse("I:0xX0000&33554431_0xH0002=6"); // 33554431 = 0x01FFFFFF vmTrigger.mockConfiguration.SetFeatureEnabled(ra::services::Feature::PreferDecimal, true); vmTrigger.mockGameContext.SetCodeNote({0U}, L"[32-bit pointer]\n+2=This is a note."); @@ -1015,7 +1015,7 @@ TEST_CLASS(TriggerConditionViewModel_Tests) TEST_METHOD(TestTooltipDoubleIndirectAddress) { IndirectAddressTriggerViewModelHarness vmTrigger; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; vmTrigger.mockGameContext.InitializeCodeNotes(); vmTrigger.Parse("I:0xH0001_I:0xH0002_0xH0003=4"); vmTrigger.mockConfiguration.SetFeatureEnabled(ra::services::Feature::PreferDecimal, true); @@ -1048,7 +1048,7 @@ TEST_CLASS(TriggerConditionViewModel_Tests) TEST_METHOD(TestTooltipDoubleIndirectAddressExternal) { IndirectAddressTriggerViewModelHarness vmTrigger; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; vmTrigger.Parse("I:0xH0001_I:0xH0002_0xH0003=4"); vmTrigger.mockConfiguration.SetFeatureEnabled(ra::services::Feature::PreferDecimal, true); @@ -1095,7 +1095,7 @@ TEST_CLASS(TriggerConditionViewModel_Tests) TEST_METHOD(TestTooltipDoubleIndirectAddressValue) { IndirectAddressTriggerViewModelHarness vmTrigger; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; vmTrigger.SetIsValue(true); vmTrigger.Parse("I:0xH0001_I:0xH0002_M:0xH0003=4"); vmTrigger.mockConfiguration.SetFeatureEnabled(ra::services::Feature::PreferDecimal, true); diff --git a/tests/ui/viewmodels/TriggerViewModel_Tests.cpp b/tests/ui/viewmodels/TriggerViewModel_Tests.cpp index 21a0181b5..bd9934a04 100644 --- a/tests/ui/viewmodels/TriggerViewModel_Tests.cpp +++ b/tests/ui/viewmodels/TriggerViewModel_Tests.cpp @@ -3,9 +3,9 @@ #include "ui\viewmodels\TriggerViewModel.hh" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\mocks\MockClipboard.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockEmulatorContext.hh" @@ -26,7 +26,7 @@ TEST_CLASS(TriggerViewModel_Tests) class TriggerViewModelHarness : public TriggerViewModel { public: - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; diff --git a/tests/ui/viewmodels/UnknownGameViewModel_Tests.cpp b/tests/ui/viewmodels/UnknownGameViewModel_Tests.cpp index c1149e99d..2de48e240 100644 --- a/tests/ui/viewmodels/UnknownGameViewModel_Tests.cpp +++ b/tests/ui/viewmodels/UnknownGameViewModel_Tests.cpp @@ -4,11 +4,11 @@ #include "services\ServiceLocator.hh" +#include "tests\devkit\context\mocks\MockConsoleContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockClipboard.hh" -#include "tests\mocks\MockConsoleContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockLocalStorage.hh" @@ -32,7 +32,7 @@ TEST_CLASS(UnknownGameViewModel_Tests) public: ra::api::mocks::MockServer mockServer; ra::context::mocks::MockRcClient mockRcClient; - ra::data::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockAchievementRuntime mockAchievementRuntime; From 280f73315c9594c5c3cf86e55a4299924a5a8777 Mon Sep 17 00:00:00 2001 From: Jamiras Date: Sat, 3 Jan 2026 16:38:13 -0700 Subject: [PATCH 2/5] fix copy/paste error --- src/devkit/data/MemoryRegion.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devkit/data/MemoryRegion.hh b/src/devkit/data/MemoryRegion.hh index eb63da901..f0c0259a0 100644 --- a/src/devkit/data/MemoryRegion.hh +++ b/src/devkit/data/MemoryRegion.hh @@ -103,7 +103,7 @@ public: const Type GetType() const noexcept { return m_nType; } /// - /// Gets the type of the region. + /// Sets the type of the region. /// void SetType(Type nType) noexcept { m_nType = nType; } From d4219e7944634f59d77650fb7a218fb226d495e3 Mon Sep 17 00:00:00 2001 From: Jamiras Date: Wed, 7 Jan 2026 10:56:48 -0700 Subject: [PATCH 3/5] MemBlock -> CapturedMemoryBlock --- src/RA_Integration.vcxproj | 2 - src/RA_Integration.vcxproj.filters | 9 - src/data/context/EmulatorContext.cpp | 4 +- src/data/context/EmulatorContext.hh | 4 +- src/data/search/MemBlock.hh | 127 ---------- src/devkit/RADevKit.vcxproj | 2 + src/devkit/RADevKit.vcxproj.filters | 6 + .../data/CapturedMemoryBlock.cpp} | 222 +++++++++--------- src/devkit/data/CapturedMemoryBlock.hh | 207 ++++++++++++++++ src/services/Search/SearchImpl.cpp | 14 +- src/services/Search/SearchImpl.hh | 18 +- src/services/Search/SearchImpl_16bit.hh | 4 +- .../Search/SearchImpl_16bit_aligned.hh | 6 +- src/services/Search/SearchImpl_16bit_be.hh | 4 +- .../Search/SearchImpl_16bit_be_aligned.hh | 4 +- src/services/Search/SearchImpl_32bit.hh | 4 +- .../Search/SearchImpl_32bit_aligned.hh | 6 +- src/services/Search/SearchImpl_32bit_be.hh | 4 +- .../Search/SearchImpl_32bit_be_aligned.hh | 4 +- src/services/Search/SearchImpl_4bit.hh | 6 +- src/services/Search/SearchImpl_8bit.hh | 4 +- src/services/Search/SearchImpl_bitcount.hh | 2 +- .../Search/SearchImpl_double32_aligned.hh | 6 +- .../Search/SearchImpl_double32_be_aligned.hh | 6 +- src/services/Search/SearchImpl_float.hh | 4 +- .../Search/SearchImpl_float_aligned.hh | 6 +- .../Search/SearchImpl_float_be_aligned.hh | 6 +- src/services/SearchResults.cpp | 9 +- src/services/SearchResults.h | 4 +- tests/RA_Integration.Tests.vcxproj | 1 - tests/RA_Integration.Tests.vcxproj.filters | 3 - tests/data/context/EmulatorContext_Tests.cpp | 10 +- 32 files changed, 400 insertions(+), 318 deletions(-) delete mode 100644 src/data/search/MemBlock.hh rename src/{data/search/MemBlock.cpp => devkit/data/CapturedMemoryBlock.cpp} (52%) create mode 100644 src/devkit/data/CapturedMemoryBlock.hh diff --git a/src/RA_Integration.vcxproj b/src/RA_Integration.vcxproj index 1b3f1580c..71f7bc2ab 100644 --- a/src/RA_Integration.vcxproj +++ b/src/RA_Integration.vcxproj @@ -92,7 +92,6 @@ - Create @@ -234,7 +233,6 @@ - diff --git a/src/RA_Integration.vcxproj.filters b/src/RA_Integration.vcxproj.filters index f87f1e472..0e6cbdd51 100644 --- a/src/RA_Integration.vcxproj.filters +++ b/src/RA_Integration.vcxproj.filters @@ -52,9 +52,6 @@ {e978c08c-fedb-4ead-af63-0420b26291bb} - - {94064815-198f-4ee6-bdea-3a44f8b79d2d} - @@ -399,9 +396,6 @@ Services\Search - - Data\Search - UI\ViewModels @@ -1010,9 +1004,6 @@ Services\Search - - Data\Search - UI\ViewModels diff --git a/src/data/context/EmulatorContext.cpp b/src/data/context/EmulatorContext.cpp index baf12f82c..f2d2dd229 100644 --- a/src/data/context/EmulatorContext.cpp +++ b/src/data/context/EmulatorContext.cpp @@ -1126,7 +1126,7 @@ bool EmulatorContext::IsMemoryInsecure() const _CONSTANT_VAR MAX_BLOCK_SIZE = 256U * 1024; // 256K -void EmulatorContext::CaptureMemory(std::vector& vBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const +void EmulatorContext::CaptureMemory(std::vector& vBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const { ra::data::ByteAddress nAdjustedAddress = nAddress; for (const auto& pMemoryBlock : m_vMemoryBlocks) @@ -1151,7 +1151,7 @@ void EmulatorContext::CaptureMemory(std::vector& vBl while (nToRead > 0) { - ra::data::search::MemBlock* pBlock = nullptr; + ra::data::CapturedMemoryBlock* pBlock = nullptr; const uint32_t nBlockSize = std::min(nToRead, MAX_BLOCK_SIZE); const bool bIsLastBlock = (nCount == 0 && nBlockSize == nToRead); diff --git a/src/data/context/EmulatorContext.hh b/src/data/context/EmulatorContext.hh index 5cba48d43..a53e0c708 100644 --- a/src/data/context/EmulatorContext.hh +++ b/src/data/context/EmulatorContext.hh @@ -9,7 +9,7 @@ #include #include "data\NotifyTargetSet.hh" -#include "data\search\MemBlock.hh" +#include "data\CapturedMemoryBlock.hh" namespace ra { namespace data { @@ -246,7 +246,7 @@ public: /// /// Captures the current state of memory /// - void CaptureMemory(std::vector& vMemBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const; + void CaptureMemory(std::vector& vMemBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const; /// /// Converts an address to a displayable string. diff --git a/src/data/search/MemBlock.hh b/src/data/search/MemBlock.hh deleted file mode 100644 index acd38be14..000000000 --- a/src/data/search/MemBlock.hh +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef SEARCH_MEMBLOCK_H -#define SEARCH_MEMBLOCK_H -#pragma once - -#include "data\Memory.hh" - -namespace ra { -namespace data { -namespace search { - -class MemBlock -{ -private: - struct AllocatedMemory - { - uint32_t nReferenceCount; - uint32_t nHash; - uint8_t pBytes[16]; - }; - -public: - explicit MemBlock(_In_ uint32_t nAddress, _In_ uint32_t nSize, _In_ uint32_t nMaxAddresses) : - m_nFirstAddress(nAddress), - m_nBytesSize(nSize), - m_nMatchingAddresses(nMaxAddresses), - m_nMaxAddresses(nMaxAddresses) - { - if (IsBytesAllocated()) - { - const auto nAllocSize = sizeof(AllocatedMemory) - sizeof(m_pAllocatedMemory->pBytes) + - ((gsl::narrow_cast(nSize) + 3) & ~3); - m_pAllocatedMemory = static_cast(malloc(nAllocSize)); - Expects(m_pAllocatedMemory != nullptr); - m_pAllocatedMemory->nReferenceCount = 1; - m_pAllocatedMemory->nHash = 0; - } - } - - MemBlock(const MemBlock& other) noexcept; - MemBlock& operator=(const MemBlock&) noexcept = delete; - MemBlock(MemBlock&& other) noexcept; - MemBlock& operator=(MemBlock&&) noexcept = delete; - - ~MemBlock() noexcept; - - uint8_t* GetBytes() noexcept - { - return IsBytesAllocated() ? &m_pAllocatedMemory->pBytes[0] : &m_vBytes[0]; - } - const uint8_t* GetBytes() const noexcept - { - return IsBytesAllocated() ? &m_pAllocatedMemory->pBytes[0] : &m_vBytes[0]; - } - - void SetFirstAddress(ra::data::ByteAddress nAddress) noexcept { m_nFirstAddress = nAddress; } - ra::data::ByteAddress GetFirstAddress() const noexcept { return m_nFirstAddress; } - uint32_t GetBytesSize() const noexcept { return m_nBytesSize & 0x00FFFFFF; } - bool IsBytesAllocated() const noexcept { return GetBytesSize() > sizeof(m_vBytes); } - void SetMaxAddresses(uint32_t nMaxAddresses) noexcept { m_nMaxAddresses = nMaxAddresses; } - uint32_t GetMaxAddresses() const noexcept { return m_nMaxAddresses; } - - bool ContainsAddress(ra::data::ByteAddress nAddress) const noexcept; - - void SetMatchingAddresses(std::vector& vAddresses, gsl::index nFirstIndex, gsl::index nLastIndex); - void CopyMatchingAddresses(const MemBlock& pSource); - void ExcludeMatchingAddress(ra::data::ByteAddress nAddress); - bool ContainsMatchingAddress(ra::data::ByteAddress nAddress) const; - - void SetMatchingAddressCount(uint32_t nCount) noexcept { m_nMatchingAddresses = nCount; } - uint32_t GetMatchingAddressCount() const noexcept { return m_nMatchingAddresses; } - ra::data::ByteAddress GetMatchingAddress(gsl::index nIndex) const noexcept; - bool AreAllAddressesMatching() const noexcept { return m_nMatchingAddresses == m_nMaxAddresses; } - - const uint8_t* GetMatchingAddressPointer() const noexcept - { - if (AreAllAddressesMatching()) - return nullptr; - - const auto nAddressesSize = (m_nMaxAddresses + 7) / 8; - return (nAddressesSize > sizeof(m_vAddresses)) ? m_pAddresses : &m_vAddresses[0]; - } - - bool HasMatchingAddress(const uint8_t* pMatchingAddresses, ra::data::ByteAddress nAddress) const noexcept - { - if (!pMatchingAddresses) - return true; - - const auto nIndex = nAddress - m_nFirstAddress; - if (nIndex >= m_nMaxAddresses) - return false; - - const auto nBit = 1 << (nIndex & 7); - return (pMatchingAddresses[nIndex >> 3] & nBit); - } - - void ShareMemory(const std::vector& vBlocks, uint32_t nHash) noexcept; - void OptimizeMemory(const std::vector& vBlocks) noexcept; - -private: - uint8_t* AllocateMatchingAddresses() noexcept; - void SetRepeat(uint32_t nCount, uint32_t nValue) noexcept; - - ra::data::ByteAddress m_nFirstAddress; // 4 bytes - uint32_t m_nBytesSize; // 4 bytes - - union // 8 bytes - { - uint8_t m_vBytes[8]{}; - AllocatedMemory* m_pAllocatedMemory; - }; - - union // 8 bytes - { - uint8_t m_vAddresses[8]{}; - uint8_t* m_pAddresses; - }; - - uint32_t m_nMatchingAddresses; // 4 bytes - uint32_t m_nMaxAddresses; // 4 bytes -}; -static_assert(sizeof(MemBlock) <= 32, "sizeof(MemBlock) is incorrect"); - -} // namespace search -} // namespace services -} // namespace ra - -#endif /* !SEARCH_MEMBLOCK_H */ diff --git a/src/devkit/RADevKit.vcxproj b/src/devkit/RADevKit.vcxproj index 47a914585..ce11eb874 100644 --- a/src/devkit/RADevKit.vcxproj +++ b/src/devkit/RADevKit.vcxproj @@ -59,6 +59,7 @@ + @@ -74,6 +75,7 @@ + diff --git a/src/devkit/RADevKit.vcxproj.filters b/src/devkit/RADevKit.vcxproj.filters index f6d63ddcd..21c3825f7 100644 --- a/src/devkit/RADevKit.vcxproj.filters +++ b/src/devkit/RADevKit.vcxproj.filters @@ -126,6 +126,9 @@ data + + data + @@ -164,5 +167,8 @@ context\impl + + data + \ No newline at end of file diff --git a/src/data/search/MemBlock.cpp b/src/devkit/data/CapturedMemoryBlock.cpp similarity index 52% rename from src/data/search/MemBlock.cpp rename to src/devkit/data/CapturedMemoryBlock.cpp index fdb7f82af..2f00b39d4 100644 --- a/src/data/search/MemBlock.cpp +++ b/src/devkit/data/CapturedMemoryBlock.cpp @@ -1,16 +1,13 @@ -#include "MemBlock.hh" - -#include "util\GSL.hh" +#include "CapturedMemoryBlock.hh" namespace ra { namespace data { -namespace search { -MemBlock::MemBlock(const MemBlock& other) noexcept : +CapturedMemoryBlock::CapturedMemoryBlock(const CapturedMemoryBlock& other) noexcept : m_nFirstAddress(other.m_nFirstAddress), m_nBytesSize(other.m_nBytesSize), - m_nMatchingAddresses(other.m_nMatchingAddresses), - m_nMaxAddresses(other.m_nMaxAddresses) + m_nMatchingAddressCount(other.m_nMatchingAddressCount), + m_nAddressCount(other.m_nAddressCount) { if (IsBytesAllocated()) { @@ -22,14 +19,14 @@ MemBlock::MemBlock(const MemBlock& other) noexcept : std::memcpy(m_vBytes, other.m_vBytes, sizeof(m_vBytes)); } - m_nMatchingAddresses = other.m_nMatchingAddresses; + m_nMatchingAddressCount = other.m_nMatchingAddressCount; if (!AreAllAddressesMatching()) { - if ((m_nMatchingAddresses + 7) / 8 > sizeof(m_vAddresses)) + if ((m_nMatchingAddressCount + 7) / 8 > sizeof(m_vAddresses)) { auto* pAddresses = AllocateMatchingAddresses(); if (pAddresses != nullptr) - std::memcpy(pAddresses, other.m_pAddresses, (m_nMatchingAddresses + 7) / 8); + std::memcpy(pAddresses, other.m_pAddresses, (m_nMatchingAddressCount + 7) / 8); } else { @@ -38,11 +35,11 @@ MemBlock::MemBlock(const MemBlock& other) noexcept : } } -MemBlock::MemBlock(MemBlock&& other) noexcept : +CapturedMemoryBlock::CapturedMemoryBlock(CapturedMemoryBlock&& other) noexcept : m_nFirstAddress(other.m_nFirstAddress), m_nBytesSize(other.m_nBytesSize), - m_nMatchingAddresses(other.m_nMatchingAddresses), - m_nMaxAddresses(other.m_nMaxAddresses) + m_nMatchingAddressCount(other.m_nMatchingAddressCount), + m_nAddressCount(other.m_nAddressCount) { if (other.IsBytesAllocated()) { @@ -57,11 +54,11 @@ MemBlock::MemBlock(MemBlock&& other) noexcept : if (!AreAllAddressesMatching()) { - if ((m_nMatchingAddresses + 7) / 8 > sizeof(m_vAddresses)) + if ((m_nMatchingAddressCount + 7) / 8 > sizeof(m_vAddresses)) { m_pAddresses = other.m_pAddresses; other.m_pAddresses = nullptr; - other.m_nMatchingAddresses = 0; + other.m_nMatchingAddressCount = 0; } else { @@ -70,7 +67,7 @@ MemBlock::MemBlock(MemBlock&& other) noexcept : } } -MemBlock::~MemBlock() noexcept +CapturedMemoryBlock::~CapturedMemoryBlock() noexcept { if (IsBytesAllocated()) { @@ -79,11 +76,11 @@ MemBlock::~MemBlock() noexcept free(m_pAllocatedMemory); } - if (!AreAllAddressesMatching() && (m_nMatchingAddresses + 7) / 8 > sizeof(m_vAddresses)) + if (!AreAllAddressesMatching() && (m_nMatchingAddressCount + 7) / 8 > sizeof(m_vAddresses)) delete[] m_pAddresses; } -void MemBlock::ShareMemory(const std::vector& vBlocks, uint32_t nHash) noexcept +void CapturedMemoryBlock::ShareMemory(const std::vector& vBlocks, uint32_t nHash) noexcept { if (IsBytesAllocated()) { @@ -111,14 +108,14 @@ void MemBlock::ShareMemory(const std::vector& vBlocks, uint32_t nHash) } } -void MemBlock::SetRepeat(uint32_t nCount, uint32_t nValue) noexcept -{ - m_nBytesSize = (nCount * sizeof(uint32_t)) | 0x01000000; - memcpy(m_vBytes, &nValue, 4); - memcpy(&m_vBytes[4], &nValue, 4); -} +//void CapturedMemoryBlock::SetRepeat(uint32_t nCount, uint32_t nValue) noexcept +//{ +// m_nBytesSize = (nCount * sizeof(uint32_t)) | 0x01000000; +// memcpy(m_vBytes, &nValue, 4); +// memcpy(&m_vBytes[4], &nValue, 4); +//} -void MemBlock::OptimizeMemory(const std::vector& vBlocks) noexcept +void CapturedMemoryBlock::OptimizeMemory(const std::vector& vBlocks) noexcept { if (!IsBytesAllocated()) return; @@ -135,12 +132,18 @@ void MemBlock::OptimizeMemory(const std::vector& vBl GSL_SUPPRESS_TYPE1 const auto* pStop = reinterpret_cast(pBytes + GetBytesSize()); - //const auto* pUniqueStart = pScan; + +#ifdef COLLAPSE_FILLED + // TODO: this attempts to identify large chunks of repeated data to avoid + // allocating AllocatedMemory for them. However, that breaks anything + // trying to read from the GetBytes() pointer, so its unfeasible at this time. + + const auto* pUniqueStart = pScan; uint32_t nHash = *pScan++; uint32_t nLast = nHash; uint32_t nRepeat = 1; - //bool bWasSplit = false; - //uint32_t nAddress = GetFirstAddress(); + bool bWasSplit = false; + uint32_t nAddress = GetFirstAddress(); while (pScan < pStop) { @@ -151,26 +154,26 @@ void MemBlock::OptimizeMemory(const std::vector& vBl } else { - //if (nRepeat >= 64 / 4) // 64 bytes of repeated data - //{ - // const auto* pRepeatStart = pScan - nRepeat - 1; - // const auto nUniqueSize = (pRepeatStart - pUniqueStart) * sizeof(uint32_t); - // if (nUniqueSize) - // { - // auto& pUniqueBlock = vBlocks.emplace_back(nAddress, nUniqueSize, nUniqueSize); - // memcpy(pUniqueBlock.GetBytes(), pUniqueStart, nUniqueSize); - // pUniqueBlock.ShareMemory(vBlocks, nHash); - // nAddress += nUniqueSize; - // } - - // auto& pRepeatBlock = vBlocks.emplace_back(nAddress, 0, 0); - // pRepeatBlock.SetRepeat(nRepeat, nLast); - // nAddress += nRepeat * sizeof(uint32_t); - - // pUniqueStart = pScan - 1; - // bWasSplit = true; - // nHash = 0; - //} + if (nRepeat >= 64 / 4) // 64 bytes of repeated data + { + const auto* pRepeatStart = pScan - nRepeat - 1; + const auto nUniqueSize = (pRepeatStart - pUniqueStart) * sizeof(uint32_t); + if (nUniqueSize) + { + auto& pUniqueBlock = vBlocks.emplace_back(nAddress, nUniqueSize, nUniqueSize); + memcpy(pUniqueBlock.GetBytes(), pUniqueStart, nUniqueSize); + pUniqueBlock.ShareMemory(vBlocks, nHash); + nAddress += nUniqueSize; + } + + auto& pRepeatBlock = vBlocks.emplace_back(nAddress, 0, 0); + pRepeatBlock.SetRepeat(nRepeat, nLast); + nAddress += nRepeat * sizeof(uint32_t); + + pUniqueStart = pScan - 1; + bWasSplit = true; + nHash = 0; + } // branchless version of "if (nRepeat & 1) nHash ^= nScan" nHash ^= (nScan * (nRepeat & 1)); @@ -180,46 +183,51 @@ void MemBlock::OptimizeMemory(const std::vector& vBl } } - //if (nRepeat >= 64 / 4) // 64 bytes of repeated data - //{ - // const auto* pRepeatStart = pScan - nRepeat - 1; - // const auto nUniqueSize = (pRepeatStart - pUniqueStart) * sizeof(uint32_t); - // if (nUniqueSize) - // { - // auto& pUniqueBlock = vBlocks.emplace_back(nAddress, nUniqueSize, nUniqueSize); - // memcpy(pUniqueBlock.GetBytes(), pUniqueStart, nUniqueSize); - // pUniqueBlock.ShareMemory(vBlocks, nHash); - // nAddress += nUniqueSize; - // } - - // auto& pRepeatBlock = vBlocks.emplace_back(nAddress, 0, 0); - // pRepeatBlock.SetRepeat(nRepeat, nLast); - // nAddress += nRepeat * sizeof(uint32_t); - - // pUniqueStart = pScan; - //} - - //if (bWasSplit) - //{ - // // copy last block - // const auto nUniqueSize = (pScan - pUniqueStart) * sizeof(uint32_t); - // if (nUniqueSize) - // { - // auto& pUniqueBlock = vBlocks.emplace_back(nAddress, nUniqueSize, nUniqueSize); - // memcpy(pUniqueBlock.GetBytes(), pUniqueStart, nUniqueSize); - // pUniqueBlock.ShareMemory(vBlocks, nHash); - // } - - // vBlocks.erase(this); - // return; - //} + if (nRepeat >= 64 / 4) // 64 bytes of repeated data + { + const auto* pRepeatStart = pScan - nRepeat - 1; + const auto nUniqueSize = (pRepeatStart - pUniqueStart) * sizeof(uint32_t); + if (nUniqueSize) + { + auto& pUniqueBlock = vBlocks.emplace_back(nAddress, nUniqueSize, nUniqueSize); + memcpy(pUniqueBlock.GetBytes(), pUniqueStart, nUniqueSize); + pUniqueBlock.ShareMemory(vBlocks, nHash); + nAddress += nUniqueSize; + } + + auto& pRepeatBlock = vBlocks.emplace_back(nAddress, 0, 0); + pRepeatBlock.SetRepeat(nRepeat, nLast); + nAddress += nRepeat * sizeof(uint32_t); + + pUniqueStart = pScan; + } + + if (bWasSplit) + { + // copy last block + const auto nUniqueSize = (pScan - pUniqueStart) * sizeof(uint32_t); + if (nUniqueSize) + { + auto& pUniqueBlock = vBlocks.emplace_back(nAddress, nUniqueSize, nUniqueSize); + memcpy(pUniqueBlock.GetBytes(), pUniqueStart, nUniqueSize); + pUniqueBlock.ShareMemory(vBlocks, nHash); + } + + vBlocks.erase(this); + return; + } +#else + uint32_t nHash = *pScan++; + while (pScan < pStop) + nHash ^= *pScan++; +#endif ShareMemory(vBlocks, nHash); } -uint8_t* MemBlock::AllocateMatchingAddresses() noexcept +uint8_t* CapturedMemoryBlock::AllocateMatchingAddresses() noexcept { - const auto nAddressesSize = (m_nMaxAddresses + 7) / 8; + const auto nAddressesSize = (m_nAddressCount + 7) / 8; if (nAddressesSize > sizeof(m_vAddresses)) { if (m_pAddresses == nullptr) @@ -231,13 +239,13 @@ uint8_t* MemBlock::AllocateMatchingAddresses() noexcept return &m_vAddresses[0]; } -void MemBlock::SetMatchingAddresses(std::vector& vAddresses, gsl::index nFirstIndex, gsl::index nLastIndex) +void CapturedMemoryBlock::SetMatchingAddresses(std::vector& vAddresses, gsl::index nFirstIndex, gsl::index nLastIndex) { - m_nMatchingAddresses = gsl::narrow_cast(nLastIndex - nFirstIndex) + 1; + m_nMatchingAddressCount = gsl::narrow_cast(nLastIndex - nFirstIndex) + 1; - if (m_nMatchingAddresses != m_nMaxAddresses) + if (m_nMatchingAddressCount != m_nAddressCount) { - const auto nAddressesSize = (m_nMaxAddresses + 7) / 8; + const auto nAddressesSize = (m_nAddressCount + 7) / 8; unsigned char* pAddresses = AllocateMatchingAddresses(); Expects(pAddresses != nullptr); @@ -245,31 +253,34 @@ void MemBlock::SetMatchingAddresses(std::vector& vAddress for (gsl::index nIndex = nFirstIndex; nIndex <= nLastIndex; ++nIndex) { const auto nOffset = vAddresses.at(nIndex) - m_nFirstAddress; - const auto nBit = 1 << (nOffset & 7); - pAddresses[nOffset >> 3] |= nBit; + if (nOffset < m_nAddressCount) + { + const auto nBit = 1 << (nOffset & 7); + pAddresses[nOffset >> 3] |= nBit; + } } } } -void MemBlock::CopyMatchingAddresses(const MemBlock& pSource) +void CapturedMemoryBlock::CopyMatchingAddresses(const CapturedMemoryBlock& pSource) { - Expects(pSource.m_nMaxAddresses == m_nMaxAddresses); + Expects(pSource.m_nAddressCount == m_nAddressCount); if (pSource.AreAllAddressesMatching()) { - m_nMatchingAddresses = m_nMaxAddresses; + m_nMatchingAddressCount = m_nAddressCount; } else { - const auto nAddressesSize = (m_nMaxAddresses + 7) / 8; + const auto nAddressesSize = (m_nAddressCount + 7) / 8; unsigned char* pAddresses = AllocateMatchingAddresses(); memcpy(pAddresses, pSource.GetMatchingAddressPointer(), nAddressesSize); - m_nMatchingAddresses = pSource.m_nMatchingAddresses; + m_nMatchingAddressCount = pSource.m_nMatchingAddressCount; } } -void MemBlock::ExcludeMatchingAddress(ra::data::ByteAddress nAddress) +void CapturedMemoryBlock::ExcludeMatchingAddress(ra::data::ByteAddress nAddress) { - const auto nAddressesSize = (m_nMaxAddresses + 7) / 8; + const auto nAddressesSize = (m_nAddressCount + 7) / 8; unsigned char* pAddresses = nullptr; const auto nIndex = nAddress - m_nFirstAddress; const auto nBit = 1 << (nIndex & 7); @@ -289,25 +300,25 @@ void MemBlock::ExcludeMatchingAddress(ra::data::ByteAddress nAddress) } pAddresses[nIndex >> 3] &= ~nBit; - --m_nMatchingAddresses; + --m_nMatchingAddressCount; } -bool MemBlock::ContainsAddress(ra::data::ByteAddress nAddress) const noexcept +bool CapturedMemoryBlock::ContainsAddress(ra::data::ByteAddress nAddress) const noexcept { if (nAddress < m_nFirstAddress) return false; nAddress -= m_nFirstAddress; - return (nAddress < m_nMaxAddresses); + return (nAddress < m_nAddressCount); } -bool MemBlock::ContainsMatchingAddress(ra::data::ByteAddress nAddress) const +bool CapturedMemoryBlock::ContainsMatchingAddress(ra::data::ByteAddress nAddress) const { if (nAddress < m_nFirstAddress) return false; const auto nIndex = nAddress - m_nFirstAddress; - if (nIndex >= m_nMaxAddresses) + if (nIndex >= m_nAddressCount) return false; if (AreAllAddressesMatching()) @@ -319,15 +330,15 @@ bool MemBlock::ContainsMatchingAddress(ra::data::ByteAddress nAddress) const return (pAddresses[nIndex >> 3] & nBit); } -ra::data::ByteAddress MemBlock::GetMatchingAddress(gsl::index nIndex) const noexcept +ra::data::ByteAddress CapturedMemoryBlock::GetMatchingAddress(gsl::index nIndex) const noexcept { if (AreAllAddressesMatching()) return m_nFirstAddress + gsl::narrow_cast(nIndex); - const auto nAddressesSize = (m_nMaxAddresses + 7) / 8; + const auto nAddressesSize = (m_nAddressCount + 7) / 8; const uint8_t* pAddresses = (nAddressesSize > sizeof(m_vAddresses)) ? m_pAddresses : &m_vAddresses[0]; ra::data::ByteAddress nAddress = m_nFirstAddress; - const ra::data::ByteAddress nStop = m_nFirstAddress + m_nMaxAddresses; + const ra::data::ByteAddress nStop = m_nFirstAddress + m_nAddressCount; uint8_t nMask = 0x01; if (pAddresses != nullptr) @@ -366,6 +377,5 @@ ra::data::ByteAddress MemBlock::GetMatchingAddress(gsl::index nIndex) const noex return 0; } -} // namespace search -} // namespace services +} // namespace data } // namespace ra diff --git a/src/devkit/data/CapturedMemoryBlock.hh b/src/devkit/data/CapturedMemoryBlock.hh new file mode 100644 index 000000000..31c86634e --- /dev/null +++ b/src/devkit/data/CapturedMemoryBlock.hh @@ -0,0 +1,207 @@ +#ifndef RA_DATA_CAPTUREDMEMORYBLOCK_HH +#define RA_DATA_CAPTUREDMEMORYBLOCK_HH +#pragma once + +#include "Memory.hh" + +#include "util/GSL.hh" + +namespace ra { +namespace data { + +class CapturedMemoryBlock +{ +private: + struct AllocatedMemory + { + uint32_t nReferenceCount; + uint32_t nHash; + uint8_t pBytes[16]; // this will actually be sized by the allocation code. + }; + +public: + explicit CapturedMemoryBlock(uint32_t nAddress, uint32_t nSize, uint32_t nMaxAddresses) : + m_nFirstAddress(nAddress), + m_nBytesSize(nSize), + m_nMatchingAddressCount(nMaxAddresses), + m_nAddressCount(nMaxAddresses) + { + if (IsBytesAllocated()) // not actually allocated yet, but about to be. + { + const auto nAllocSize = sizeof(AllocatedMemory) - sizeof(m_pAllocatedMemory->pBytes) + + ((gsl::narrow_cast(nSize) + 3) & ~3); + m_pAllocatedMemory = static_cast(malloc(nAllocSize)); + Expects(m_pAllocatedMemory != nullptr); + m_pAllocatedMemory->nReferenceCount = 1; + m_pAllocatedMemory->nHash = 0; + } + } + + ~CapturedMemoryBlock() noexcept; + + CapturedMemoryBlock(const CapturedMemoryBlock& other) noexcept; + CapturedMemoryBlock& operator=(const CapturedMemoryBlock&) noexcept = delete; + CapturedMemoryBlock(CapturedMemoryBlock&& other) noexcept; + CapturedMemoryBlock& operator=(CapturedMemoryBlock&&) noexcept = delete; + + /// + /// Gets the raw bytes that were captured. + /// + uint8_t* GetBytes() noexcept + { + return IsBytesAllocated() ? &m_pAllocatedMemory->pBytes[0] : &m_vBytes[0]; + } + + /// + /// Gets the raw bytes that were captured. + /// + const uint8_t* GetBytes() const noexcept + { + return IsBytesAllocated() ? &m_pAllocatedMemory->pBytes[0] : &m_vBytes[0]; + } + + /// + /// Gets the number of captured bytes. + /// + uint32_t GetBytesSize() const noexcept { return m_nBytesSize; } + + /// + /// Gets the first address of the captured memory. + /// + /// + /// May be virtualized as addresses represent indices into the captured memory. + /// + ByteAddress GetFirstAddress() const noexcept { return m_nFirstAddress; } + + /// + /// Sets the first address of the captured memory. + /// + void SetFirstAddress(ByteAddress nAddress) noexcept { m_nFirstAddress = nAddress; } + + /// + /// Gets the number of addresses associated to the captured memory. + /// + /// + /// This is specifed by the capturing code to indicate how many whole records are availble + /// in the captured memory depending on the captured size. For example, 75 bytes of memory + /// holds 18 whole 32-bit records, so the caller would set this to 18. + /// + uint32_t GetAddressCount() const noexcept { return m_nAddressCount; } + + /// + /// Sets the number of addresses associated to the captured memory. + /// + void SetAddressCount(uint32_t nAddressCount) noexcept + { + m_nAddressCount = nAddressCount; + m_nMatchingAddressCount = nAddressCount; + } + + /// + /// Determines whether the specified address is valid within this CapturedMemoryBlock. + /// + bool ContainsAddress(ByteAddress nAddress) const noexcept; + + /// + /// Gets the number of addresses associated to the captured memory that have been flagged as matching. + /// + uint32_t GetMatchingAddressCount() const noexcept { return m_nMatchingAddressCount; } + + /// + /// Gets the Nth matching address. + /// + ByteAddress GetMatchingAddress(gsl::index nIndex) const noexcept; + + /// + /// Determines whether the specified address is marked as matching. + /// + bool ContainsMatchingAddress(ByteAddress nAddress) const; + + /// + /// Specifies which addresses are matching from a slice of an address list. + /// + void SetMatchingAddresses(std::vector& vAddresses, gsl::index nFirstIndex, gsl::index nLastIndex); + + /// + /// Marks an address as no longer matching. + /// + void ExcludeMatchingAddress(ByteAddress nAddress); + + /// + /// Copies the matching addresses from another CapturedMemoryBlock. + /// + void CopyMatchingAddresses(const CapturedMemoryBlock& pSource); + + /// + /// Gets the raw pointer to the matching address data to pass to . + /// + /// + /// Exposed for performance. Do not call unnecessarily. + /// + const uint8_t* GetMatchingAddressPointer() const noexcept + { + if (AreAllAddressesMatching()) + return nullptr; + + const auto nAddressesSize = (m_nAddressCount + 7) / 8; + return (nAddressesSize > sizeof(m_vAddresses)) ? m_pAddresses : &m_vAddresses[0]; + } + + /// + /// Determines whether the specified address is marked as matching. + /// + /// + /// Exposed for performance. Call for general use. + /// + bool HasMatchingAddress(const uint8_t* pMatchingAddresses, ByteAddress nAddress) const noexcept + { + if (!pMatchingAddresses) + return true; + + const auto nIndex = nAddress - m_nFirstAddress; + if (nIndex >= m_nAddressCount) + return false; + + const auto nBit = 1 << (nIndex & 7); + return (pMatchingAddresses[nIndex >> 3] & nBit); + } + + /// + /// Attempts to minimize memory allocations by detecting and sharing large blocks of repeated data. + /// + /// A collection of previously captured memory blocks that could be shared. + void OptimizeMemory(const std::vector& vBlocks) noexcept; + +private: + bool IsBytesAllocated() const noexcept { return GetBytesSize() > sizeof(m_vBytes); } + + void ShareMemory(const std::vector& vBlocks, uint32_t nHash) noexcept; + //void SetRepeat(uint32_t nCount, uint32_t nValue) noexcept; + + uint8_t* AllocateMatchingAddresses() noexcept; + bool AreAllAddressesMatching() const noexcept { return m_nMatchingAddressCount == m_nAddressCount; } + + ByteAddress m_nFirstAddress; // 4 bytes + uint32_t m_nBytesSize; // 4 bytes + + union // 8 bytes + { + uint8_t m_vBytes[8]{}; + AllocatedMemory* m_pAllocatedMemory; + }; + + union // 8 bytes + { + uint8_t m_vAddresses[8]{}; + uint8_t* m_pAddresses; + }; + + uint32_t m_nMatchingAddressCount;// 4 bytes + uint32_t m_nAddressCount; // 4 bytes +}; +static_assert(sizeof(CapturedMemoryBlock) <= 32, "sizeof(CapturedMemoryBlock) is incorrect"); + +} // namespace data +} // namespace ra + +#endif /* !RA_DATA_CAPTUREDMEMORYBLOCK_HH */ diff --git a/src/services/Search/SearchImpl.cpp b/src/services/Search/SearchImpl.cpp index 382ab018e..e8177d262 100644 --- a/src/services/Search/SearchImpl.cpp +++ b/src/services/Search/SearchImpl.cpp @@ -156,7 +156,7 @@ bool SearchImpl::GetMatchingAddress(const SearchResults& srResults, gsl::index n if (nIndex < gsl::narrow_cast(pBlock.GetMatchingAddressCount())) { result.nAddress = pBlock.GetMatchingAddress(nIndex); - return GetValueFromMemBlock(pBlock, result); + return GetValueFromCapturedMemoryBlock(pBlock, result); } nIndex -= pBlock.GetMatchingAddressCount(); @@ -181,7 +181,7 @@ size_t SearchImpl::GetIndexOfBlockForVirtualAddress(const SearchResults& srResul } const uint32_t nOffset = nAddress - pBlockMid.GetFirstAddress(); - if (nOffset >= pBlockMid.GetMaxAddresses()) + if (nOffset >= pBlockMid.GetAddressCount()) { nIndexLow = nIndexMid + 1; continue; @@ -199,7 +199,7 @@ bool SearchImpl::GetValueAtVirtualAddress(const SearchResults& srResults, Search const auto nIndex = GetIndexOfBlockForVirtualAddress(srResults, result.nAddress); if (nIndex < srResults.m_vBlocks.size()) { - if (GetValueFromMemBlock(srResults.m_vBlocks.at(nIndex), result)) + if (GetValueFromCapturedMemoryBlock(srResults.m_vBlocks.at(nIndex), result)) return true; } @@ -272,7 +272,7 @@ bool SearchImpl::MatchesFilter(const SearchResults& pResults, const SearchResult } void SearchImpl::ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const { const auto nBlockAddress = pPreviousBlock.GetFirstAddress(); @@ -293,7 +293,7 @@ void SearchImpl::ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pByte } void SearchImpl::ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const { const auto* pBlockBytes = pPreviousBlock.GetBytes(); @@ -315,7 +315,7 @@ void SearchImpl::ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytes } } -bool SearchImpl::GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept +bool SearchImpl::GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept { if (result.nAddress < block.GetFirstAddress()) return false; @@ -357,7 +357,7 @@ void SearchImpl::AddBlocks(SearchResults& srNew, std::vector& vMatches) const; // generic implementation for less used search types - virtual void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, const MemBlock& pPreviousBlock, + virtual void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const; @@ -144,7 +144,7 @@ protected: #pragma warning(disable : 5045) template void ApplyCompareFilterLittleEndian(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, unsigned nAdjustment, std::vector& vMatches) const { const auto* pScan = pBytes; @@ -225,7 +225,7 @@ protected: /// against [out] The list of matching addresses template void ApplyCompareFilterLittleEndian(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const { switch (nComparison) @@ -256,7 +256,7 @@ protected: #else // #ifndef DISABLE_TEMPLATED_SEARCH template void ApplyCompareFilterLittleEndian(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const { if (TIsConstantFilter) @@ -281,7 +281,7 @@ protected: return srResults.m_vBlocks.front().GetFirstAddress(); } - static const std::vector& GetBlocks(const SearchResults& srResults) noexcept + static const std::vector& GetBlocks(const SearchResults& srResults) noexcept { return srResults.m_vBlocks; } @@ -304,14 +304,14 @@ protected: /// true if the memory was available in the block, false if not. /// Sets result.nValue to the value from the captured memory, and changes result.nAddress to a real /// address - virtual bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept; + virtual bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept; // Gets the index of the block in srResults containing the provided virtual address. static size_t GetIndexOfBlockForVirtualAddress(const SearchResults& srResults, uint32_t nAddress); virtual uint32_t BuildValue(const uint8_t* ptr) const noexcept; - static MemBlock& AddBlock(SearchResults& srResults, ra::data::ByteAddress nAddress, uint32_t nSize, + static CapturedMemoryBlock& AddBlock(SearchResults& srResults, ra::data::ByteAddress nAddress, uint32_t nSize, uint32_t nMaxAddresses) { return srResults.m_vBlocks.emplace_back(nAddress, nSize, nMaxAddresses); diff --git a/src/services/Search/SearchImpl_16bit.hh b/src/services/Search/SearchImpl_16bit.hh index 122e7c475..52c09e741 100644 --- a/src/services/Search/SearchImpl_16bit.hh +++ b/src/services/Search/SearchImpl_16bit.hh @@ -25,7 +25,7 @@ public: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, @@ -33,7 +33,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, diff --git a/src/services/Search/SearchImpl_16bit_aligned.hh b/src/services/Search/SearchImpl_16bit_aligned.hh index fb972ced3..91401ea4c 100644 --- a/src/services/Search/SearchImpl_16bit_aligned.hh +++ b/src/services/Search/SearchImpl_16bit_aligned.hh @@ -30,7 +30,7 @@ public: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, @@ -38,7 +38,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, @@ -46,7 +46,7 @@ protected: } - bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept override + bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept override { const unsigned int nOffset = (result.nAddress - block.GetFirstAddress()) * 2; if (nOffset + 1 >= block.GetBytesSize()) diff --git a/src/services/Search/SearchImpl_16bit_be.hh b/src/services/Search/SearchImpl_16bit_be.hh index adc65db7b..82138c02a 100644 --- a/src/services/Search/SearchImpl_16bit_be.hh +++ b/src/services/Search/SearchImpl_16bit_be.hh @@ -24,7 +24,7 @@ protected: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { SearchImpl::ApplyConstantFilter(pBytes, pBytesStop, @@ -32,7 +32,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { SearchImpl::ApplyCompareFilter(pBytes, pBytesStop, diff --git a/src/services/Search/SearchImpl_16bit_be_aligned.hh b/src/services/Search/SearchImpl_16bit_be_aligned.hh index 2846de42d..03034f89b 100644 --- a/src/services/Search/SearchImpl_16bit_be_aligned.hh +++ b/src/services/Search/SearchImpl_16bit_be_aligned.hh @@ -24,7 +24,7 @@ protected: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { SearchImpl::ApplyConstantFilter(pBytes, pBytesStop, @@ -32,7 +32,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { SearchImpl::ApplyCompareFilter(pBytes, pBytesStop, diff --git a/src/services/Search/SearchImpl_32bit.hh b/src/services/Search/SearchImpl_32bit.hh index 7b1f5b963..6c53756e7 100644 --- a/src/services/Search/SearchImpl_32bit.hh +++ b/src/services/Search/SearchImpl_32bit.hh @@ -25,7 +25,7 @@ public: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, @@ -33,7 +33,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, diff --git a/src/services/Search/SearchImpl_32bit_aligned.hh b/src/services/Search/SearchImpl_32bit_aligned.hh index 6c6c02692..5ac0fd9e5 100644 --- a/src/services/Search/SearchImpl_32bit_aligned.hh +++ b/src/services/Search/SearchImpl_32bit_aligned.hh @@ -30,7 +30,7 @@ public: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, @@ -38,7 +38,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, @@ -46,7 +46,7 @@ protected: } - bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept override + bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept override { const unsigned int nOffset = (result.nAddress - block.GetFirstAddress()) * 4; if (nOffset + 3 >= block.GetBytesSize()) diff --git a/src/services/Search/SearchImpl_32bit_be.hh b/src/services/Search/SearchImpl_32bit_be.hh index b7cd80604..7a172c54d 100644 --- a/src/services/Search/SearchImpl_32bit_be.hh +++ b/src/services/Search/SearchImpl_32bit_be.hh @@ -22,7 +22,7 @@ class ThirtyTwoBitBigEndianSearchImpl : public ThirtyTwoBitSearchImpl protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { SearchImpl::ApplyConstantFilter(pBytes, pBytesStop, @@ -30,7 +30,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { SearchImpl::ApplyCompareFilter(pBytes, pBytesStop, diff --git a/src/services/Search/SearchImpl_32bit_be_aligned.hh b/src/services/Search/SearchImpl_32bit_be_aligned.hh index ea77997b8..e6d53a483 100644 --- a/src/services/Search/SearchImpl_32bit_be_aligned.hh +++ b/src/services/Search/SearchImpl_32bit_be_aligned.hh @@ -22,7 +22,7 @@ class ThirtyTwoBitBigEndianAlignedSearchImpl : public ThirtyTwoBitAlignedSearchI protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { SearchImpl::ApplyConstantFilter(pBytes, pBytesStop, @@ -30,7 +30,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { SearchImpl::ApplyCompareFilter(pBytes, pBytesStop, diff --git a/src/services/Search/SearchImpl_4bit.hh b/src/services/Search/SearchImpl_4bit.hh index 5809b47e3..30950d044 100644 --- a/src/services/Search/SearchImpl_4bit.hh +++ b/src/services/Search/SearchImpl_4bit.hh @@ -50,7 +50,7 @@ class FourBitSearchImpl : public SearchImpl } void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { const auto nBlockAddress = pPreviousBlock.GetFirstAddress(); @@ -78,7 +78,7 @@ class FourBitSearchImpl : public SearchImpl } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { const auto* pBlockBytes = pPreviousBlock.GetBytes(); @@ -110,7 +110,7 @@ class FourBitSearchImpl : public SearchImpl } protected: - bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept override + bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept override { if (result.nAddress & 1) result.nSize = ra::data::Memory::Size::NibbleUpper; diff --git a/src/services/Search/SearchImpl_8bit.hh b/src/services/Search/SearchImpl_8bit.hh index b4356b415..abf07cd3c 100644 --- a/src/services/Search/SearchImpl_8bit.hh +++ b/src/services/Search/SearchImpl_8bit.hh @@ -12,7 +12,7 @@ class EightBitSearchImpl : public SearchImpl { protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, @@ -20,7 +20,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { ApplyCompareFilterLittleEndian(pBytes, pBytesStop, diff --git a/src/services/Search/SearchImpl_bitcount.hh b/src/services/Search/SearchImpl_bitcount.hh index e060ed87d..fb518b949 100644 --- a/src/services/Search/SearchImpl_bitcount.hh +++ b/src/services/Search/SearchImpl_bitcount.hh @@ -48,7 +48,7 @@ protected: } private: - bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept override + bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept override { if (result.nAddress < block.GetFirstAddress()) return false; diff --git a/src/services/Search/SearchImpl_double32_aligned.hh b/src/services/Search/SearchImpl_double32_aligned.hh index aa35bbd8c..be93eabbf 100644 --- a/src/services/Search/SearchImpl_double32_aligned.hh +++ b/src/services/Search/SearchImpl_double32_aligned.hh @@ -47,7 +47,7 @@ public: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { pBytes += 4; // we're only looking at the four most significant bytes @@ -68,7 +68,7 @@ protected: GSL_SUPPRESS_TYPE1 void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { // cannot use base implementation because we need to offset pBytes and pBlockBytes @@ -94,7 +94,7 @@ protected: } } - bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept override + bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept override { const unsigned int nOffset = (result.nAddress - block.GetFirstAddress()) * 8; if (nOffset + 7 >= block.GetBytesSize()) diff --git a/src/services/Search/SearchImpl_double32_be_aligned.hh b/src/services/Search/SearchImpl_double32_be_aligned.hh index 9a6cfabe6..ae6ca1c55 100644 --- a/src/services/Search/SearchImpl_double32_be_aligned.hh +++ b/src/services/Search/SearchImpl_double32_be_aligned.hh @@ -32,7 +32,7 @@ public: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { if (nComparison == ComparisonType::Equals || nComparison == ComparisonType::NotEqualTo) @@ -49,7 +49,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { if (nComparison == ComparisonType::Equals || nComparison == ComparisonType::NotEqualTo) @@ -65,7 +65,7 @@ protected: } } - bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept override + bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept override { const unsigned int nOffset = (result.nAddress - block.GetFirstAddress()) * 8; if (nOffset + 3 >= block.GetBytesSize()) diff --git a/src/services/Search/SearchImpl_float.hh b/src/services/Search/SearchImpl_float.hh index 68cd9e212..41f8f9643 100644 --- a/src/services/Search/SearchImpl_float.hh +++ b/src/services/Search/SearchImpl_float.hh @@ -99,7 +99,7 @@ protected: GSL_SUPPRESS_TYPE1 void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { if (nComparison == ComparisonType::Equals || nComparison == ComparisonType::NotEqualTo) @@ -132,7 +132,7 @@ protected: GSL_SUPPRESS_TYPE1 void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { if (nComparison == ComparisonType::Equals || nComparison == ComparisonType::NotEqualTo) diff --git a/src/services/Search/SearchImpl_float_aligned.hh b/src/services/Search/SearchImpl_float_aligned.hh index a6c1a5f53..720340ebe 100644 --- a/src/services/Search/SearchImpl_float_aligned.hh +++ b/src/services/Search/SearchImpl_float_aligned.hh @@ -30,7 +30,7 @@ public: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { if (nComparison == ComparisonType::Equals || nComparison == ComparisonType::NotEqualTo) @@ -47,7 +47,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { if (nComparison == ComparisonType::Equals || nComparison == ComparisonType::NotEqualTo) @@ -63,7 +63,7 @@ protected: } } - bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept override + bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept override { const unsigned int nOffset = (result.nAddress - block.GetFirstAddress()) * 4; if (nOffset + 3 >= block.GetBytesSize()) diff --git a/src/services/Search/SearchImpl_float_be_aligned.hh b/src/services/Search/SearchImpl_float_be_aligned.hh index eaddb2e3d..0987add61 100644 --- a/src/services/Search/SearchImpl_float_be_aligned.hh +++ b/src/services/Search/SearchImpl_float_be_aligned.hh @@ -30,7 +30,7 @@ public: protected: void ApplyConstantFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nConstantValue, std::vector& vMatches) const override { if (nComparison == ComparisonType::Equals || nComparison == ComparisonType::NotEqualTo) @@ -47,7 +47,7 @@ protected: } void ApplyCompareFilter(const uint8_t* pBytes, const uint8_t* pBytesStop, - const MemBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, + const CapturedMemoryBlock& pPreviousBlock, ComparisonType nComparison, unsigned nAdjustment, std::vector& vMatches) const override { if (nComparison == ComparisonType::Equals || nComparison == ComparisonType::NotEqualTo) @@ -63,7 +63,7 @@ protected: } } - bool GetValueFromMemBlock(const MemBlock& block, SearchResult& result) const noexcept override + bool GetValueFromCapturedMemoryBlock(const CapturedMemoryBlock& block, SearchResult& result) const noexcept override { const unsigned int nOffset = (result.nAddress - block.GetFirstAddress()) * 4; if (nOffset + 3 >= block.GetBytesSize()) diff --git a/src/services/SearchResults.cpp b/src/services/SearchResults.cpp index 8e0ecf3e0..509490482 100644 --- a/src/services/SearchResults.cpp +++ b/src/services/SearchResults.cpp @@ -115,14 +115,14 @@ static search::SearchImpl* GetSearchImpl(SearchType nType) noexcept } #ifndef RA_UTEST -static size_t CalcSize(const std::vector& vBlocks) +static size_t CalcSize(const std::vector& vBlocks) { std::set vAllocatedMemoryBlocks; - size_t nTotalSize = vBlocks.size() * sizeof(data::search::MemBlock); + size_t nTotalSize = vBlocks.size() * sizeof(ra::data::CapturedMemoryBlock); for (const auto& pBlock : vBlocks) { - if (pBlock.IsBytesAllocated()) + if (pBlock.GetBytesSize() > 8) // IsBytesAllocated { const auto* pBytes = pBlock.GetBytes(); if (vAllocatedMemoryBlocks.find(pBytes) == vAllocatedMemoryBlocks.end()) @@ -165,8 +165,7 @@ void SearchResults::Initialize(ra::data::ByteAddress nAddress, size_t nBytes, Se pBlock.SetFirstAddress(m_pImpl->ConvertFromRealAddress(pBlock.GetFirstAddress())); const auto nAdjustedAddressCount = m_pImpl->GetAddressCountForBytes(pBlock.GetBytesSize()); - pBlock.SetMaxAddresses(nAdjustedAddressCount); - pBlock.SetMatchingAddressCount(nAdjustedAddressCount); + pBlock.SetAddressCount(nAdjustedAddressCount); } RA_LOG_INFO("Allocated %zu bytes for initial search", CalcSize(m_vBlocks)); diff --git a/src/services/SearchResults.h b/src/services/SearchResults.h index 314aa8b1c..1c4e2bf0d 100644 --- a/src/services/SearchResults.h +++ b/src/services/SearchResults.h @@ -6,7 +6,7 @@ #include "data\context\EmulatorContext.hh" -#include "data\search\MemBlock.hh" +#include "data\CapturedMemoryBlock.hh" namespace ra { namespace services { @@ -213,7 +213,7 @@ class SearchResults private: void MergeSearchResults(const SearchResults& srMemory, const SearchResults& srAddresses); - std::vector m_vBlocks; + std::vector m_vBlocks; SearchType m_nType = SearchType::EightBit; friend class search::SearchImpl; diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj index c760d7ed3..7b6f5d32f 100644 --- a/tests/RA_Integration.Tests.vcxproj +++ b/tests/RA_Integration.Tests.vcxproj @@ -93,7 +93,6 @@ - Create diff --git a/tests/RA_Integration.Tests.vcxproj.filters b/tests/RA_Integration.Tests.vcxproj.filters index 18e67caf4..81bfe992d 100644 --- a/tests/RA_Integration.Tests.vcxproj.filters +++ b/tests/RA_Integration.Tests.vcxproj.filters @@ -438,9 +438,6 @@ Code - - Code - Code diff --git a/tests/data/context/EmulatorContext_Tests.cpp b/tests/data/context/EmulatorContext_Tests.cpp index 7841278a0..b647b4c01 100644 --- a/tests/data/context/EmulatorContext_Tests.cpp +++ b/tests/data/context/EmulatorContext_Tests.cpp @@ -1886,7 +1886,7 @@ TEST_CLASS(EmulatorContext_Tests) emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - std::vector vBlocks; + std::vector vBlocks; emulator.CaptureMemory(vBlocks, 0, 30, 0); Assert::AreEqual({ 2 }, vBlocks.size()); @@ -1909,7 +1909,7 @@ TEST_CLASS(EmulatorContext_Tests) emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - std::vector vBlocks; + std::vector vBlocks; emulator.CaptureMemory(vBlocks, 8, 20, 0); Assert::AreEqual({ 2 }, vBlocks.size()); @@ -1932,7 +1932,7 @@ TEST_CLASS(EmulatorContext_Tests) emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - std::vector vBlocks; + std::vector vBlocks; emulator.CaptureMemory(vBlocks, 20, 10, 0); Assert::AreEqual({ 1 }, vBlocks.size()); @@ -1951,7 +1951,7 @@ TEST_CLASS(EmulatorContext_Tests) emulator.AddMemoryBlock(1, 10, nullptr, nullptr); emulator.AddMemoryBlock(2, 10, &ReadMemory2, &WriteMemory2); - std::vector vBlocks; + std::vector vBlocks; emulator.CaptureMemory(vBlocks, 0, 30, 0); Assert::AreEqual({ 2 }, vBlocks.size()); @@ -1975,7 +1975,7 @@ TEST_CLASS(EmulatorContext_Tests) emulator.AddMemoryBlock(1, 10, nullptr, nullptr); emulator.AddMemoryBlock(2, 10, &ReadMemory2, &WriteMemory2); - std::vector vBlocks; + std::vector vBlocks; emulator.CaptureMemory(vBlocks, 20, 10, 0); Assert::AreEqual({ 1 }, vBlocks.size()); From e6f23b7a62eca3c81dff1b9507837cbf982d27ad Mon Sep 17 00:00:00 2001 From: Jamiras Date: Wed, 7 Jan 2026 16:38:56 -0700 Subject: [PATCH 4/5] extract memory management from EmulatorContext into separate IEmulatorMemoryContext --- src/Exports.cpp | 23 +- src/RA_Defs.cpp | 11 +- src/RA_Integration.vcxproj | 4 +- src/RA_Integration.vcxproj.filters | 12 +- src/data/context/EmulatorContext.cpp | 603 -------------- src/data/context/EmulatorContext.hh | 130 --- src/data/context/SessionTracker.cpp | 6 +- src/data/models/CodeNoteModel.cpp | 12 +- src/data/models/CodeNoteModel.hh | 4 +- src/data/models/CodeNotesModel.cpp | 8 +- src/data/models/MemoryRegionsModel.cpp | 6 +- src/data/models/TriggerValidation.cpp | 4 +- src/devkit/RADevKit.vcxproj | 7 + src/devkit/RADevKit.vcxproj.filters | 21 + src/devkit/context/IEmulatorMemoryContext.hh | 120 +++ .../context/impl/EmulatorMemoryContext.cpp | 623 ++++++++++++++ .../context/impl/EmulatorMemoryContext.hh | 139 ++++ src/{ => devkit}/services/IClock.hh | 4 +- src/devkit/services/IDebuggerDetector.hh | 29 + src/{ => devkit}/services/impl/Clock.hh | 0 src/services/AchievementRuntime.cpp | 31 +- src/services/AchievementRuntimeExports.cpp | 31 +- src/services/GameIdentifier.cpp | 3 +- src/services/Initialization.cpp | 8 + src/services/Search/SearchImpl.cpp | 4 +- src/services/Search/SearchImpl.hh | 2 +- src/services/Search/SearchImpl_asciitext.hh | 4 +- src/services/Search/SearchImpl_bitcount.hh | 4 +- src/services/SearchResults.cpp | 18 +- src/services/SearchResults.h | 9 +- src/services/impl/WindowsDebuggerDetector.cpp | 73 ++ src/services/impl/WindowsDebuggerDetector.hh | 20 + src/ui/viewmodels/AssetEditorViewModel.hh | 1 + src/ui/viewmodels/AssetListViewModel.cpp | 6 +- .../viewmodels/MemoryBookmarksViewModel.cpp | 7 +- .../viewmodels/MemoryInspectorViewModel.cpp | 8 +- src/ui/viewmodels/MemorySearchViewModel.cpp | 19 +- src/ui/viewmodels/MemorySearchViewModel.hh | 6 +- src/ui/viewmodels/MemoryViewerViewModel.cpp | 44 +- src/ui/viewmodels/MemoryViewerViewModel.hh | 4 +- .../viewmodels/MemoryWatchListViewModel.cpp | 16 +- src/ui/viewmodels/MemoryWatchListViewModel.hh | 4 +- src/ui/viewmodels/MemoryWatchViewModel.cpp | 10 +- src/ui/viewmodels/PointerFinderViewModel.cpp | 7 +- .../viewmodels/PointerInspectorViewModel.cpp | 15 +- src/ui/viewmodels/TriggerViewModel.hh | 2 + src/ui/win32/CodeNotesDialog.cpp | 8 +- src/ui/win32/CodeNotesDialog.hh | 4 +- src/ui/win32/MemoryBookmarksDialog.cpp | 10 +- src/ui/win32/MemoryBookmarksDialog.hh | 4 +- src/ui/win32/MemoryInspectorDialog.cpp | 6 +- .../bindings/GridAddressColumnBinding.cpp | 4 +- .../bindings/MemoryViewerControlBinding.cpp | 4 +- tests/Exports_Tests.cpp | 2 +- tests/RA_Integration.Tests.vcxproj | 1 + tests/RA_Integration.Tests.vcxproj.filters | 3 + tests/data/context/EmulatorContext_Tests.cpp | 712 +--------------- tests/data/context/GameContext_Tests.cpp | 4 +- tests/data/context/SessionTracker_Tests.cpp | 2 +- tests/data/models/AchievementModel_Tests.cpp | 2 +- tests/data/models/CodeNoteModel_Tests.cpp | 16 +- tests/data/models/CodeNotesModel_Tests.cpp | 50 +- .../data/models/MemoryRegionsModel_Tests.cpp | 50 +- tests/data/models/TriggerValidation_Tests.cpp | 8 +- tests/devkit/RADevKit.Tests.vcxproj.vcxproj | 4 + .../RADevKit.Tests.vcxproj.vcxproj.filters | 12 + .../impl/EmulatorMemoryContext_Tests.cpp | 771 ++++++++++++++++++ .../mocks/MockEmulatorMemoryContext.cpp | 94 +++ .../mocks/MockEmulatorMemoryContext.hh | 75 ++ .../{ => devkit/services}/mocks/MockClock.hh | 0 .../services/mocks/MockDebuggerDetector.hh | 33 + tests/mocks/MockAchievementRuntime.cpp | 11 - tests/mocks/MockEmulatorContext.hh | 100 --- tests/mocks/MockGameContext.hh | 4 +- .../AchievementLogicSerializer_Tests.cpp | 30 +- .../AchievementRuntimeExports_Tests.cpp | 14 +- tests/services/AchievementRuntime_Tests.cpp | 52 +- tests/services/FileLocalStorage_Tests.cpp | 2 +- tests/services/FileLogger_Tests.cpp | 2 +- tests/services/GameIdentifier_Tests.cpp | 6 +- tests/services/SearchResults_Tests.cpp | 364 ++++----- .../viewmodels/AssetEditorViewModel_Tests.cpp | 4 +- .../viewmodels/AssetListViewModel_Tests.cpp | 10 +- .../viewmodels/CodeNotesViewModel_Tests.cpp | 6 +- .../IntegrationMenuViewModel_Tests.cpp | 4 +- .../MemoryBookmarksViewModel_Tests.cpp | 4 +- .../MemoryInspectorViewModel_Tests.cpp | 4 +- .../MemoryRegionsViewModel_Tests.cpp | 2 + .../MemorySearchViewModel_Tests.cpp | 28 +- .../MemoryViewerViewModel_Tests.cpp | 3 +- .../MemoryWatchListViewModel_Tests.cpp | 4 +- ...OverlayAchievementsPageViewModel_Tests.cpp | 2 +- .../OverlayFriendsPageViewModel_Tests.cpp | 2 +- tests/ui/viewmodels/OverlayManager_Tests.cpp | 2 +- .../PointerFinderViewModel_Tests.cpp | 30 +- .../PointerInspectorViewModel_Tests.cpp | 4 +- .../TriggerConditionViewModel_Tests.cpp | 12 +- .../ui/viewmodels/TriggerViewModel_Tests.cpp | 6 +- 98 files changed, 2624 insertions(+), 2089 deletions(-) create mode 100644 src/devkit/context/IEmulatorMemoryContext.hh create mode 100644 src/devkit/context/impl/EmulatorMemoryContext.cpp create mode 100644 src/devkit/context/impl/EmulatorMemoryContext.hh rename src/{ => devkit}/services/IClock.hh (94%) create mode 100644 src/devkit/services/IDebuggerDetector.hh rename src/{ => devkit}/services/impl/Clock.hh (100%) create mode 100644 src/services/impl/WindowsDebuggerDetector.cpp create mode 100644 src/services/impl/WindowsDebuggerDetector.hh create mode 100644 tests/devkit/context/impl/EmulatorMemoryContext_Tests.cpp create mode 100644 tests/devkit/context/mocks/MockEmulatorMemoryContext.cpp create mode 100644 tests/devkit/context/mocks/MockEmulatorMemoryContext.hh rename tests/{ => devkit/services}/mocks/MockClock.hh (100%) create mode 100644 tests/devkit/services/mocks/MockDebuggerDetector.hh diff --git a/src/Exports.cpp b/src/Exports.cpp index 03ad55e4c..44446d365 100644 --- a/src/Exports.cpp +++ b/src/Exports.cpp @@ -11,6 +11,7 @@ #include "context\IConsoleContext.hh" #include "context\IRcClient.hh" #include "context\impl\ConsoleContext.hh" +#include "context\impl\EmulatorMemoryContext.hh" #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" @@ -428,20 +429,30 @@ API void CCONV _RA_SetUserAgentDetail(const char* sDetail) API void CCONV _RA_InstallMemoryBank(int nBankID, void* pReader, void* pWriter, int nBankSize) { - ra::services::ServiceLocator::GetMutable().AddMemoryBlock(nBankID, nBankSize, - static_cast(pReader), - static_cast(pWriter)); + auto* pEmulatorMemoryContext = dynamic_cast(&ra::services::ServiceLocator::GetMutable()); + if (pEmulatorMemoryContext) + { + pEmulatorMemoryContext->AddMemoryBlock(nBankID, nBankSize, + static_cast(pReader), + static_cast(pWriter)); + } } API void CCONV _RA_InstallMemoryBankBlockReader(int nBankID, void* pReader) { - ra::services::ServiceLocator::GetMutable().AddMemoryBlockReader( - nBankID, static_cast(pReader)); + auto* pEmulatorMemoryContext = dynamic_cast(&ra::services::ServiceLocator::GetMutable()); + if (pEmulatorMemoryContext) + { + pEmulatorMemoryContext->AddMemoryBlockReader( + nBankID, static_cast(pReader)); + } } API void CCONV _RA_ClearMemoryBanks() { - ra::services::ServiceLocator::GetMutable().ClearMemoryBlocks(); + auto* pEmulatorMemoryContext = dynamic_cast(&ra::services::ServiceLocator::GetMutable()); + if (pEmulatorMemoryContext) + pEmulatorMemoryContext->ClearMemoryBlocks();; } API unsigned int CCONV _RA_IdentifyRom(const BYTE* pROM, unsigned int nROMSize) diff --git a/src/RA_Defs.cpp b/src/RA_Defs.cpp index 1ef1a6c2e..e5e4a94ff 100644 --- a/src/RA_Defs.cpp +++ b/src/RA_Defs.cpp @@ -1,9 +1,10 @@ #include "RA_Defs.h" -#include "util\Strings.hh" -#include "services\ServiceLocator.hh" +#include "context/IEmulatorMemoryContext.hh" -#include "data\context\EmulatorContext.hh" +#include "services/ServiceLocator.hh" + +#include "util/Strings.hh" #include @@ -13,8 +14,8 @@ _Use_decl_annotations_ std::string ByteAddressToString(ra::data::ByteAddress nAddr) { #ifndef RA_UTEST - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - return pEmulatorContext.FormatAddress(nAddr); + const auto& pEmulatorMemoryContext = ra::services::ServiceLocator::Get(); + return pEmulatorMemoryContext.FormatAddress(nAddr); #else return ra::StringPrintf("0x%04x", nAddr); #endif diff --git a/src/RA_Integration.vcxproj b/src/RA_Integration.vcxproj index 71f7bc2ab..a130f44ed 100644 --- a/src/RA_Integration.vcxproj +++ b/src/RA_Integration.vcxproj @@ -110,6 +110,7 @@ + @@ -253,7 +254,6 @@ - @@ -262,9 +262,9 @@ - + diff --git a/src/RA_Integration.vcxproj.filters b/src/RA_Integration.vcxproj.filters index 0e6cbdd51..0a856bc75 100644 --- a/src/RA_Integration.vcxproj.filters +++ b/src/RA_Integration.vcxproj.filters @@ -414,6 +414,9 @@ Services\Impl + + Services\Impl + @@ -470,12 +473,6 @@ Services\Impl - - Services - - - Services\Impl - Services\Impl @@ -1025,6 +1022,9 @@ Services\Impl + + Services\Impl + diff --git a/src/data/context/EmulatorContext.cpp b/src/data/context/EmulatorContext.cpp index f2d2dd229..e29c561f2 100644 --- a/src/data/context/EmulatorContext.cpp +++ b/src/data/context/EmulatorContext.cpp @@ -34,40 +34,9 @@ namespace ra { namespace data { namespace context { -static std::string FormatAddressLarge(ra::data::ByteAddress nAddress) -{ - std::string sAddress; - sAddress.resize(10); - sprintf_s(sAddress.data(), 11, "0x%08x", nAddress); - return sAddress; -} - -static std::string FormatAddressMedium(ra::data::ByteAddress nAddress) -{ - if (nAddress & 0xFF000000) - return FormatAddressLarge(nAddress); - - std::string sAddress; - sAddress.resize(8); - sprintf_s(sAddress.data(), 9, "0x%06x", nAddress); - return sAddress; -} - -static std::string FormatAddressSmall(ra::data::ByteAddress nAddress) -{ - if (nAddress & 0xFFFF0000) - return FormatAddressMedium(nAddress); - - std::string sAddress; - sAddress.resize(6); - sprintf_s(sAddress.data(), 7, "0x%04x", nAddress); - return sAddress; -} - void EmulatorContext::Initialize(EmulatorID nEmulatorId, const char* sClientName) { m_nEmulatorId = nEmulatorId; - m_fFormatAddress = FormatAddressSmall; switch (nEmulatorId) { @@ -625,578 +594,6 @@ std::string EmulatorContext::GetGameTitle() const return std::string(buffer.data()); } -void EmulatorContext::ClearMemoryBlocks() -{ - m_vMemoryBlocks.clear(); - - if (m_nTotalMemorySize != 0U) - { - m_nTotalMemorySize = 0U; - OnTotalMemorySizeChanged(); - } -} - -void EmulatorContext::AddMemoryBlock(gsl::index nIndex, size_t nBytes, - EmulatorContext::MemoryReadFunction pReader, EmulatorContext::MemoryWriteFunction pWriter) -{ - while (m_vMemoryBlocks.size() <= ra::to_unsigned(nIndex)) - m_vMemoryBlocks.emplace_back(); - - MemoryBlock& pBlock = m_vMemoryBlocks.at(nIndex); - if (pBlock.size == 0) - { - pBlock.size = nBytes; - pBlock.read = pReader; - pBlock.write = pWriter; - pBlock.readBlock = nullptr; - - m_nTotalMemorySize += nBytes; - - OnTotalMemorySizeChanged(); - } -} - -void EmulatorContext::AddMemoryBlockReader(gsl::index nIndex, - EmulatorContext::MemoryReadBlockFunction pReader) -{ - if (nIndex < gsl::narrow_cast(m_vMemoryBlocks.size())) - m_vMemoryBlocks.at(nIndex).readBlock = pReader; -} - -void EmulatorContext::OnTotalMemorySizeChanged() -{ - if (m_nTotalMemorySize <= 0x10000) - m_fFormatAddress = FormatAddressSmall; - else if (m_nTotalMemorySize <= 0x1000000) - m_fFormatAddress = FormatAddressMedium; - else - m_fFormatAddress = FormatAddressLarge; - - if (m_vNotifyTargets.LockIfNotEmpty()) - { - for (auto& target : m_vNotifyTargets.Targets()) - target.OnTotalMemorySizeChanged(); - - m_vNotifyTargets.Unlock(); - } -} - -bool EmulatorContext::HasInvalidRegions() const noexcept -{ - for (const auto& pBlock : m_vMemoryBlocks) - { - if (!pBlock.read) - return true; - } - - return false; -} - -bool EmulatorContext::IsValidAddress(ra::data::ByteAddress nAddress) const noexcept -{ - for (const auto& pBlock : m_vMemoryBlocks) - { - if (nAddress < pBlock.size) - { - if (pBlock.read) - return true; - - break; - } - - nAddress -= gsl::narrow_cast(pBlock.size); - } - - return false; -} - -void EmulatorContext::AssertIsOnDoFrameThread() const -{ -#if RA_INTEGRATION_VERSION_REVISION != 0 - #if !defined(RA_UTEST) - const auto* pClient = ra::services::ServiceLocator::Get().GetClient(); - const auto& pRuntime = ra::services::ServiceLocator::Get(); - if (!pClient->state.allow_background_memory_reads && - !pRuntime.IsOnDoFrameThread()) - { - const auto& pGameContext = ra::services::ServiceLocator::Get(); - if (pGameContext.GameId() != 0 && !pGameContext.IsGameLoading()) - { - ra::ui::viewmodels::MessageBoxViewModel::ShowWarningMessage( - L"Memory Read on Background Thread", - L"Memory is being read on a thread other than the thread that last called rc_client_do_frame and the " - L"client has specified that should not be allowed. Please notify a RetroAchievements engineer what you " - L"were doing when this occurred."); - } - } - #endif -#endif -} - -uint8_t EmulatorContext::ReadMemoryByte(ra::data::ByteAddress nAddress) const -{ - AssertIsOnDoFrameThread(); - - for (const auto& pBlock : m_vMemoryBlocks) - { - if (nAddress < pBlock.size) - { - if (pBlock.read) - return pBlock.read(nAddress); - - break; - } - - nAddress -= gsl::narrow_cast(pBlock.size); - } - - return 0; -} - -uint32_t EmulatorContext::ReadMemory(ra::data::ByteAddress nAddress, uint8_t pBuffer[], size_t nCount, - const EmulatorContext::MemoryBlock& pBlock) -{ - Expects(pBuffer != nullptr); - - if (pBlock.readBlock) - { - const size_t nRead = pBlock.readBlock(nAddress, pBuffer, gsl::narrow_cast(nCount)); - if (nRead < nCount) - memset(pBuffer + nRead, 0, nCount - nRead); - - return gsl::narrow_cast(nRead); - } - - if (!pBlock.read) - { - memset(pBuffer, 0, nCount); - return 0; - } - - auto nRemaining = nCount; - while (nRemaining >= 8) // unrolled loop to read 8-byte chunks - { - *pBuffer++ = pBlock.read(nAddress++); - *pBuffer++ = pBlock.read(nAddress++); - *pBuffer++ = pBlock.read(nAddress++); - *pBuffer++ = pBlock.read(nAddress++); - *pBuffer++ = pBlock.read(nAddress++); - *pBuffer++ = pBlock.read(nAddress++); - *pBuffer++ = pBlock.read(nAddress++); - *pBuffer++ = pBlock.read(nAddress++); - nRemaining -= 8; - } - - switch (nRemaining) // partial Duff's device to read remaining bytes - { - case 7: - *pBuffer++ = pBlock.read(nAddress++); - _FALLTHROUGH; - case 6: - *pBuffer++ = pBlock.read(nAddress++); - _FALLTHROUGH; - case 5: - *pBuffer++ = pBlock.read(nAddress++); - _FALLTHROUGH; - case 4: - *pBuffer++ = pBlock.read(nAddress++); - _FALLTHROUGH; - case 3: - *pBuffer++ = pBlock.read(nAddress++); - _FALLTHROUGH; - case 2: - *pBuffer++ = pBlock.read(nAddress++); - _FALLTHROUGH; - case 1: - *pBuffer++ = pBlock.read(nAddress++); - _FALLTHROUGH; - default: - break; - } - - return gsl::narrow_cast(nCount); -} - -_Use_decl_annotations_ -uint32_t EmulatorContext::ReadMemory(ra::data::ByteAddress nAddress, uint8_t pBuffer[], size_t nCount) const -{ - AssertIsOnDoFrameThread(); - - uint32_t nBytesRead = 0; - Expects(pBuffer != nullptr); - - for (const auto& pBlock : m_vMemoryBlocks) - { - if (nAddress >= pBlock.size) - { - nAddress -= gsl::narrow_cast(pBlock.size); - continue; - } - - const size_t nBlockRemaining = pBlock.size - nAddress; - size_t nToRead = std::min(nCount, nBlockRemaining); - - nBytesRead += ReadMemory(nAddress, pBuffer, nToRead, pBlock); - - pBuffer += nToRead; - nCount -= nToRead; - - if (nCount == 0) - return nBytesRead; - - nAddress = 0; - } - - if (nCount > 0) - memset(pBuffer, 0, nCount); - - return nBytesRead; -} - -uint32_t EmulatorContext::ReadMemory(ra::data::ByteAddress nAddress, Memory::Size nSize) const -{ - switch (nSize) - { - case Memory::Size::Bit0: - return (ReadMemoryByte(nAddress) & 0x01); - case Memory::Size::Bit1: - return (ReadMemoryByte(nAddress) & 0x02) ? 1 : 0; - case Memory::Size::Bit2: - return (ReadMemoryByte(nAddress) & 0x04) ? 1 : 0; - case Memory::Size::Bit3: - return (ReadMemoryByte(nAddress) & 0x08) ? 1 : 0; - case Memory::Size::Bit4: - return (ReadMemoryByte(nAddress) & 0x10) ? 1 : 0; - case Memory::Size::Bit5: - return (ReadMemoryByte(nAddress) & 0x20) ? 1 : 0; - case Memory::Size::Bit6: - return (ReadMemoryByte(nAddress) & 0x40) ? 1 : 0; - case Memory::Size::Bit7: - return (ReadMemoryByte(nAddress) & 0x80) ? 1 : 0; - case Memory::Size::NibbleLower: - return (ReadMemoryByte(nAddress) & 0x0F); - case Memory::Size::NibbleUpper: - return ((ReadMemoryByte(nAddress) >> 4) & 0x0F); - case Memory::Size::EightBit: - return ReadMemoryByte(nAddress); - default: - case Memory::Size::SixteenBit: - { - uint8_t buffer[2]; - ReadMemory(nAddress, buffer, 2); - return buffer[0] | (buffer[1] << 8); - } - case Memory::Size::TwentyFourBit: - { - uint8_t buffer[3]; - ReadMemory(nAddress, buffer, 3); - return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16); - } - case Memory::Size::Float: - case Memory::Size::FloatBigEndian: - case Memory::Size::Double32: - case Memory::Size::Double32BigEndian: - case Memory::Size::MBF32: - case Memory::Size::MBF32LE: - case Memory::Size::ThirtyTwoBit: - { - uint8_t buffer[4]; - ReadMemory(nAddress, buffer, 4); - return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); - } - case Memory::Size::SixteenBitBigEndian: - { - uint8_t buffer[2]; - ReadMemory(nAddress, buffer, 2); - return buffer[1] | (buffer[0] << 8); - } - case Memory::Size::TwentyFourBitBigEndian: - { - uint8_t buffer[3]; - ReadMemory(nAddress, buffer, 3); - return buffer[2] | (buffer[1] << 8) | (buffer[0] << 16); - } - case Memory::Size::ThirtyTwoBitBigEndian: - { - uint8_t buffer[4]; - ReadMemory(nAddress, buffer, 4); - return buffer[3] | (buffer[2] << 8) | (buffer[1] << 16) | (buffer[0] << 24); - } - case Memory::Size::BitCount: - { - const uint8_t nValue = ReadMemoryByte(nAddress); - static const std::array nBitsSet = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; - return nBitsSet.at(nValue & 0x0F) + nBitsSet.at((nValue >> 4) & 0x0F); - } - } -} - -void EmulatorContext::WriteMemory(ra::data::ByteAddress nAddress, const uint8_t* pBytes, size_t nBytes) const -{ - Expects(pBytes != nullptr); - size_t nBytesWritten = 0; - auto nBlockAddress = nAddress; - - for (const auto& pBlock : m_vMemoryBlocks) - { - if (nBlockAddress < pBlock.size) - { - if (!pBlock.write) - break; - - m_bMemoryModified = true; - - if (nBytes == 1) - { - pBlock.write(nBlockAddress, pBytes[0]); - nBytesWritten = 1; - break; - } - else - { - do - { - pBlock.write(nBlockAddress++, pBytes[nBytesWritten++]); - } while (nBytesWritten < nBytes && nBlockAddress < pBlock.size); - - if (nBytesWritten == nBytes) - break; - } - } - - nBlockAddress -= gsl::narrow_cast(pBlock.size); - } - - if (nBytesWritten > 0) - { - if (m_vNotifyTargets.LockIfNotEmpty()) - { - for (auto& target : m_vNotifyTargets.Targets()) - { - for (unsigned nIndex = 0; nIndex < nBytesWritten; ++nIndex) - target.OnByteWritten(nAddress + nIndex, pBytes[nIndex]); - } - - m_vNotifyTargets.Unlock(); - } - } -} - -void EmulatorContext::WriteMemoryByte(ra::data::ByteAddress nAddress, uint8_t nValue) const -{ - WriteMemory(nAddress, &nValue, 1); -} - -void EmulatorContext::WriteMemory(ra::data::ByteAddress nAddress, Memory::Size nSize, uint32_t nValue) const -{ - union - { - uint32_t u32; - uint8_t u8[4]; - } u; - u.u32 = nValue; - - switch (nSize) - { - case Memory::Size::EightBit: - WriteMemory(nAddress, u.u8, 1); - break; - - case Memory::Size::SixteenBit: - WriteMemory(nAddress, u.u8, 2); - break; - - case Memory::Size::TwentyFourBit: - WriteMemory(nAddress, u.u8, 3); - break; - - case Memory::Size::ThirtyTwoBit: - // already little endian - WriteMemory(nAddress, u.u8, 4); - break; - - case Memory::Size::Float: - case Memory::Size::FloatBigEndian: - case Memory::Size::Double32: - case Memory::Size::Double32BigEndian: - case Memory::Size::MBF32: - case Memory::Size::MBF32LE: - // assume the value has already been encoded into a 32-bit little endian value - WriteMemory(nAddress, u.u8, 4); - break; - - case Memory::Size::SixteenBitBigEndian: - u.u8[3] = u.u8[0]; - u.u8[2] = u.u8[1]; - WriteMemory(nAddress, &u.u8[2], 2); - break; - - case Memory::Size::TwentyFourBitBigEndian: - u.u8[3] = u.u8[0]; - u.u8[0] = u.u8[2]; - u.u8[2] = u.u8[3]; - WriteMemory(nAddress, u.u8, 3); - break; - - case Memory::Size::ThirtyTwoBitBigEndian: - u.u32 = ra::data::Memory::ReverseBytes(nValue); - WriteMemory(nAddress, u.u8, 4); - break; - - case Memory::Size::Bit0: - u.u32 = (ReadMemoryByte(nAddress) & ~0x01) | (nValue & 1); - WriteMemory(nAddress, u.u8, 1); - break; - case Memory::Size::Bit1: - u.u32 = (ReadMemoryByte(nAddress) & ~0x02) | ((nValue & 1) << 1); - WriteMemory(nAddress, u.u8, 1); - break; - case Memory::Size::Bit2: - u.u32 = (ReadMemoryByte(nAddress) & ~0x04) | ((nValue & 1) << 2); - WriteMemory(nAddress, u.u8, 1); - break; - case Memory::Size::Bit3: - u.u32 = (ReadMemoryByte(nAddress) & ~0x08) | ((nValue & 1) << 3); - WriteMemory(nAddress, u.u8, 1); - break; - case Memory::Size::Bit4: - u.u32 = (ReadMemoryByte(nAddress) & ~0x10) | ((nValue & 1) << 4); - WriteMemory(nAddress, u.u8, 1); - break; - case Memory::Size::Bit5: - u.u32 = (ReadMemoryByte(nAddress) & ~0x20) | ((nValue & 1) << 5); - WriteMemory(nAddress, u.u8, 1); - break; - case Memory::Size::Bit6: - u.u32 = (ReadMemoryByte(nAddress) & ~0x40) | ((nValue & 1) << 6); - WriteMemory(nAddress, u.u8, 1); - break; - case Memory::Size::Bit7: - u.u32 = (ReadMemoryByte(nAddress) & ~0x80) | ((nValue & 1) << 7); - WriteMemory(nAddress, u.u8, 1); - break; - - case Memory::Size::NibbleLower: - u.u32 = (ReadMemoryByte(nAddress) & ~0x0F) | (nValue & 0x0F); - WriteMemory(nAddress, u.u8, 1); - break; - case Memory::Size::NibbleUpper: - u.u32 = (ReadMemoryByte(nAddress) & ~0xF0) | ((nValue & 0x0F) << 4); - WriteMemory(nAddress, u.u8, 1); - break; - - default: - break; - } -} - -void EmulatorContext::ResetMemoryModified() -{ - m_bMemoryModified = false; - - if (m_bMemoryInsecure) - { - // memory was insecure, immediately do a check - const auto& pDesktop = ra::services::ServiceLocator::Get(); - m_bMemoryInsecure = pDesktop.IsDebuggerPresent(); - - const auto& pClock = ra::services::ServiceLocator::Get(); - m_tLastInsecureCheck = pClock.UpTime(); - } -} - -bool EmulatorContext::IsMemoryInsecure() const -{ - if (m_bMemoryInsecure) - return true; - - // limit checks to once every 10 seconds - const auto& pClock = ra::services::ServiceLocator::Get(); - const auto tNow = pClock.UpTime(); - const auto tElapsed = tNow - m_tLastInsecureCheck; - if (tElapsed > std::chrono::seconds(10)) - { - const auto& pDesktop = ra::services::ServiceLocator::Get(); - m_bMemoryInsecure = pDesktop.IsDebuggerPresent(); - m_tLastInsecureCheck = tNow; - } - - return m_bMemoryInsecure; -} - -_CONSTANT_VAR MAX_BLOCK_SIZE = 256U * 1024; // 256K - -void EmulatorContext::CaptureMemory(std::vector& vBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const -{ - ra::data::ByteAddress nAdjustedAddress = nAddress; - for (const auto& pMemoryBlock : m_vMemoryBlocks) - { - if (nAdjustedAddress >= pMemoryBlock.size) - { - nAdjustedAddress -= gsl::narrow_cast(pMemoryBlock.size); - continue; - } - - if (!pMemoryBlock.read && !pMemoryBlock.readBlock) - { - nCount -= gsl::narrow_cast(pMemoryBlock.size); - nAddress += gsl::narrow_cast(pMemoryBlock.size); - nAdjustedAddress = 0; - continue; - } - - const uint32_t nBlockRemaining = gsl::narrow_cast(pMemoryBlock.size) - nAdjustedAddress; - uint32_t nToRead = std::min(nCount, nBlockRemaining); - nCount -= nToRead; - - while (nToRead > 0) - { - ra::data::CapturedMemoryBlock* pBlock = nullptr; - - const uint32_t nBlockSize = std::min(nToRead, MAX_BLOCK_SIZE); - const bool bIsLastBlock = (nCount == 0 && nBlockSize == nToRead); - if (!bIsLastBlock) - { - // capture nPadding overlapping bytes so we don't have to stitch multiple - // blocks together if a read occurs at the block boundary - pBlock = &vBlocks.emplace_back(nAddress, nBlockSize + nPadding, nBlockSize); - } - else - { - pBlock = &vBlocks.emplace_back(nAddress, nBlockSize, nBlockSize); - } - - Expects(pBlock != nullptr); - ReadMemory(nAdjustedAddress, pBlock->GetBytes(), nBlockSize, pMemoryBlock); - pBlock->OptimizeMemory(vBlocks); - - nAddress += nBlockSize; - nAdjustedAddress += nBlockSize; - nToRead -= nBlockSize; - } - - if (nCount == 0) - break; - - nAdjustedAddress = 0; - } - - if (nPadding) - { - // copy the first four bytes of each block to the last four bytes of the previous - // block to cover the overlap - for (size_t i = 1; i < vBlocks.size(); ++i) - { - auto& pDstBlock = vBlocks.at(i - 1); - // ASSERT: pDstBlock->GetBytes() is a size that's a multiple of 4 even if - // pDstBlock->GetBytesSize() is not. - auto* pDstBytes = pDstBlock.GetBytes() + (pDstBlock.GetBytesSize() & ~3); - const auto* pSrcBytes = vBlocks.at(i).GetBytes(); - memcpy(pDstBytes, pSrcBytes, 4); - } - } -} - void EmulatorContext::UpdateMenuState(int nMenuItemId) const { SyncClientExternalRAIntegrationMenuItem(nMenuItemId); diff --git a/src/data/context/EmulatorContext.hh b/src/data/context/EmulatorContext.hh index a53e0c708..318031835 100644 --- a/src/data/context/EmulatorContext.hh +++ b/src/data/context/EmulatorContext.hh @@ -178,128 +178,15 @@ public: /// const wchar_t* GetCancelButtonText() const noexcept { return m_sCancelButtonText; } - typedef uint8_t(MemoryReadFunction)(uint32_t nAddress); - typedef uint32_t(MemoryReadBlockFunction)(uint32_t nAddress, uint8_t* pBuffer, uint32_t nBytes); - typedef void (MemoryWriteFunction)(uint32_t nAddress, uint8_t nValue); - - /// - /// Specifies functions to read and write memory in the emulator. - /// - void AddMemoryBlock(gsl::index nIndex, size_t nBytes, MemoryReadFunction pReader, MemoryWriteFunction pWriter); - - /// - /// Specifies functions to read chunks of memory in the emulator. - /// - void AddMemoryBlockReader(gsl::index nIndex, MemoryReadBlockFunction pReader); - - /// - /// Clears all registered memory blocks so they can be rebuilt. - /// - void ClearMemoryBlocks(); - - /// - /// Gets the total amount of emulator-exposed memory. - /// - size_t TotalMemorySize() const noexcept { return m_nTotalMemorySize; } - - /// - /// Determines if any invalid regions were registered. - /// - bool HasInvalidRegions() const noexcept; - - /// - /// Determines if the specified address is valid. - /// - bool IsValidAddress(ra::data::ByteAddress nAddress) const noexcept; - - /// - /// Reads memory from the emulator. - /// - uint32_t ReadMemory(ra::data::ByteAddress nAddress, Memory::Size nSize) const; - - /// - /// Reads memory from the emulator. - /// - uint8_t ReadMemoryByte(ra::data::ByteAddress nAddress) const; - - /// - /// Reads memory from the emulator. - /// - uint32_t ReadMemory(ra::data::ByteAddress nAddress, _Out_writes_(nCount) uint8_t pBuffer[], size_t nCount) const; - - /// - /// Writes memory to the emulator. - /// - void WriteMemoryByte(ra::data::ByteAddress nAddress, uint8_t nValue) const; - - /// - /// Writes memory to the emulator. - /// - void WriteMemory(ra::data::ByteAddress nAddress, Memory::Size nSize, uint32_t nValue) const; - class DispatchesReadMemory { protected: static void DispatchMemoryRead(std::function&& fFunction); }; - /// - /// Captures the current state of memory - /// - void CaptureMemory(std::vector& vMemBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const; - - /// - /// Converts an address to a displayable string. - /// - std::string FormatAddress(ra::data::ByteAddress nAddress) const { return m_fFormatAddress(nAddress); } - - /// - /// Gets whether or not memory has been modified. - /// - bool WasMemoryModified() const noexcept { return m_bMemoryModified; } - - /// - /// Sets the memory modified flag. - /// - void SetMemoryModified() noexcept { m_bMemoryModified = true; } - - /// - /// Resets the memory modified flag. - /// - void ResetMemoryModified(); - - /// - /// Determines if the memory is considered secure. - /// - virtual bool IsMemoryInsecure() const; - - class NotifyTarget - { - public: - NotifyTarget() noexcept = default; - virtual ~NotifyTarget() noexcept = default; - NotifyTarget(const NotifyTarget&) noexcept = delete; - NotifyTarget& operator=(const NotifyTarget&) noexcept = delete; - NotifyTarget(NotifyTarget&&) noexcept = default; - NotifyTarget& operator=(NotifyTarget&&) noexcept = default; - - virtual void OnTotalMemorySizeChanged() noexcept(false) {} - virtual void OnByteWritten(ra::data::ByteAddress, uint8_t) noexcept(false) {} - }; - - void AddNotifyTarget(NotifyTarget& pTarget) noexcept { m_vNotifyTargets.Add(pTarget); } - void RemoveNotifyTarget(NotifyTarget& pTarget) noexcept { m_vNotifyTargets.Remove(pTarget); } - -private: - mutable ra::data::NotifyTargetSet m_vNotifyTargets; - - void WriteMemory(ra::data::ByteAddress nAddress, const uint8_t* pBytes, size_t nByteCount) const; - protected: void UpdateUserAgent(); - void OnTotalMemorySizeChanged(); virtual bool ValidateClientVersion(bool& bHardcore); - void AssertIsOnDoFrameThread() const noexcept(false); EmulatorID m_nEmulatorId = EmulatorID::UnknownEmulator; std::string m_sVersion; @@ -316,23 +203,6 @@ protected: std::function m_fUnpauseEmulator; std::function m_fGetGameTitle; std::function m_fRebuildMenu; - - std::function m_fFormatAddress; - - struct MemoryBlock - { - size_t size; - MemoryReadFunction* read; - MemoryWriteFunction* write; - MemoryReadBlockFunction* readBlock; - }; - static uint32_t ReadMemory(ra::data::ByteAddress nAddress, uint8_t pBuffer[], size_t nCount, const MemoryBlock& pBlock); - - std::vector m_vMemoryBlocks; - size_t m_nTotalMemorySize = 0U; - mutable bool m_bMemoryModified = false; - mutable bool m_bMemoryInsecure = false; - mutable std::chrono::steady_clock::time_point m_tLastInsecureCheck{}; }; } // namespace context diff --git a/src/data/context/SessionTracker.cpp b/src/data/context/SessionTracker.cpp index 48ae824a1..b7263193e 100644 --- a/src/data/context/SessionTracker.cpp +++ b/src/data/context/SessionTracker.cpp @@ -5,6 +5,8 @@ #include "util\Log.hh" #include "util\Strings.hh" +#include "context\IEmulatorMemoryContext.hh" + #include "data\context\GameContext.hh" #include "services\AchievementRuntime.hh" @@ -162,8 +164,8 @@ void SessionTracker::UpdateSession(time_t tSessionStart) const auto& pConfiguration = ra::services::ServiceLocator::Get(); if (pConfiguration.IsFeatureEnabled(ra::services::Feature::Hardcore)) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - pEmulatorContext.IsMemoryInsecure(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + pMemoryContext.IsMemoryInsecure(); } } diff --git a/src/data/models/CodeNoteModel.cpp b/src/data/models/CodeNoteModel.cpp index 75aa56a2e..92ff8a819 100644 --- a/src/data/models/CodeNoteModel.cpp +++ b/src/data/models/CodeNoteModel.cpp @@ -2,8 +2,6 @@ #include "context\IConsoleContext.hh" -#include "data\context\EmulatorContext.hh" - #include "services\ServiceLocator.hh" #include "util\Strings.hh" @@ -92,7 +90,7 @@ static ra::data::ByteAddress ConvertPointer(ra::data::ByteAddress nAddress) return nAddress; } -void CodeNoteModel::UpdateRawPointerValue(ra::data::ByteAddress nAddress, const ra::data::context::EmulatorContext& pEmulatorContext, +void CodeNoteModel::UpdateRawPointerValue(ra::data::ByteAddress nAddress, const ra::context::IEmulatorMemoryContext& pMemoryContext, NoteMovedFunction fNoteMovedCallback) { if (m_pPointerData == nullptr) @@ -100,7 +98,7 @@ void CodeNoteModel::UpdateRawPointerValue(ra::data::ByteAddress nAddress, const m_pPointerData->PointerRead = true; - const uint32_t nValue = pEmulatorContext.ReadMemory(nAddress, GetMemSize()); + const uint32_t nValue = pMemoryContext.ReadMemory(nAddress, GetMemSize()); if (nValue != m_pPointerData->RawPointerValue) { m_pPointerData->RawPointerValue = nValue; @@ -130,7 +128,7 @@ void CodeNoteModel::UpdateRawPointerValue(ra::data::ByteAddress nAddress, const if (pNote.IsPointer()) { pNote.UpdateRawPointerValue(m_pPointerData->PointerAddress + pNote.GetAddress(), - pEmulatorContext, fNoteMovedCallback); + pMemoryContext, fNoteMovedCallback); } } } @@ -1130,8 +1128,8 @@ void CodeNoteModel::ProcessIndirectNotes(const std::wstring& sNote, size_t nInde // flag it to be converted to an RA address when evaluating indirect notes in DoFrame() if (m_nMemSize == Memory::Size::ThirtyTwoBit || m_nMemSize == Memory::Size::ThirtyTwoBitBigEndian) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - const auto nMaxAddress = pEmulatorContext.TotalMemorySize(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nMaxAddress = pMemoryContext.TotalMemorySize(); const auto nUnderflowMinAddress = 0xFFFFFFFF - nMaxAddress + 1; pointerData->OffsetType = PointerData::OffsetType::Converted; diff --git a/src/data/models/CodeNoteModel.hh b/src/data/models/CodeNoteModel.hh index 2ff8e3dca..2c1af74b6 100644 --- a/src/data/models/CodeNoteModel.hh +++ b/src/data/models/CodeNoteModel.hh @@ -4,7 +4,7 @@ #include "data/Types.hh" -#include "data/context/EmulatorContext.hh" +#include "context/IEmulatorMemoryContext.hh" namespace ra { namespace data { @@ -45,7 +45,7 @@ public: virtual bool GetPointerChain(std::vector& vChain, const CodeNoteModel& pRootNote) const; typedef std::function NoteMovedFunction; - void UpdateRawPointerValue(ra::data::ByteAddress nAddress, const ra::data::context::EmulatorContext& pEmulatorContext, NoteMovedFunction fNoteMovedCallback); + void UpdateRawPointerValue(ra::data::ByteAddress nAddress, const ra::context::IEmulatorMemoryContext& pMemoryContext, NoteMovedFunction fNoteMovedCallback); bool GetPreviousAddress(ra::data::ByteAddress nBeforeAddress, ra::data::ByteAddress& nPreviousAddress) const; bool GetNextAddress(ra::data::ByteAddress nAfterAddress, ra::data::ByteAddress& nNextAddress) const; diff --git a/src/data/models/CodeNotesModel.cpp b/src/data/models/CodeNotesModel.cpp index 183e41a77..f362b19a3 100644 --- a/src/data/models/CodeNotesModel.cpp +++ b/src/data/models/CodeNotesModel.cpp @@ -510,7 +510,7 @@ void CodeNotesModel::DoFrame() if (!m_bHasPointers) return; - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); for (auto& pCodeNote : m_vCodeNotes) { @@ -518,11 +518,11 @@ void CodeNotesModel::DoFrame() { if (!m_fCodeNoteMoved) { - pCodeNote->UpdateRawPointerValue(pCodeNote->GetAddress(), pEmulatorContext, nullptr); + pCodeNote->UpdateRawPointerValue(pCodeNote->GetAddress(), pMemoryContext, nullptr); } else if (pCodeNote->HasRawPointerValue()) { - pCodeNote->UpdateRawPointerValue(pCodeNote->GetAddress(), pEmulatorContext, + pCodeNote->UpdateRawPointerValue(pCodeNote->GetAddress(), pMemoryContext, [this](ra::data::ByteAddress nOldAddress, ra::data::ByteAddress nNewAddress, const CodeNoteModel& pOffsetNote) { m_fCodeNoteMoved(nOldAddress, nNewAddress, pOffsetNote.GetNote()); }); @@ -530,7 +530,7 @@ void CodeNotesModel::DoFrame() else { // pointer hasn't been read before, provide dummy previous address - pCodeNote->UpdateRawPointerValue(pCodeNote->GetAddress(), pEmulatorContext, + pCodeNote->UpdateRawPointerValue(pCodeNote->GetAddress(), pMemoryContext, [this](ra::data::ByteAddress, ra::data::ByteAddress nNewAddress, const CodeNoteModel& pOffsetNote) { m_fCodeNoteMoved(0xFFFFFFFF, nNewAddress, pOffsetNote.GetNote()); }); diff --git a/src/data/models/MemoryRegionsModel.cpp b/src/data/models/MemoryRegionsModel.cpp index cd14984fb..3b5ad1168 100644 --- a/src/data/models/MemoryRegionsModel.cpp +++ b/src/data/models/MemoryRegionsModel.cpp @@ -2,7 +2,7 @@ #include "RA_Defs.h" -#include "data/context/EmulatorContext.hh" +#include "context/IEmulatorMemoryContext.hh" #include "services/ServiceLocator.hh" @@ -129,8 +129,8 @@ static bool ParseAddress(const wchar_t** pointer, ra::data::ByteAddress& address bool MemoryRegionsModel::ParseFilterRange(const std::wstring& sRange, _Out_ ra::data::ByteAddress& nStart, _Out_ ra::data::ByteAddress& nEnd) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - const auto nMax = gsl::narrow_cast(pEmulatorContext.TotalMemorySize()) - 1; + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nMax = gsl::narrow_cast(pMemoryContext.TotalMemorySize()) - 1; if (sRange.empty()) { diff --git a/src/data/models/TriggerValidation.cpp b/src/data/models/TriggerValidation.cpp index a94873f0f..50ae79e22 100644 --- a/src/data/models/TriggerValidation.cpp +++ b/src/data/models/TriggerValidation.cpp @@ -235,8 +235,8 @@ bool TriggerValidation::Validate(const std::string& sTrigger, std::wstring& sErr if (nMaxAddress == 0) { // if console definition doesn't specify the max address, see how much was exposed by the emulator - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - nMaxAddress = gsl::narrow_cast(pEmulatorContext.TotalMemorySize()) - 1; + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + nMaxAddress = gsl::narrow_cast(pMemoryContext.TotalMemorySize()) - 1; nResult = rc_validate_trigger(&trigger->trigger, sErrorBuffer, sizeof(sErrorBuffer), nMaxAddress); } diff --git a/src/devkit/RADevKit.vcxproj b/src/devkit/RADevKit.vcxproj index ce11eb874..c4b92da1f 100644 --- a/src/devkit/RADevKit.vcxproj +++ b/src/devkit/RADevKit.vcxproj @@ -58,6 +58,7 @@ + @@ -70,8 +71,11 @@ + + + @@ -86,10 +90,13 @@ + + + diff --git a/src/devkit/RADevKit.vcxproj.filters b/src/devkit/RADevKit.vcxproj.filters index 21c3825f7..64a9130b4 100644 --- a/src/devkit/RADevKit.vcxproj.filters +++ b/src/devkit/RADevKit.vcxproj.filters @@ -129,6 +129,24 @@ data + + context\impl + + + context + + + services\impl + + + services + + + services + + + services\impl + @@ -170,5 +188,8 @@ data + + context\impl + \ No newline at end of file diff --git a/src/devkit/context/IEmulatorMemoryContext.hh b/src/devkit/context/IEmulatorMemoryContext.hh new file mode 100644 index 000000000..20f925d49 --- /dev/null +++ b/src/devkit/context/IEmulatorMemoryContext.hh @@ -0,0 +1,120 @@ +#ifndef RA_CONTEXT_IEMULATORMEMORYCONTEXT_HH +#define RA_CONTEXT_IEMULATORMEMORYCONTEXT_HH +#pragma once + +#include "data/Memory.hh" + +#include + +#include "data/CapturedMemoryBlock.hh" +#include "data/NotifyTargetSet.hh" + +namespace ra { +namespace context { + +class IEmulatorMemoryContext +{ +public: + virtual ~IEmulatorMemoryContext() noexcept = default; + IEmulatorMemoryContext(const IEmulatorMemoryContext&) noexcept = delete; + IEmulatorMemoryContext& operator=(const IEmulatorMemoryContext&) noexcept = delete; + IEmulatorMemoryContext(IEmulatorMemoryContext&&) noexcept = delete; + IEmulatorMemoryContext& operator=(IEmulatorMemoryContext&&) noexcept = delete; + + /// + /// Gets the total amount of emulator-exposed memory. + /// + virtual size_t TotalMemorySize() const noexcept = 0; + + /// + /// Determines if any invalid regions were registered. + /// + virtual bool HasInvalidRegions() const noexcept = 0; + + /// + /// Determines if the specified address is valid. + /// + virtual bool IsValidAddress(ra::data::ByteAddress nAddress) const noexcept = 0; + + /// + /// Reads memory from the emulator. + /// + virtual uint32_t ReadMemory(ra::data::ByteAddress nAddress, ra::data::Memory::Size nSize) const = 0; + + /// + /// Reads memory from the emulator. + /// + virtual uint8_t ReadMemoryByte(ra::data::ByteAddress nAddress) const = 0; + + /// + /// Reads memory from the emulator. + /// + virtual uint32_t ReadMemory(ra::data::ByteAddress nAddress, uint8_t pBuffer[], size_t nCount) const = 0; + + /// + /// Writes memory to the emulator. + /// + virtual void WriteMemoryByte(ra::data::ByteAddress nAddress, uint8_t nValue) const = 0; + + /// + /// Writes memory to the emulator. + /// + virtual void WriteMemory(ra::data::ByteAddress nAddress, ra::data::Memory::Size nSize, uint32_t nValue) const = 0; + + /// + /// Captures the current state of memory + /// + virtual void CaptureMemory(std::vector& vMemBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const = 0; + + /// + /// Converts an address to a displayable string. + /// + virtual std::string FormatAddress(ra::data::ByteAddress nAddress) const = 0; + + /// + /// Gets whether or not memory has been modified. + /// + virtual bool WasMemoryModified() const noexcept = 0; + + /// + /// Sets the memory modified flag. + /// + virtual void SetMemoryModified() noexcept = 0; + + /// + /// Resets the memory modified flag. + /// + virtual void ResetMemoryModified() = 0; + + /// + /// Determines if the memory is considered secure. + /// + virtual bool IsMemoryInsecure() const = 0; + + class NotifyTarget + { + public: + NotifyTarget() noexcept = default; + virtual ~NotifyTarget() noexcept = default; + NotifyTarget(const NotifyTarget&) noexcept = delete; + NotifyTarget& operator=(const NotifyTarget&) noexcept = delete; + NotifyTarget(NotifyTarget&&) noexcept = default; + NotifyTarget& operator=(NotifyTarget&&) noexcept = default; + + virtual void OnTotalMemorySizeChanged() noexcept(false) {} + virtual void OnByteWritten(ra::data::ByteAddress, uint8_t) noexcept(false) {} + }; + + void AddNotifyTarget(NotifyTarget& pTarget) noexcept { m_vNotifyTargets.Add(pTarget); } + void RemoveNotifyTarget(NotifyTarget& pTarget) noexcept { m_vNotifyTargets.Remove(pTarget); } + +protected: + IEmulatorMemoryContext() noexcept = default; + + mutable ra::data::NotifyTargetSet m_vNotifyTargets; +}; + +} // namespace context +} // namespace ra + +#endif // !RA_CONTEXT_IEMULATORMEMORYCONTEXT_HH diff --git a/src/devkit/context/impl/EmulatorMemoryContext.cpp b/src/devkit/context/impl/EmulatorMemoryContext.cpp new file mode 100644 index 000000000..ceab3490c --- /dev/null +++ b/src/devkit/context/impl/EmulatorMemoryContext.cpp @@ -0,0 +1,623 @@ +#include "EmulatorMemoryContext.hh" + +#include "services/IClock.hh" +#include "services/IDebuggerDetector.hh" +#include "services/ServiceLocator.hh" + +#include "util/Compat.hh" +#include "util/TypeCasts.hh" + +namespace ra { +namespace context { +namespace impl { + +static std::string FormatAddressLarge(ra::data::ByteAddress nAddress) +{ + std::string sAddress; + sAddress.resize(10); + sprintf_s(sAddress.data(), 11, "0x%08x", nAddress); + return sAddress; +} + +static std::string FormatAddressMedium(ra::data::ByteAddress nAddress) +{ + if (nAddress & 0xFF000000) + return FormatAddressLarge(nAddress); + + std::string sAddress; + sAddress.resize(8); + sprintf_s(sAddress.data(), 9, "0x%06x", nAddress); + return sAddress; +} + +static std::string FormatAddressSmall(ra::data::ByteAddress nAddress) +{ + if (nAddress & 0xFFFF0000) + return FormatAddressMedium(nAddress); + + std::string sAddress; + sAddress.resize(6); + sprintf_s(sAddress.data(), 7, "0x%04x", nAddress); + return sAddress; +} + +GSL_SUPPRESS_F6 +EmulatorMemoryContext::EmulatorMemoryContext() noexcept +{ + m_fFormatAddress = FormatAddressSmall; +} + +void EmulatorMemoryContext::ClearMemoryBlocks() +{ + m_vMemoryBlocks.clear(); + + if (m_nTotalMemorySize != 0U) + { + m_nTotalMemorySize = 0U; + OnTotalMemorySizeChanged(); + } +} + +void EmulatorMemoryContext::AddMemoryBlock(gsl::index nIndex, size_t nBytes, + EmulatorMemoryContext::MemoryReadFunction pReader, EmulatorMemoryContext::MemoryWriteFunction pWriter) +{ + while (m_vMemoryBlocks.size() <= ra::to_unsigned(nIndex)) + m_vMemoryBlocks.emplace_back(); + + MemoryBlock& pBlock = m_vMemoryBlocks.at(nIndex); + if (pBlock.size == 0) + { + pBlock.size = nBytes; + pBlock.read = pReader; + pBlock.write = pWriter; + pBlock.readBlock = nullptr; + + m_nTotalMemorySize += nBytes; + + OnTotalMemorySizeChanged(); + } +} + +void EmulatorMemoryContext::AddMemoryBlockReader(gsl::index nIndex, + EmulatorMemoryContext::MemoryReadBlockFunction pReader) +{ + if (nIndex < gsl::narrow_cast(m_vMemoryBlocks.size())) + m_vMemoryBlocks.at(nIndex).readBlock = pReader; +} + +void EmulatorMemoryContext::OnTotalMemorySizeChanged() +{ + if (m_nTotalMemorySize <= 0x10000) + m_fFormatAddress = FormatAddressSmall; + else if (m_nTotalMemorySize <= 0x1000000) + m_fFormatAddress = FormatAddressMedium; + else + m_fFormatAddress = FormatAddressLarge; + + if (m_vNotifyTargets.LockIfNotEmpty()) + { + for (auto& target : m_vNotifyTargets.Targets()) + target.OnTotalMemorySizeChanged(); + + m_vNotifyTargets.Unlock(); + } +} + +bool EmulatorMemoryContext::HasInvalidRegions() const noexcept +{ + for (const auto& pBlock : m_vMemoryBlocks) + { + if (!pBlock.read) + return true; + } + + return false; +} + +bool EmulatorMemoryContext::IsValidAddress(ra::data::ByteAddress nAddress) const noexcept +{ + for (const auto& pBlock : m_vMemoryBlocks) + { + if (nAddress < pBlock.size) + { + if (pBlock.read) + return true; + + break; + } + + nAddress -= gsl::narrow_cast(pBlock.size); + } + + return false; +} + +void EmulatorMemoryContext::AssertIsOnDoFrameThread() const +{ +#if RA_INTEGRATION_VERSION_REVISION != 0 + #if !defined(RA_UTEST) + const auto* pClient = ra::services::ServiceLocator::Get().GetClient(); + const auto& pRuntime = ra::services::ServiceLocator::Get(); + if (!pClient->state.allow_background_memory_reads && + !pRuntime.IsOnDoFrameThread()) + { + const auto& pGameContext = ra::services::ServiceLocator::Get(); + if (pGameContext.GameId() != 0 && !pGameContext.IsGameLoading()) + { + ra::ui::viewmodels::MessageBoxViewModel::ShowWarningMessage( + L"Memory Read on Background Thread", + L"Memory is being read on a thread other than the thread that last called rc_client_do_frame and the " + L"client has specified that should not be allowed. Please notify a RetroAchievements engineer what you " + L"were doing when this occurred."); + } + } + #endif +#endif +} + +uint8_t EmulatorMemoryContext::ReadMemoryByte(ra::data::ByteAddress nAddress) const +{ + AssertIsOnDoFrameThread(); + + for (const auto& pBlock : m_vMemoryBlocks) + { + if (nAddress < pBlock.size) + { + if (pBlock.read) + return pBlock.read(nAddress); + + break; + } + + nAddress -= gsl::narrow_cast(pBlock.size); + } + + return 0; +} + +uint32_t EmulatorMemoryContext::ReadMemory(ra::data::ByteAddress nAddress, uint8_t pBuffer[], size_t nCount, + const EmulatorMemoryContext::MemoryBlock& pBlock) +{ + Expects(pBuffer != nullptr); + + if (pBlock.readBlock) + { + const size_t nRead = pBlock.readBlock(nAddress, pBuffer, gsl::narrow_cast(nCount)); + if (nRead < nCount) + memset(pBuffer + nRead, 0, nCount - nRead); + + return gsl::narrow_cast(nRead); + } + + if (!pBlock.read) + { + memset(pBuffer, 0, nCount); + return 0; + } + + auto nRemaining = nCount; + while (nRemaining >= 8) // unrolled loop to read 8-byte chunks + { + *pBuffer++ = pBlock.read(nAddress++); + *pBuffer++ = pBlock.read(nAddress++); + *pBuffer++ = pBlock.read(nAddress++); + *pBuffer++ = pBlock.read(nAddress++); + *pBuffer++ = pBlock.read(nAddress++); + *pBuffer++ = pBlock.read(nAddress++); + *pBuffer++ = pBlock.read(nAddress++); + *pBuffer++ = pBlock.read(nAddress++); + nRemaining -= 8; + } + + switch (nRemaining) // partial Duff's device to read remaining bytes + { + case 7: + *pBuffer++ = pBlock.read(nAddress++); + _FALLTHROUGH; + case 6: + *pBuffer++ = pBlock.read(nAddress++); + _FALLTHROUGH; + case 5: + *pBuffer++ = pBlock.read(nAddress++); + _FALLTHROUGH; + case 4: + *pBuffer++ = pBlock.read(nAddress++); + _FALLTHROUGH; + case 3: + *pBuffer++ = pBlock.read(nAddress++); + _FALLTHROUGH; + case 2: + *pBuffer++ = pBlock.read(nAddress++); + _FALLTHROUGH; + case 1: + *pBuffer++ = pBlock.read(nAddress++); + _FALLTHROUGH; + default: + break; + } + + return gsl::narrow_cast(nCount); +} + +uint32_t EmulatorMemoryContext::ReadMemory(ra::data::ByteAddress nAddress, uint8_t pBuffer[], size_t nCount) const +{ + AssertIsOnDoFrameThread(); + + uint32_t nBytesRead = 0; + Expects(pBuffer != nullptr); + + for (const auto& pBlock : m_vMemoryBlocks) + { + if (nAddress >= pBlock.size) + { + nAddress -= gsl::narrow_cast(pBlock.size); + continue; + } + + const size_t nBlockRemaining = pBlock.size - nAddress; + size_t nToRead = std::min(nCount, nBlockRemaining); + + nBytesRead += ReadMemory(nAddress, pBuffer, nToRead, pBlock); + + pBuffer += nToRead; + nCount -= nToRead; + + if (nCount == 0) + return nBytesRead; + + nAddress = 0; + } + + if (nCount > 0) + memset(pBuffer, 0, nCount); + + return nBytesRead; +} + +uint32_t EmulatorMemoryContext::ReadMemory(ra::data::ByteAddress nAddress, ra::data::Memory::Size nSize) const +{ + switch (nSize) + { + case ra::data::Memory::Size::Bit0: + return (ReadMemoryByte(nAddress) & 0x01); + case ra::data::Memory::Size::Bit1: + return (ReadMemoryByte(nAddress) & 0x02) ? 1 : 0; + case ra::data::Memory::Size::Bit2: + return (ReadMemoryByte(nAddress) & 0x04) ? 1 : 0; + case ra::data::Memory::Size::Bit3: + return (ReadMemoryByte(nAddress) & 0x08) ? 1 : 0; + case ra::data::Memory::Size::Bit4: + return (ReadMemoryByte(nAddress) & 0x10) ? 1 : 0; + case ra::data::Memory::Size::Bit5: + return (ReadMemoryByte(nAddress) & 0x20) ? 1 : 0; + case ra::data::Memory::Size::Bit6: + return (ReadMemoryByte(nAddress) & 0x40) ? 1 : 0; + case ra::data::Memory::Size::Bit7: + return (ReadMemoryByte(nAddress) & 0x80) ? 1 : 0; + case ra::data::Memory::Size::NibbleLower: + return (ReadMemoryByte(nAddress) & 0x0F); + case ra::data::Memory::Size::NibbleUpper: + return ((ReadMemoryByte(nAddress) >> 4) & 0x0F); + case ra::data::Memory::Size::EightBit: + return ReadMemoryByte(nAddress); + default: + case ra::data::Memory::Size::SixteenBit: + { + uint8_t buffer[2]; + ReadMemory(nAddress, buffer, 2); + return buffer[0] | (buffer[1] << 8); + } + case ra::data::Memory::Size::TwentyFourBit: + { + uint8_t buffer[3]; + ReadMemory(nAddress, buffer, 3); + return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16); + } + case ra::data::Memory::Size::Float: + case ra::data::Memory::Size::FloatBigEndian: + case ra::data::Memory::Size::Double32: + case ra::data::Memory::Size::Double32BigEndian: + case ra::data::Memory::Size::MBF32: + case ra::data::Memory::Size::MBF32LE: + case ra::data::Memory::Size::ThirtyTwoBit: + { + uint8_t buffer[4]; + ReadMemory(nAddress, buffer, 4); + return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); + } + case ra::data::Memory::Size::SixteenBitBigEndian: + { + uint8_t buffer[2]; + ReadMemory(nAddress, buffer, 2); + return buffer[1] | (buffer[0] << 8); + } + case ra::data::Memory::Size::TwentyFourBitBigEndian: + { + uint8_t buffer[3]; + ReadMemory(nAddress, buffer, 3); + return buffer[2] | (buffer[1] << 8) | (buffer[0] << 16); + } + case ra::data::Memory::Size::ThirtyTwoBitBigEndian: + { + uint8_t buffer[4]; + ReadMemory(nAddress, buffer, 4); + return buffer[3] | (buffer[2] << 8) | (buffer[1] << 16) | (buffer[0] << 24); + } + case ra::data::Memory::Size::BitCount: + { + const uint8_t nValue = ReadMemoryByte(nAddress); + static const std::array nBitsSet = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; + return nBitsSet.at(nValue & 0x0F) + nBitsSet.at((nValue >> 4) & 0x0F); + } + } +} + +void EmulatorMemoryContext::WriteMemory(ra::data::ByteAddress nAddress, const uint8_t* pBytes, size_t nBytes) const +{ + Expects(pBytes != nullptr); + size_t nBytesWritten = 0; + auto nBlockAddress = nAddress; + + for (const auto& pBlock : m_vMemoryBlocks) + { + if (nBlockAddress < pBlock.size) + { + if (!pBlock.write) + break; + + m_bMemoryModified = true; + + if (nBytes == 1) + { + pBlock.write(nBlockAddress, pBytes[0]); + nBytesWritten = 1; + break; + } + else + { + do + { + pBlock.write(nBlockAddress++, pBytes[nBytesWritten++]); + } while (nBytesWritten < nBytes && nBlockAddress < pBlock.size); + + if (nBytesWritten == nBytes) + break; + } + } + + nBlockAddress -= gsl::narrow_cast(pBlock.size); + } + + if (nBytesWritten > 0) + { + if (m_vNotifyTargets.LockIfNotEmpty()) + { + for (auto& target : m_vNotifyTargets.Targets()) + { + for (unsigned nIndex = 0; nIndex < nBytesWritten; ++nIndex) + target.OnByteWritten(nAddress + nIndex, pBytes[nIndex]); + } + + m_vNotifyTargets.Unlock(); + } + } +} + +void EmulatorMemoryContext::WriteMemoryByte(ra::data::ByteAddress nAddress, uint8_t nValue) const +{ + WriteMemory(nAddress, &nValue, 1); +} + +void EmulatorMemoryContext::WriteMemory(ra::data::ByteAddress nAddress, ra::data::Memory::Size nSize, uint32_t nValue) const +{ + union + { + uint32_t u32; + uint8_t u8[4]; + } u; + u.u32 = nValue; + + switch (nSize) + { + case ra::data::Memory::Size::EightBit: + WriteMemory(nAddress, u.u8, 1); + break; + + case ra::data::Memory::Size::SixteenBit: + WriteMemory(nAddress, u.u8, 2); + break; + + case ra::data::Memory::Size::TwentyFourBit: + WriteMemory(nAddress, u.u8, 3); + break; + + case ra::data::Memory::Size::ThirtyTwoBit: + // already little endian + WriteMemory(nAddress, u.u8, 4); + break; + + case ra::data::Memory::Size::Float: + case ra::data::Memory::Size::FloatBigEndian: + case ra::data::Memory::Size::Double32: + case ra::data::Memory::Size::Double32BigEndian: + case ra::data::Memory::Size::MBF32: + case ra::data::Memory::Size::MBF32LE: + // assume the value has already been encoded into a 32-bit little endian value + WriteMemory(nAddress, u.u8, 4); + break; + + case ra::data::Memory::Size::SixteenBitBigEndian: + u.u8[3] = u.u8[0]; + u.u8[2] = u.u8[1]; + WriteMemory(nAddress, &u.u8[2], 2); + break; + + case ra::data::Memory::Size::TwentyFourBitBigEndian: + u.u8[3] = u.u8[0]; + u.u8[0] = u.u8[2]; + u.u8[2] = u.u8[3]; + WriteMemory(nAddress, u.u8, 3); + break; + + case ra::data::Memory::Size::ThirtyTwoBitBigEndian: + u.u32 = ra::data::Memory::ReverseBytes(nValue); + WriteMemory(nAddress, u.u8, 4); + break; + + case ra::data::Memory::Size::Bit0: + u.u32 = (ReadMemoryByte(nAddress) & ~0x01) | (nValue & 1); + WriteMemory(nAddress, u.u8, 1); + break; + case ra::data::Memory::Size::Bit1: + u.u32 = (ReadMemoryByte(nAddress) & ~0x02) | ((nValue & 1) << 1); + WriteMemory(nAddress, u.u8, 1); + break; + case ra::data::Memory::Size::Bit2: + u.u32 = (ReadMemoryByte(nAddress) & ~0x04) | ((nValue & 1) << 2); + WriteMemory(nAddress, u.u8, 1); + break; + case ra::data::Memory::Size::Bit3: + u.u32 = (ReadMemoryByte(nAddress) & ~0x08) | ((nValue & 1) << 3); + WriteMemory(nAddress, u.u8, 1); + break; + case ra::data::Memory::Size::Bit4: + u.u32 = (ReadMemoryByte(nAddress) & ~0x10) | ((nValue & 1) << 4); + WriteMemory(nAddress, u.u8, 1); + break; + case ra::data::Memory::Size::Bit5: + u.u32 = (ReadMemoryByte(nAddress) & ~0x20) | ((nValue & 1) << 5); + WriteMemory(nAddress, u.u8, 1); + break; + case ra::data::Memory::Size::Bit6: + u.u32 = (ReadMemoryByte(nAddress) & ~0x40) | ((nValue & 1) << 6); + WriteMemory(nAddress, u.u8, 1); + break; + case ra::data::Memory::Size::Bit7: + u.u32 = (ReadMemoryByte(nAddress) & ~0x80) | ((nValue & 1) << 7); + WriteMemory(nAddress, u.u8, 1); + break; + + case ra::data::Memory::Size::NibbleLower: + u.u32 = (ReadMemoryByte(nAddress) & ~0x0F) | (nValue & 0x0F); + WriteMemory(nAddress, u.u8, 1); + break; + case ra::data::Memory::Size::NibbleUpper: + u.u32 = (ReadMemoryByte(nAddress) & ~0xF0) | ((nValue & 0x0F) << 4); + WriteMemory(nAddress, u.u8, 1); + break; + + default: + break; + } +} + +void EmulatorMemoryContext::ResetMemoryModified() +{ + m_bMemoryModified = false; + + if (m_bMemoryInsecure) + { + // memory was insecure, immediately do a check + const auto& pDesktop = ra::services::ServiceLocator::Get(); + m_bMemoryInsecure = pDesktop.IsDebuggerPresent(); + + const auto& pClock = ra::services::ServiceLocator::Get(); + m_tLastInsecureCheck = pClock.UpTime(); + } +} + +bool EmulatorMemoryContext::IsMemoryInsecure() const +{ + if (m_bMemoryInsecure) + return true; + + // limit checks to once every 10 seconds + const auto& pClock = ra::services::ServiceLocator::Get(); + const auto tNow = pClock.UpTime(); + const auto tElapsed = tNow - m_tLastInsecureCheck; + if (tElapsed > std::chrono::seconds(10)) + { + const auto& pDesktop = ra::services::ServiceLocator::Get(); + m_bMemoryInsecure = pDesktop.IsDebuggerPresent(); + m_tLastInsecureCheck = tNow; + } + + return m_bMemoryInsecure; +} + +_CONSTANT_VAR MAX_BLOCK_SIZE = 256U * 1024; // 256K + +void EmulatorMemoryContext::CaptureMemory(std::vector& vBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const +{ + ra::data::ByteAddress nAdjustedAddress = nAddress; + for (const auto& pMemoryBlock : m_vMemoryBlocks) + { + if (nAdjustedAddress >= pMemoryBlock.size) + { + nAdjustedAddress -= gsl::narrow_cast(pMemoryBlock.size); + continue; + } + + if (!pMemoryBlock.read && !pMemoryBlock.readBlock) + { + nCount -= gsl::narrow_cast(pMemoryBlock.size); + nAddress += gsl::narrow_cast(pMemoryBlock.size); + nAdjustedAddress = 0; + continue; + } + + const uint32_t nBlockRemaining = gsl::narrow_cast(pMemoryBlock.size) - nAdjustedAddress; + uint32_t nToRead = std::min(nCount, nBlockRemaining); + nCount -= nToRead; + + while (nToRead > 0) + { + ra::data::CapturedMemoryBlock* pBlock = nullptr; + + const uint32_t nBlockSize = std::min(nToRead, MAX_BLOCK_SIZE); + const bool bIsLastBlock = (nCount == 0 && nBlockSize == nToRead); + if (!bIsLastBlock) + { + // capture nPadding overlapping bytes so we don't have to stitch multiple + // blocks together if a read occurs at the block boundary + pBlock = &vBlocks.emplace_back(nAddress, nBlockSize + nPadding, nBlockSize); + } + else + { + pBlock = &vBlocks.emplace_back(nAddress, nBlockSize, nBlockSize); + } + + Expects(pBlock != nullptr); + ReadMemory(nAdjustedAddress, pBlock->GetBytes(), nBlockSize, pMemoryBlock); + pBlock->OptimizeMemory(vBlocks); + + nAddress += nBlockSize; + nAdjustedAddress += nBlockSize; + nToRead -= nBlockSize; + } + + if (nCount == 0) + break; + + nAdjustedAddress = 0; + } + + if (nPadding) + { + // copy the first four bytes of each block to the last four bytes of the previous + // block to cover the overlap + for (size_t i = 1; i < vBlocks.size(); ++i) + { + auto& pDstBlock = vBlocks.at(i - 1); + // ASSERT: pDstBlock->GetBytes() is a size that's a multiple of 4 even if + // pDstBlock->GetBytesSize() is not. + auto* pDstBytes = pDstBlock.GetBytes() + (pDstBlock.GetBytesSize() & ~3); + const auto* pSrcBytes = vBlocks.at(i).GetBytes(); + memcpy(pDstBytes, pSrcBytes, 4); + } + } +} + +} // namespace impl +} // namespace context +} // namespace ra diff --git a/src/devkit/context/impl/EmulatorMemoryContext.hh b/src/devkit/context/impl/EmulatorMemoryContext.hh new file mode 100644 index 000000000..98cd3b525 --- /dev/null +++ b/src/devkit/context/impl/EmulatorMemoryContext.hh @@ -0,0 +1,139 @@ +#ifndef RA_CONTEXT_IMPL_EMULATORMEMORYCONTEXT_HH +#define RA_CONTEXT_IMPL_EMULATORMEMORYCONTEXT_HH +#pragma once + +#include "context/IEmulatorMemoryContext.hh" + +namespace ra { +namespace context { +namespace impl { + +class EmulatorMemoryContext : public IEmulatorMemoryContext +{ +public: + EmulatorMemoryContext() noexcept; + virtual ~EmulatorMemoryContext() noexcept = default; + EmulatorMemoryContext(const EmulatorMemoryContext&) noexcept = delete; + EmulatorMemoryContext& operator=(const EmulatorMemoryContext&) noexcept = delete; + EmulatorMemoryContext(EmulatorMemoryContext&&) noexcept = delete; + EmulatorMemoryContext& operator=(EmulatorMemoryContext&&) noexcept = delete; + + typedef uint8_t(MemoryReadFunction)(uint32_t nAddress); + typedef uint32_t(MemoryReadBlockFunction)(uint32_t nAddress, uint8_t* pBuffer, uint32_t nBytes); + typedef void (MemoryWriteFunction)(uint32_t nAddress, uint8_t nValue); + + /// + /// Specifies functions to read and write memory in the emulator. + /// + void AddMemoryBlock(gsl::index nIndex, size_t nBytes, MemoryReadFunction pReader, MemoryWriteFunction pWriter); + + /// + /// Specifies functions to read chunks of memory in the emulator. + /// + void AddMemoryBlockReader(gsl::index nIndex, MemoryReadBlockFunction pReader); + + /// + /// Clears all registered memory blocks so they can be rebuilt. + /// + void ClearMemoryBlocks(); + + /// + /// Gets the total amount of emulator-exposed memory. + /// + size_t TotalMemorySize() const noexcept override { return m_nTotalMemorySize; } + + /// + /// Determines if any invalid regions were registered. + /// + bool HasInvalidRegions() const noexcept override; + + /// + /// Determines if the specified address is valid. + /// + bool IsValidAddress(ra::data::ByteAddress nAddress) const noexcept override; + + /// + /// Reads memory from the emulator. + /// + uint32_t ReadMemory(ra::data::ByteAddress nAddress, ra::data::Memory::Size nSize) const override; + + /// + /// Reads memory from the emulator. + /// + uint8_t ReadMemoryByte(ra::data::ByteAddress nAddress) const override; + + /// + /// Reads memory from the emulator. + /// + uint32_t ReadMemory(ra::data::ByteAddress nAddress, uint8_t pBuffer[], size_t nCount) const override; + + /// + /// Writes memory to the emulator. + /// + void WriteMemoryByte(ra::data::ByteAddress nAddress, uint8_t nValue) const override; + + /// + /// Writes memory to the emulator. + /// + void WriteMemory(ra::data::ByteAddress nAddress, ra::data::Memory::Size nSize, uint32_t nValue) const override; + + /// + /// Captures the current state of memory + /// + void CaptureMemory(std::vector& vMemBlocks, ra::data::ByteAddress nAddress, uint32_t nCount, uint32_t nPadding) const override; + + /// + /// Converts an address to a displayable string. + /// + std::string FormatAddress(ra::data::ByteAddress nAddress) const override { return m_fFormatAddress(nAddress); } + + /// + /// Gets whether or not memory has been modified. + /// + bool WasMemoryModified() const noexcept override { return m_bMemoryModified; } + + /// + /// Sets the memory modified flag. + /// + void SetMemoryModified() noexcept override { m_bMemoryModified = true; } + + /// + /// Resets the memory modified flag. + /// + void ResetMemoryModified() override; + + /// + /// Determines if the memory is considered secure. + /// + bool IsMemoryInsecure() const override; + +private: + void WriteMemory(ra::data::ByteAddress nAddress, const uint8_t* pBytes, size_t nByteCount) const; + +protected: + void OnTotalMemorySizeChanged(); + void AssertIsOnDoFrameThread() const noexcept(false); + + std::function m_fFormatAddress; + + struct MemoryBlock + { + size_t size; + MemoryReadFunction* read; + MemoryWriteFunction* write; + MemoryReadBlockFunction* readBlock; + }; + static uint32_t ReadMemory(ra::data::ByteAddress nAddress, uint8_t pBuffer[], size_t nCount, const MemoryBlock& pBlock); + + std::vector m_vMemoryBlocks; + size_t m_nTotalMemorySize = 0U; + mutable bool m_bMemoryModified = false; + mutable bool m_bMemoryInsecure = false; + mutable std::chrono::steady_clock::time_point m_tLastInsecureCheck{}; +}; + +} // namespace impl +} // namespace context +} // namespace ra + +#endif // !RA_CONTEXT_IMPL_EMULATORMEMORYCONTEXT_HH diff --git a/src/services/IClock.hh b/src/devkit/services/IClock.hh similarity index 94% rename from src/services/IClock.hh rename to src/devkit/services/IClock.hh index 2f351b4bb..639d56842 100644 --- a/src/services/IClock.hh +++ b/src/devkit/services/IClock.hh @@ -2,6 +2,8 @@ #define RA_SERVICES_ICLOCK_HH #pragma once +#include + namespace ra { namespace services { @@ -33,4 +35,4 @@ protected: } // namespace services } // namespace ra -#endif // !RA_SERVICES_ILOGGER_HH +#endif // !RA_SERVICES_ICLOCK_HH diff --git a/src/devkit/services/IDebuggerDetector.hh b/src/devkit/services/IDebuggerDetector.hh new file mode 100644 index 000000000..644a7f7ef --- /dev/null +++ b/src/devkit/services/IDebuggerDetector.hh @@ -0,0 +1,29 @@ +#ifndef RA_SERVICES_IDEBUGGERDETECTOR_HH +#define RA_SERVICES_IDEBUGGERDETECTOR_HH +#pragma once + +namespace ra { +namespace services { + +class IDebuggerDetector +{ +public: + virtual ~IDebuggerDetector() noexcept = default; + IDebuggerDetector(const IDebuggerDetector&) noexcept = delete; + IDebuggerDetector& operator=(const IDebuggerDetector&) noexcept = delete; + IDebuggerDetector(IDebuggerDetector&&) noexcept = delete; + IDebuggerDetector& operator=(IDebuggerDetector&&) noexcept = delete; + + /// + /// Determines if the process is running in a debugger. + /// + virtual bool IsDebuggerPresent() const = 0; + +protected: + IDebuggerDetector() noexcept = default; +}; + +} // namespace services +} // namespace ra + +#endif // !RA_SERVICES_IDEBUGGERDETECTOR_HH diff --git a/src/services/impl/Clock.hh b/src/devkit/services/impl/Clock.hh similarity index 100% rename from src/services/impl/Clock.hh rename to src/devkit/services/impl/Clock.hh diff --git a/src/services/AchievementRuntime.cpp b/src/services/AchievementRuntime.cpp index 2ff6cd441..bfd72b2f2 100644 --- a/src/services/AchievementRuntime.cpp +++ b/src/services/AchievementRuntime.cpp @@ -12,6 +12,7 @@ #include "RA_md5factory.h" #include "context\IConsoleContext.hh" +#include "context\IEmulatorMemoryContext.hh" #include "context\IRcClient.hh" #include "data\context\EmulatorContext.hh" @@ -61,11 +62,11 @@ static int CanSubmit() if (pConfiguration.IsFeatureEnabled(ra::services::Feature::Offline)) return 0; - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - if (pEmulatorContext.WasMemoryModified()) + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + if (pMemoryContext.WasMemoryModified()) return 0; - if (_RA_HardcoreModeIsActive() && pEmulatorContext.IsMemoryInsecure()) + if (_RA_HardcoreModeIsActive() && pMemoryContext.IsMemoryInsecure()) return 0; return 1; @@ -235,8 +236,8 @@ AchievementRuntime::~AchievementRuntime() uint32_t AchievementRuntime::ReadMemory(uint32_t nAddress, uint8_t* pBuffer, uint32_t nBytes, rc_client_t*) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - return pEmulatorContext.ReadMemory(nAddress, pBuffer, nBytes); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + return pMemoryContext.ReadMemory(nAddress, pBuffer, nBytes); } typedef struct QueueMemoryReadData @@ -1639,8 +1640,8 @@ static void HandleAchievementTriggeredEvent(const rc_client_achievement_t& pAchi bSubmit = false; } - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - if (bSubmit && pEmulatorContext.WasMemoryModified()) + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + if (bSubmit && pMemoryContext.WasMemoryModified()) { vmPopup->SetTitle(L"Achievement Unlocked LOCALLY"); vmPopup->SetErrorDetail(L"Error: RAM tampered with"); @@ -1650,7 +1651,7 @@ static void HandleAchievementTriggeredEvent(const rc_client_achievement_t& pAchi bSubmit = false; } - if (bSubmit && _RA_HardcoreModeIsActive() && pEmulatorContext.IsMemoryInsecure()) + if (bSubmit && _RA_HardcoreModeIsActive() && pMemoryContext.IsMemoryInsecure()) { vmPopup->SetTitle(L"Achievement Unlocked LOCALLY"); vmPopup->SetErrorDetail(L"Error: RAM insecure"); @@ -1969,8 +1970,8 @@ static void HandleLeaderboardSubmittedEvent(const rc_client_leaderboard_t& pLead bSubmit = false; } - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - if (bSubmit && pEmulatorContext.WasMemoryModified()) + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + if (bSubmit && pMemoryContext.WasMemoryModified()) { vmPopup->SetErrorDetail(L"Error: RAM tampered with"); bSubmit = false; @@ -1983,7 +1984,7 @@ static void HandleLeaderboardSubmittedEvent(const rc_client_leaderboard_t& pLead vmPopup->SetErrorDetail(L"Submission requires Hardcore mode"); bSubmit = false; } - else if (pEmulatorContext.IsMemoryInsecure()) + else if (pMemoryContext.IsMemoryInsecure()) { vmPopup->SetErrorDetail(L"Error: RAM insecure"); bSubmit = false; @@ -2702,15 +2703,15 @@ int AchievementRuntime::SaveProgressToBuffer(uint8_t* pBuffer, int nBufferSize) extern "C" unsigned int rc_peek_callback(unsigned int nAddress, unsigned int nBytes, _UNUSED void* pData) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); switch (nBytes) { case 1: - return pEmulatorContext.ReadMemoryByte(nAddress); + return pMemoryContext.ReadMemoryByte(nAddress); case 2: - return pEmulatorContext.ReadMemory(nAddress, ra::data::Memory::Size::SixteenBit); + return pMemoryContext.ReadMemory(nAddress, ra::data::Memory::Size::SixteenBit); case 4: - return pEmulatorContext.ReadMemory(nAddress, ra::data::Memory::Size::ThirtyTwoBit); + return pMemoryContext.ReadMemory(nAddress, ra::data::Memory::Size::ThirtyTwoBit); default: return 0U; } diff --git a/src/services/AchievementRuntimeExports.cpp b/src/services/AchievementRuntimeExports.cpp index 6c21c3569..860b6aefe 100644 --- a/src/services/AchievementRuntimeExports.cpp +++ b/src/services/AchievementRuntimeExports.cpp @@ -5,7 +5,9 @@ #include "RA_Resource.h" #include "context\IConsoleContext.hh" +#include "context\IEmulatorMemoryContext.hh" #include "context\IRcClient.hh" +#include "context\impl\EmulatorMemoryContext.hh" #include "data\context\GameContext.hh" @@ -71,9 +73,9 @@ class AchievementRuntimeExports : private AchievementRuntime typedef struct MemoryBlockWrapper { ra::data::ByteAddress nOffset; - ra::data::context::EmulatorContext::MemoryReadFunction* fReadByte; - ra::data::context::EmulatorContext::MemoryWriteFunction* fWriteByte; - ra::data::context::EmulatorContext::MemoryReadBlockFunction* fReadBlock; + ra::context::impl::EmulatorMemoryContext::MemoryReadFunction* fReadByte; + ra::context::impl::EmulatorMemoryContext::MemoryWriteFunction* fWriteByte; + ra::context::impl::EmulatorMemoryContext::MemoryReadBlockFunction* fReadBlock; } MemoryBlockWrapper; static std::array s_memoryBlockWrappers; @@ -83,8 +85,11 @@ class AchievementRuntimeExports : private AchievementRuntime { const auto& pConsoleContext = ra::services::ServiceLocator::Get(); - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.ClearMemoryBlocks(); + auto* pEmulatorMemoryContext = dynamic_cast(&ra::services::ServiceLocator::GetMutable()); + if (!pEmulatorMemoryContext) + return; + + pEmulatorMemoryContext->ClearMemoryBlocks(); gsl::index nIndex = 0; uint32_t nBytes = 0; @@ -96,10 +101,10 @@ class AchievementRuntimeExports : private AchievementRuntime { if (nBytes > 0) { - pEmulatorContext.AddMemoryBlock(nIndex, nBytes, + pEmulatorMemoryContext->AddMemoryBlock(nIndex, nBytes, s_memoryBlockWrappers.at(nIndex).fReadByte, s_memoryBlockWrappers.at(nIndex).fWriteByte); - pEmulatorContext.AddMemoryBlockReader(nIndex, + pEmulatorMemoryContext->AddMemoryBlockReader(nIndex, s_memoryBlockWrappers.at(nIndex).fReadBlock); nBytes = 0; @@ -107,7 +112,7 @@ class AchievementRuntimeExports : private AchievementRuntime s_memoryBlockWrappers.at(nIndex).nOffset = pRegion.GetStartAddress(); } - pEmulatorContext.AddMemoryBlock(nIndex++, nSize, nullptr, nullptr); + pEmulatorMemoryContext->AddMemoryBlock(nIndex++, nSize, nullptr, nullptr); Expects(gsl::narrow_cast(nIndex) < s_memoryBlockWrappers.size()); s_memoryBlockWrappers.at(nIndex).nOffset = pRegion.GetEndAddress() + 1; @@ -120,10 +125,10 @@ class AchievementRuntimeExports : private AchievementRuntime if (nBytes > 0) { - pEmulatorContext.AddMemoryBlock(nIndex, nBytes, + pEmulatorMemoryContext->AddMemoryBlock(nIndex, nBytes, s_memoryBlockWrappers.at(nIndex).fReadByte, s_memoryBlockWrappers.at(nIndex).fWriteByte); - pEmulatorContext.AddMemoryBlockReader(nIndex, + pEmulatorMemoryContext->AddMemoryBlockReader(nIndex, s_memoryBlockWrappers.at(nIndex).fReadBlock); } } @@ -586,11 +591,11 @@ class AchievementRuntimeExports : private AchievementRuntime pAchievement->GetChanges() != ra::data::models::AssetChanges::None) // unpublished changes return RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_MODIFIED; - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - if (pEmulatorContext.WasMemoryModified()) + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + if (pMemoryContext.WasMemoryModified()) return RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_INSECURE; - if (_RA_HardcoreModeIsActive() && pEmulatorContext.IsMemoryInsecure()) + if (_RA_HardcoreModeIsActive() && pMemoryContext.IsMemoryInsecure()) return RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_INSECURE; return RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_PUBLISHED; diff --git a/src/services/GameIdentifier.cpp b/src/services/GameIdentifier.cpp index e9f304003..f18c415d7 100644 --- a/src/services/GameIdentifier.cpp +++ b/src/services/GameIdentifier.cpp @@ -8,6 +8,7 @@ #include "api\ResolveHash.hh" #include "context\IConsoleContext.hh" +#include "context\IEmulatorMemoryContext.hh" #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" @@ -218,7 +219,7 @@ void GameIdentifier::ActivateGame(unsigned int nGameId) pGameContext.SetGameHash((m_nPendingGameId == 0) ? m_sPendingHash : ""); } - ra::services::ServiceLocator::GetMutable().ResetMemoryModified(); + ra::services::ServiceLocator::GetMutable().ResetMemoryModified(); } void GameIdentifier::IdentifyAndActivateGame(const BYTE* pROM, size_t nROMSize) diff --git a/src/services/Initialization.cpp b/src/services/Initialization.cpp index f9e5ee542..a5b04351d 100644 --- a/src/services/Initialization.cpp +++ b/src/services/Initialization.cpp @@ -3,6 +3,7 @@ #include "api\impl\DisconnectedServer.hh" #include "context\impl\ConsoleContext.hh" +#include "context\impl\EmulatorMemoryContext.hh" #include "context\impl\RcClient.hh" #include "data\context\EmulatorContext.hh" @@ -23,6 +24,7 @@ #include "services\impl\WindowsAudioSystem.hh" #include "services\impl\WindowsClipboard.hh" #include "services\impl\WindowsDebuggerFileLogger.hh" +#include "services\impl\WindowsDebuggerDetector.hh" #include "services\impl\WindowsFileSystem.hh" #include "services\impl\WindowsHttpRequester.hh" @@ -161,6 +163,12 @@ void Initialization::RegisterServices(EmulatorID nEmulatorId, const char* sClien auto pRcClient = std::make_unique(); ra::services::ServiceLocator::Provide(std::move(pRcClient)); + auto pEmulatorMemoryContext = std::make_unique(); + ra::services::ServiceLocator::Provide(std::move(pEmulatorMemoryContext)); + + auto pDebuggerDetector = std::make_unique(); + ra::services::ServiceLocator::Provide(std::move(pDebuggerDetector)); + auto pAchievementRuntime = std::make_unique(); ra::services::ServiceLocator::Provide(std::move(pAchievementRuntime)); diff --git a/src/services/Search/SearchImpl.cpp b/src/services/Search/SearchImpl.cpp index e8177d262..34ae0b919 100644 --- a/src/services/Search/SearchImpl.cpp +++ b/src/services/Search/SearchImpl.cpp @@ -223,10 +223,10 @@ std::wstring SearchImpl::GetFormattedValue(const SearchResults& pResults, ra::da } bool SearchImpl::UpdateValue(const SearchResults& pResults, SearchResult& pResult, - _Out_ std::wstring* sFormattedValue, const ra::data::context::EmulatorContext& pEmulatorContext) const + _Out_ std::wstring* sFormattedValue, const ra::context::IEmulatorMemoryContext& pMemoryContext) const { const uint32_t nPreviousValue = pResult.nValue; - pResult.nValue = pEmulatorContext.ReadMemory(pResult.nAddress, pResult.nSize); + pResult.nValue = pMemoryContext.ReadMemory(pResult.nAddress, pResult.nSize); if (sFormattedValue) *sFormattedValue = GetFormattedValue(pResults, pResult); diff --git a/src/services/Search/SearchImpl.hh b/src/services/Search/SearchImpl.hh index 52b1a5c2c..cc25a2269 100644 --- a/src/services/Search/SearchImpl.hh +++ b/src/services/Search/SearchImpl.hh @@ -90,7 +90,7 @@ public: // updates the provided result with the current value at the provided real address virtual bool UpdateValue(const SearchResults& pResults, SearchResult& pResult, _Out_ std::wstring* sFormattedValue, - const ra::data::context::EmulatorContext& pEmulatorContext) const; + const ra::context::IEmulatorMemoryContext& pMemoryContext) const; /// /// Determines if the provided search result would appear in pResults if it were freshly populated from diff --git a/src/services/Search/SearchImpl_asciitext.hh b/src/services/Search/SearchImpl_asciitext.hh index 4bc57f33f..05175c181 100644 --- a/src/services/Search/SearchImpl_asciitext.hh +++ b/src/services/Search/SearchImpl_asciitext.hh @@ -163,10 +163,10 @@ public: } bool UpdateValue(const SearchResults&, SearchResult& pResult, - _Out_ std::wstring* sFormattedValue, const ra::data::context::EmulatorContext& pEmulatorContext) const override + _Out_ std::wstring* sFormattedValue, const ra::context::IEmulatorMemoryContext& pMemoryContext) const override { std::array pBuffer; - pEmulatorContext.ReadMemory(pResult.nAddress, &pBuffer.at(0), pBuffer.size()); + pMemoryContext.ReadMemory(pResult.nAddress, &pBuffer.at(0), pBuffer.size()); std::wstring sText; GetASCIIText(sText, pBuffer.data(), pBuffer.size()); diff --git a/src/services/Search/SearchImpl_bitcount.hh b/src/services/Search/SearchImpl_bitcount.hh index fb518b949..8f73bbf83 100644 --- a/src/services/Search/SearchImpl_bitcount.hh +++ b/src/services/Search/SearchImpl_bitcount.hh @@ -23,10 +23,10 @@ protected: } bool UpdateValue(const SearchResults& pResults, SearchResult& pResult, - _Out_ std::wstring* sFormattedValue, const ra::data::context::EmulatorContext& pEmulatorContext) const override + _Out_ std::wstring* sFormattedValue, const ra::context::IEmulatorMemoryContext& pMemoryContext) const override { const unsigned int nPreviousValue = pResult.nValue; - pResult.nValue = pEmulatorContext.ReadMemory(pResult.nAddress, ra::data::Memory::Size::EightBit); + pResult.nValue = pMemoryContext.ReadMemory(pResult.nAddress, ra::data::Memory::Size::EightBit); if (sFormattedValue) *sFormattedValue = GetFormattedValue(pResults, pResult); diff --git a/src/services/SearchResults.cpp b/src/services/SearchResults.cpp index 509490482..e64fd7aa1 100644 --- a/src/services/SearchResults.cpp +++ b/src/services/SearchResults.cpp @@ -3,7 +3,7 @@ #include "RA_Defs.h" #include "util\Log.hh" -#include "data\context\EmulatorContext.hh" +#include "context\IEmulatorMemoryContext.hh" #include "services\ServiceLocator.hh" @@ -147,8 +147,8 @@ void SearchResults::Initialize(ra::data::ByteAddress nAddress, size_t nBytes, Se m_nType = nType; m_pImpl = GetSearchImpl(nType); - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - const auto nTotalMemorySize = pEmulatorContext.TotalMemorySize(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nTotalMemorySize = pMemoryContext.TotalMemorySize(); if (nAddress > nTotalMemorySize) nAddress = 0; if (nBytes + nAddress > nTotalMemorySize) @@ -158,7 +158,7 @@ void SearchResults::Initialize(ra::data::ByteAddress nAddress, size_t nBytes, Se if (nPadding >= nBytes) nBytes = 0; - pEmulatorContext.CaptureMemory(m_vBlocks, nAddress, gsl::narrow_cast(nBytes), nPadding); + pMemoryContext.CaptureMemory(m_vBlocks, nAddress, gsl::narrow_cast(nBytes), nPadding); for (auto& pBlock : m_vBlocks) { @@ -327,9 +327,9 @@ _Use_decl_annotations_ bool SearchResults::Initialize(const SearchResults& srSource, ComparisonType nCompareType, SearchFilterType nFilterType, const std::wstring& sFilterValue) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - auto pReadMemory = [&pEmulatorContext](ra::data::ByteAddress nAddress, uint8_t* pBuffer, size_t nBufferSize) { - pEmulatorContext.ReadMemory(nAddress, pBuffer, nBufferSize); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + auto pReadMemory = [&pMemoryContext](ra::data::ByteAddress nAddress, uint8_t* pBuffer, size_t nBufferSize) { + pMemoryContext.ReadMemory(nAddress, pBuffer, nBufferSize); }; return Initialize(srSource, pReadMemory, nCompareType, nFilterType, sFilterValue); @@ -426,10 +426,10 @@ std::wstring SearchResults::GetFormattedValue(ra::data::ByteAddress nAddress, ra } bool SearchResults::UpdateValue(SearchResult& pResult, - _Out_ std::wstring* sFormattedValue, const ra::data::context::EmulatorContext& pEmulatorContext) const + _Out_ std::wstring* sFormattedValue, const ra::context::IEmulatorMemoryContext& pMemoryContext) const { if (m_pImpl) - return m_pImpl->UpdateValue(*this, pResult, sFormattedValue, pEmulatorContext); + return m_pImpl->UpdateValue(*this, pResult, sFormattedValue, pMemoryContext); if (sFormattedValue) sFormattedValue->clear(); diff --git a/src/services/SearchResults.h b/src/services/SearchResults.h index 1c4e2bf0d..ebae438fb 100644 --- a/src/services/SearchResults.h +++ b/src/services/SearchResults.h @@ -2,11 +2,10 @@ #define SEARCHRESULTS_H #pragma once -#include "data\Types.hh" +#include "data/CapturedMemoryBlock.hh" +#include "data/Types.hh" -#include "data\context\EmulatorContext.hh" - -#include "data\CapturedMemoryBlock.hh" +#include "context/IEmulatorMemoryContext.hh" namespace ra { namespace services { @@ -154,7 +153,7 @@ class SearchResults /// Pointer to a string to populate with a textual representation of the value. [optional] /// true if the value changed, false if not. bool UpdateValue(SearchResult& pResult, _Out_ std::wstring* sFormattedValue, - const ra::data::context::EmulatorContext& pEmulatorContext) const; + const ra::context::IEmulatorMemoryContext& pMemoryContext) const; /// /// Determines if a value compared to its previous value matches the filter. diff --git a/src/services/impl/WindowsDebuggerDetector.cpp b/src/services/impl/WindowsDebuggerDetector.cpp new file mode 100644 index 000000000..600b4f8f5 --- /dev/null +++ b/src/services/impl/WindowsDebuggerDetector.cpp @@ -0,0 +1,73 @@ +#include "WindowsDebuggerDetector.hh" + +#include "util/Log.hh" +#include "util/Strings.hh" + +#include + +namespace ra { +namespace services { +namespace impl { + +static bool IsSuspiciousProcessRunning() +{ + bool bFound = false; + + const HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hSnapshot) + { + PROCESSENTRY32 pe32; + pe32.dwSize = sizeof(PROCESSENTRY32); + if (Process32First(hSnapshot, &pe32)) + { + do + { + if (tcslen_s(pe32.szExeFile) >= 15) + { + std::string sFilename = ra::Narrow(pe32.szExeFile); + ra::StringMakeLowercase(sFilename); + + // cannot reliably detect injection without ObRegisterCallbacks, which requires Vista, + // instead just look for the default process names (it's better than nothing) + // [Cheat Engine.exe, cheatengine-i386.exe, cheatengine-x86_64.exe] + if (sFilename.find("cheat") != std::string::npos && + sFilename.find("engine") != std::string::npos) + { + RA_LOG_WARN("Cheat Engine detected"); + bFound = true; + break; + } + } + } while (Process32Next(hSnapshot, &pe32)); + } + CloseHandle(hSnapshot); + } + + return bFound; +} + +bool WindowsDebuggerDetector::IsDebuggerPresent() const +{ +#ifdef NDEBUG // allow debugger-limited functionality when using a DEBUG build + if (::IsDebuggerPresent()) + { + RA_LOG_WARN("Debugger detected"); + return true; + } + + BOOL bDebuggerPresent; + if (::CheckRemoteDebuggerPresent(GetCurrentProcess(), &bDebuggerPresent) && bDebuggerPresent) + { + RA_LOG_WARN("Remote debugger detected"); + return true; + } +#endif + + // real cheating tools don't register as debuggers (or intercept and override the call) + // also check for known bad agents and assume that the player is using them to cheat + return IsSuspiciousProcessRunning(); +} + +} // namespace impl +} // namespace services +} // namespace ra diff --git a/src/services/impl/WindowsDebuggerDetector.hh b/src/services/impl/WindowsDebuggerDetector.hh new file mode 100644 index 000000000..ccf0e2b14 --- /dev/null +++ b/src/services/impl/WindowsDebuggerDetector.hh @@ -0,0 +1,20 @@ +#ifndef RA_SERVICES_IMPL_DEBUGGER_DETECTOR +#define RA_SERVICES_IMPL_DEBUGGER_DETECTOR + +#include "services/IDebuggerDetector.hh" + +namespace ra { +namespace services { +namespace impl { + +class WindowsDebuggerDetector : public IDebuggerDetector +{ +public: + bool IsDebuggerPresent() const override; +}; + +} // namespace impl +} // namespace services +} // namespace ra + +#endif // !RA_SERVICES_IMPL_DEBUGGER_DETECTOR diff --git a/src/ui/viewmodels/AssetEditorViewModel.hh b/src/ui/viewmodels/AssetEditorViewModel.hh index 3f4303a4c..63cc13982 100644 --- a/src/ui/viewmodels/AssetEditorViewModel.hh +++ b/src/ui/viewmodels/AssetEditorViewModel.hh @@ -5,6 +5,7 @@ #include "TriggerViewModel.hh" #include "data\Types.hh" +#include "data\context\EmulatorContext.hh" #include "data\models\AchievementModel.hh" #include "data\models\AssetModelBase.hh" diff --git a/src/ui/viewmodels/AssetListViewModel.cpp b/src/ui/viewmodels/AssetListViewModel.cpp index 7c3dce86c..4195d5a2d 100644 --- a/src/ui/viewmodels/AssetListViewModel.cpp +++ b/src/ui/viewmodels/AssetListViewModel.cpp @@ -1,5 +1,7 @@ #include "AssetListViewModel.hh" +#include "context\IEmulatorMemoryContext.hh" + #include "data\context\GameContext.hh" #include "data\context\UserContext.hh" @@ -411,8 +413,8 @@ void AssetListViewModel::OnValueChanged(const BoolModelProperty::ChangeArgs& arg auto& pRuntime = ra::services::ServiceLocator::GetMutable(); pRuntime.SetPaused(!args.tNewValue); - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.SetMemoryModified(); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.SetMemoryModified(); } WindowViewModelBase::OnValueChanged(args); diff --git a/src/ui/viewmodels/MemoryBookmarksViewModel.cpp b/src/ui/viewmodels/MemoryBookmarksViewModel.cpp index 961be8943..66ce282cf 100644 --- a/src/ui/viewmodels/MemoryBookmarksViewModel.cpp +++ b/src/ui/viewmodels/MemoryBookmarksViewModel.cpp @@ -4,8 +4,9 @@ #include "RA_Json.h" #include "util\Strings.hh" +#include "context\IEmulatorMemoryContext.hh" + #include "data\Types.hh" -#include "data\context\EmulatorContext.hh" #include "data\models\TriggerValidation.hh" #include "services\AchievementLogicSerializer.hh" @@ -84,8 +85,8 @@ bool MemoryBookmarksViewModel::MemoryBookmarkViewModel::ChangeValue(uint32_t nNe // value changed. if it's frozen, write the frozen value back into memory if (nBehavior == BookmarkBehavior::Frozen) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - pEmulatorContext.WriteMemory(GetAddress(), GetSize(), GetCurrentValueRaw()); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + pMemoryContext.WriteMemory(GetAddress(), GetSize(), GetCurrentValueRaw()); return false; } diff --git a/src/ui/viewmodels/MemoryInspectorViewModel.cpp b/src/ui/viewmodels/MemoryInspectorViewModel.cpp index 7f30a3094..a4bff2ae2 100644 --- a/src/ui/viewmodels/MemoryInspectorViewModel.cpp +++ b/src/ui/viewmodels/MemoryInspectorViewModel.cpp @@ -54,8 +54,8 @@ void MemoryInspectorViewModel::DoFrame() m_pViewer.DoFrame(); const auto nAddress = GetCurrentAddress(); - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - const auto nValue = pEmulatorContext.ReadMemoryByte(nAddress); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nValue = pMemoryContext.ReadMemoryByte(nAddress); SetValue(CurrentAddressValueProperty, nValue); } @@ -465,8 +465,8 @@ void MemoryInspectorViewModel::ToggleBit(int nBit) nValue ^= (1 << nBit); // push the updated value to the emulator - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - pEmulatorContext.WriteMemoryByte(nAddress, gsl::narrow_cast(nValue)); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + pMemoryContext.WriteMemoryByte(nAddress, gsl::narrow_cast(nValue)); // update the local value, which will cause the bits string to get updated SetValue(CurrentAddressValueProperty, nValue); diff --git a/src/ui/viewmodels/MemorySearchViewModel.cpp b/src/ui/viewmodels/MemorySearchViewModel.cpp index 784c2d57c..ecffe119e 100644 --- a/src/ui/viewmodels/MemorySearchViewModel.cpp +++ b/src/ui/viewmodels/MemorySearchViewModel.cpp @@ -168,8 +168,8 @@ MemorySearchViewModel::MemorySearchViewModel() void MemorySearchViewModel::InitializeNotifyTargets() { - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.AddNotifyTarget(*this); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.AddNotifyTarget(*this); OnTotalMemorySizeChanged(); auto& pGameContext = ra::services::ServiceLocator::GetMutable(); @@ -195,7 +195,8 @@ void MemorySearchViewModel::OnTotalMemorySizeChanged() { RebuildPredefinedFilterRanges(); - const auto nTotalBankSize = gsl::narrow_cast(ra::services::ServiceLocator::Get().TotalMemorySize()); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nTotalBankSize = gsl::narrow_cast(pMemoryContext.TotalMemorySize()); SetValue(CanBeginNewSearchProperty, (nTotalBankSize > 0U)); SetValue(TotalMemorySizeProperty, nTotalBankSize); } @@ -427,7 +428,7 @@ void MemorySearchViewModel::DoFrame() return; } - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); { std::lock_guard lock(m_oMutex); @@ -445,7 +446,7 @@ void MemorySearchViewModel::DoFrame() pCurrentResults.pResults.GetMatchingAddress(nIndex++, pResult); const auto nPreviousValue = pResult.nValue; - UpdateResult(pRow, pCurrentResults.pResults, pResult, false, pEmulatorContext); + UpdateResult(pRow, pCurrentResults.pResults, pResult, false, pMemoryContext); // when updating an existing result, check to see if it's been modified and update the tracker if (!pRow.bHasBeenModified && pResult.nValue != nPreviousValue) @@ -852,7 +853,7 @@ void MemorySearchViewModel::UpdateResults() const auto& vmBookmarks = ra::services::ServiceLocator::Get().MemoryBookmarks; const auto& pGameContext = ra::services::ServiceLocator::Get(); - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); const auto* pCodeNotes = pGameContext.Assets().FindCodeNotes(); m_vResults.RemoveNotifyTarget(*this); @@ -889,7 +890,7 @@ void MemorySearchViewModel::UpdateResults() pRow->SetAddress(ra::Widen(sAddress)); - UpdateResult(*pRow, pCurrentResults.pResults, pResult, true, pEmulatorContext); + UpdateResult(*pRow, pCurrentResults.pResults, pResult, true, pMemoryContext); const auto pCodeNote = (pCodeNotes != nullptr) ? pCodeNotes->FindCodeNote(pResult.nAddress, pResult.nSize) : std::wstring(L""); @@ -913,12 +914,12 @@ void MemorySearchViewModel::UpdateResults() void MemorySearchViewModel::UpdateResult(SearchResultViewModel& vmResult, const ra::services::SearchResults& pResults, ra::services::SearchResult& pResult, - bool bForceFilterCheck, const ra::data::context::EmulatorContext& pEmulatorContext) + bool bForceFilterCheck, const ra::context::IEmulatorMemoryContext& pMemoryContext) { std::wstring sFormattedValue; pResult.nValue = vmResult.nCurrentValue; - if (pResults.UpdateValue(pResult, &sFormattedValue, pEmulatorContext) || bForceFilterCheck) + if (pResults.UpdateValue(pResult, &sFormattedValue, pMemoryContext) || bForceFilterCheck) { if (pResults.GetFilterType() == ra::services::SearchFilterType::InitialValue) vmResult.bMatchesFilter = pResults.MatchesFilter(m_vSearchResults.front()->pResults, pResult); diff --git a/src/ui/viewmodels/MemorySearchViewModel.hh b/src/ui/viewmodels/MemorySearchViewModel.hh index 8e516f7ac..b2037b8d2 100644 --- a/src/ui/viewmodels/MemorySearchViewModel.hh +++ b/src/ui/viewmodels/MemorySearchViewModel.hh @@ -2,6 +2,8 @@ #define RA_UI_MEMORYSEARCHVIEWMODEL_H #pragma once +#include "context\IEmulatorMemoryContext.hh" + #include "data\Types.hh" #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" @@ -20,7 +22,7 @@ namespace viewmodels { class MemorySearchViewModel : public ViewModelBase, protected ViewModelCollectionBase::NotifyTarget, - protected ra::data::context::EmulatorContext::NotifyTarget, + protected ra::context::IEmulatorMemoryContext::NotifyTarget, protected ra::data::context::EmulatorContext::DispatchesReadMemory, protected ra::data::context::GameContext::NotifyTarget { @@ -520,7 +522,7 @@ private: void DoApplyFilter(); void UpdateResult(SearchResultViewModel& pRow, const ra::services::SearchResults& pResults, ra::services::SearchResult& pResult, bool bForceFilterCheck, - const ra::data::context::EmulatorContext& pEmulatorContext); + const ra::context::IEmulatorMemoryContext& pMemoryContext); void OnPredefinedFilterRangeChanged(const IntModelProperty::ChangeArgs& args); void OnFilterRangeChanged(); diff --git a/src/ui/viewmodels/MemoryViewerViewModel.cpp b/src/ui/viewmodels/MemoryViewerViewModel.cpp index 6abecb6f4..d77f6f4ad 100644 --- a/src/ui/viewmodels/MemoryViewerViewModel.cpp +++ b/src/ui/viewmodels/MemoryViewerViewModel.cpp @@ -124,10 +124,10 @@ MemoryViewerViewModel::MemoryViewerViewModel() void MemoryViewerViewModel::InitializeNotifyTargets() { - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.AddNotifyTarget(*this); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.AddNotifyTarget(*this); - m_nTotalMemorySize = gsl::narrow(pEmulatorContext.TotalMemorySize()); + m_nTotalMemorySize = gsl::narrow(pMemoryContext.TotalMemorySize()); auto& pGameContext = ra::services::ServiceLocator::GetMutable(); pGameContext.AddNotifyTarget(*this); @@ -137,8 +137,8 @@ void MemoryViewerViewModel::InitializeNotifyTargets() void MemoryViewerViewModel::InitializeFixedViewer(ra::data::ByteAddress nAddress) { - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - m_nTotalMemorySize = gsl::narrow(pEmulatorContext.TotalMemorySize()); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + m_nTotalMemorySize = gsl::narrow(pMemoryContext.TotalMemorySize()); m_bReadOnly = true; m_bAddressFixed = true; @@ -295,11 +295,11 @@ void MemoryViewerViewModel::UpdateInvalidRegions() const auto nFirstAddress = GetFirstAddress(); const auto nVisibleBytes = std::min(m_nTotalMemorySize - nFirstAddress, nVisibleLines * 16); - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - if (pEmulatorContext.HasInvalidRegions()) + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + if (pMemoryContext.HasInvalidRegions()) { for (unsigned i = 0; i < nVisibleBytes; ++i) - m_pInvalid[i] = pEmulatorContext.IsValidAddress(nFirstAddress + i) ? 0 : 1; + m_pInvalid[i] = pMemoryContext.IsValidAddress(nFirstAddress + i) ? 0 : 1; } else { @@ -468,8 +468,8 @@ void MemoryViewerViewModel::ReadMemory(ra::data::ByteAddress nFirstAddress, int return; } - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - pEmulatorContext.ReadMemory(nFirstAddress, m_pMemory, gsl::narrow_cast(nNumVisibleLines) * 16); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + pMemoryContext.ReadMemory(nFirstAddress, m_pMemory, gsl::narrow_cast(nNumVisibleLines) * 16); UpdateInvalidRegions(); UpdateColors(); @@ -705,8 +705,8 @@ void MemoryViewerViewModel::IncreaseCurrentValue(uint32_t nModifier) DispatchMemoryRead([this, nModifier]() { const auto nAddress = GetAddress(); const auto nSize = GetSize(); - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - auto nMem = pEmulatorContext.ReadMemory(nAddress, nSize); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + auto nMem = pMemoryContext.ReadMemory(nAddress, nSize); auto const nMaxValue = ra::data::Memory::SizeMax(nSize); if (nMem >= nMaxValue) @@ -717,7 +717,7 @@ void MemoryViewerViewModel::IncreaseCurrentValue(uint32_t nModifier) else nMem += nModifier; - pEmulatorContext.WriteMemory(nAddress, nSize, nMem); + pMemoryContext.WriteMemory(nAddress, nSize, nMem); }); } @@ -729,8 +729,8 @@ void MemoryViewerViewModel::DecreaseCurrentValue(uint32_t nModifier) DispatchMemoryRead([this, nModifier]() { const auto nAddress = GetAddress(); const auto nSize = GetSize(); - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - auto nMem = pEmulatorContext.ReadMemory(nAddress, nSize); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + auto nMem = pMemoryContext.ReadMemory(nAddress, nSize); if (nMem == 0) return; @@ -740,7 +740,7 @@ void MemoryViewerViewModel::DecreaseCurrentValue(uint32_t nModifier) else nMem -= nModifier; - pEmulatorContext.WriteMemory(nAddress, nSize, nMem); + pMemoryContext.WriteMemory(nAddress, nSize, nMem); }); } @@ -833,9 +833,9 @@ void MemoryViewerViewModel::OnCodeNoteChanged(ra::data::ByteAddress nAddress, co void MemoryViewerViewModel::OnTotalMemorySizeChanged() { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); const bool bTotalMemorySizeWasZero = (m_nTotalMemorySize == 0); - m_nTotalMemorySize = gsl::narrow_cast(pEmulatorContext.TotalMemorySize()); + m_nTotalMemorySize = gsl::narrow_cast(pMemoryContext.TotalMemorySize()); if (m_nTotalMemorySize == 0) { @@ -1115,8 +1115,8 @@ bool MemoryViewerViewModel::OnChar(char c) m_nNeedsRedraw |= REDRAW_MEMORY; // push the updated value to the emulator - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.WriteMemoryByte(nAddress, nByte); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.WriteMemoryByte(nAddress, nByte); // advance the cursor to the next nibble AdvanceCursor(); @@ -1147,8 +1147,8 @@ void MemoryViewerViewModel::DoFrame() const auto nVisibleLines = GetNumVisibleLines(); Expects(nVisibleLines < MaxLines); - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - pEmulatorContext.ReadMemory(nAddress, pMemory, gsl::narrow_cast(nVisibleLines) * 16); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + pMemoryContext.ReadMemory(nAddress, pMemory, gsl::narrow_cast(nVisibleLines) * 16); constexpr int nStride = 8; for (int nIndex = 0; nIndex < nVisibleLines * 16; nIndex += nStride) diff --git a/src/ui/viewmodels/MemoryViewerViewModel.hh b/src/ui/viewmodels/MemoryViewerViewModel.hh index d4a5cc5e4..4db303a2c 100644 --- a/src/ui/viewmodels/MemoryViewerViewModel.hh +++ b/src/ui/viewmodels/MemoryViewerViewModel.hh @@ -2,6 +2,8 @@ #define RA_UI_MEMORYVIEWERVIEWMODEL_H #pragma once +#include "context\IEmulatorMemoryContext.hh" + #include "data\Types.hh" #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" @@ -18,7 +20,7 @@ namespace viewmodels { class MemoryViewerViewModel : public ViewModelBase, protected ra::data::context::GameContext::NotifyTarget, - protected ra::data::context::EmulatorContext::NotifyTarget, + protected ra::context::IEmulatorMemoryContext::NotifyTarget, protected ra::data::context::EmulatorContext::DispatchesReadMemory { public: diff --git a/src/ui/viewmodels/MemoryWatchListViewModel.cpp b/src/ui/viewmodels/MemoryWatchListViewModel.cpp index de14c331f..a748df864 100644 --- a/src/ui/viewmodels/MemoryWatchListViewModel.cpp +++ b/src/ui/viewmodels/MemoryWatchListViewModel.cpp @@ -63,8 +63,8 @@ void MemoryWatchListViewModel::InitializeNotifyTargets(bool syncNotes) pGameContext.AddNotifyTarget(*this); } - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.AddNotifyTarget(*this); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.AddNotifyTarget(*this); } void MemoryWatchListViewModel::OnCodeNoteMoved(ra::data::ByteAddress nOldAddress, ra::data::ByteAddress nNewAddress, const std::wstring& sNote) @@ -112,15 +112,15 @@ void MemoryWatchListViewModel::OnByteWritten(ra::data::ByteAddress nAddress, uin void MemoryWatchListViewModel::DoFrame() { // don't watch for memory changes while we're processing the list. frozen bookmarks may write memory - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.RemoveNotifyTarget(*this); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.RemoveNotifyTarget(*this); m_vItems.BeginUpdate(); for (auto& pItem : m_vItems) pItem.DoFrame(); m_vItems.EndUpdate(); - pEmulatorContext.AddNotifyTarget(*this); + pMemoryContext.AddNotifyTarget(*this); } void MemoryWatchListViewModel::OnViewModelBoolValueChanged(gsl::index nIndex, const BoolModelProperty::ChangeArgs& args) @@ -132,14 +132,14 @@ void MemoryWatchListViewModel::OnViewModelBoolValueChanged(gsl::index nIndex, co } else if (args.Property == MemoryWatchViewModel::IsWritingMemoryProperty) { - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); if (args.tNewValue) { - pEmulatorContext.RemoveNotifyTarget(*this); + pMemoryContext.RemoveNotifyTarget(*this); } else { - pEmulatorContext.AddNotifyTarget(*this); + pMemoryContext.AddNotifyTarget(*this); const auto* pItem = m_vItems.GetItemAt(nIndex); Expects(pItem != nullptr); diff --git a/src/ui/viewmodels/MemoryWatchListViewModel.hh b/src/ui/viewmodels/MemoryWatchListViewModel.hh index dcfbf2c31..a5b8af9f9 100644 --- a/src/ui/viewmodels/MemoryWatchListViewModel.hh +++ b/src/ui/viewmodels/MemoryWatchListViewModel.hh @@ -2,6 +2,8 @@ #define RA_UI_MEMORYWATCHLISTVIEWMODEL_H #pragma once +#include "context\IEmulatorMemoryContext.hh" + #include "data\Types.hh" #include "data\context\EmulatorContext.hh" #include "data\context\GameContext.hh" @@ -18,7 +20,7 @@ namespace viewmodels { class MemoryWatchListViewModel : public ViewModelBase, protected ra::data::context::GameContext::NotifyTarget, - protected ra::data::context::EmulatorContext::NotifyTarget, + protected ra::context::IEmulatorMemoryContext::NotifyTarget, protected ra::data::context::EmulatorContext::DispatchesReadMemory, protected ra::ui::ViewModelCollectionBase::NotifyTarget { diff --git a/src/ui/viewmodels/MemoryWatchViewModel.cpp b/src/ui/viewmodels/MemoryWatchViewModel.cpp index 5f2d6b43c..0bee09dcc 100644 --- a/src/ui/viewmodels/MemoryWatchViewModel.cpp +++ b/src/ui/viewmodels/MemoryWatchViewModel.cpp @@ -247,12 +247,12 @@ uint32_t MemoryWatchViewModel::ReadValue() // updated, proceeed to logic below to do the special processing. } - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); if (m_nSize == ra::data::Memory::Size::Text) { // only have 32 bits to store the value in. generate a hash for the string std::array pBuffer; - pEmulatorContext.ReadMemory(m_nAddress, &pBuffer.at(0), pBuffer.size() - 1); + pMemoryContext.ReadMemory(m_nAddress, &pBuffer.at(0), pBuffer.size() - 1); pBuffer.at(pBuffer.size() - 1) = '\0'; const char* pText; @@ -262,7 +262,7 @@ uint32_t MemoryWatchViewModel::ReadValue() return ra::StringHash(sText); } - return pEmulatorContext.ReadMemory(m_nAddress, m_nSize); + return pMemoryContext.ReadMemory(m_nAddress, m_nSize); } void MemoryWatchViewModel::EndInitialization() @@ -283,7 +283,7 @@ void MemoryWatchViewModel::EndInitialization() bool MemoryWatchViewModel::SetCurrentValue(const std::wstring& sValue, _Out_ std::wstring& sError) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); const auto nAddress = m_nAddress; unsigned nValue = 0; @@ -317,7 +317,7 @@ bool MemoryWatchViewModel::SetCurrentValue(const std::wstring& sValue, _Out_ std // use the IsWritingMemoryProperty to disable the event handler in the list // while we write the memory so it doesn't try to sync the value back here SetValue(IsWritingMemoryProperty, true); - pEmulatorContext.WriteMemory(nAddress, m_nSize, nValue); + pMemoryContext.WriteMemory(nAddress, m_nSize, nValue); SetValue(IsWritingMemoryProperty, false); // update the fields dependent on m_nValue diff --git a/src/ui/viewmodels/PointerFinderViewModel.cpp b/src/ui/viewmodels/PointerFinderViewModel.cpp index ce9a129e9..07081f3b3 100644 --- a/src/ui/viewmodels/PointerFinderViewModel.cpp +++ b/src/ui/viewmodels/PointerFinderViewModel.cpp @@ -58,7 +58,8 @@ void PointerFinderViewModel::StateViewModel::ToggleCapture() void PointerFinderViewModel::StateViewModel::Capture() { - if (ra::services::ServiceLocator::Get().TotalMemorySize() == 0) + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + if (pMemoryContext.TotalMemorySize() == 0) { ra::ui::viewmodels::MessageBoxViewModel::ShowErrorMessage(L"No game loaded.", L"Cannot capture memory without a loaded game."); return; @@ -89,8 +90,8 @@ void PointerFinderViewModel::StateViewModel::Capture() } DispatchMemoryRead([this]() { - const auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - const auto nMemorySize = gsl::narrow(pEmulatorContext.TotalMemorySize()); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nMemorySize = gsl::narrow(pMemoryContext.TotalMemorySize()); m_pCapture.reset(new ra::services::SearchResults()); m_pCapture->Initialize(0, nMemorySize, m_pOwner->GetSearchType()); diff --git a/src/ui/viewmodels/PointerInspectorViewModel.cpp b/src/ui/viewmodels/PointerInspectorViewModel.cpp index 0aa3eeef8..ba15c49ed 100644 --- a/src/ui/viewmodels/PointerInspectorViewModel.cpp +++ b/src/ui/viewmodels/PointerInspectorViewModel.cpp @@ -3,6 +3,7 @@ #include "RA_Defs.h" #include "context\IConsoleContext.hh" +#include "context\IEmulatorMemoryContext.hh" #include "services\AchievementLogicSerializer.hh" #include "services\IClipboard.hh" @@ -163,16 +164,16 @@ void PointerInspectorViewModel::OnEndGameLoad() m_vPointers.BeginUpdate(); m_vPointers.Clear(); - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); const auto* pCodeNotes = pGameContext.Assets().FindCodeNotes(); if (pCodeNotes != nullptr) { pCodeNotes->EnumerateCodeNotes( - [this, &pEmulatorContext](ra::data::ByteAddress nAddress, const ra::data::models::CodeNoteModel& pNote) { + [this, &pMemoryContext](ra::data::ByteAddress nAddress, const ra::data::models::CodeNoteModel& pNote) { if (pNote.IsPointer()) { m_vPointers.Add(nAddress, - ra::StringPrintf(L"%s | %s", pEmulatorContext.FormatAddress(nAddress), + ra::StringPrintf(L"%s | %s", pMemoryContext.FormatAddress(nAddress), ra::data::models::CodeNoteModel::TrimSize( pNote.GetPointerDescription(), false))); } @@ -238,10 +239,10 @@ void PointerInspectorViewModel::UpdatePointerVisibility(ra::data::ByteAddress nA if (bIsPointerNote) { // valid pointer note not found, insert it - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); m_vPointers.BeginUpdate(); m_vPointers.Add(nAddress, - ra::StringPrintf(L"%s | %s", pEmulatorContext.FormatAddress(nAddress), + ra::StringPrintf(L"%s | %s", pMemoryContext.FormatAddress(nAddress), ra::data::models::CodeNoteModel::TrimSize(pNote->GetPointerDescription(), false))); m_vPointers.MoveItem(nCount, nIndex); m_vPointers.EndUpdate(); @@ -850,8 +851,8 @@ void PointerInspectorViewModel::UpdatePointerChainRowColor(PointerInspectorViewM if (nMemSize == ra::data::Memory::Size::TwentyFourBit) nMemSize = ra::data::Memory::Size::ThirtyTwoBit; - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - const auto nRawPointer = pEmulatorContext.ReadMemory(pPointer.GetAddress(), nMemSize); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nRawPointer = pMemoryContext.ReadMemory(pPointer.GetAddress(), nMemSize); bValid = (pConsoleContext.ByteAddressFromRealAddress(nRawPointer) != 0xFFFFFFFF); } else diff --git a/src/ui/viewmodels/TriggerViewModel.hh b/src/ui/viewmodels/TriggerViewModel.hh index 1a56b82a1..8c2ef4ce9 100644 --- a/src/ui/viewmodels/TriggerViewModel.hh +++ b/src/ui/viewmodels/TriggerViewModel.hh @@ -2,6 +2,8 @@ #define RA_UI_TRIGGERVIEWMODEL_H #pragma once +#include "data\context\EmulatorContext.hh" + #include "data\models\CapturedTriggerHits.hh" #include "ui\ViewModelBase.hh" diff --git a/src/ui/win32/CodeNotesDialog.cpp b/src/ui/win32/CodeNotesDialog.cpp index 41b925b82..d37b8656f 100644 --- a/src/ui/win32/CodeNotesDialog.cpp +++ b/src/ui/win32/CodeNotesDialog.cpp @@ -55,16 +55,16 @@ void CodeNotesDialog::Presenter::OnClosed() noexcept { m_pDialog.reset(); } CodeNotesDialog::CodeNotesGridBinding::CodeNotesGridBinding(ViewModelBase& vmViewModel) : ra::ui::win32::bindings::MultiLineGridBinding(vmViewModel) { - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.AddNotifyTarget(*this); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.AddNotifyTarget(*this); } CodeNotesDialog::CodeNotesGridBinding::~CodeNotesGridBinding() { if (ra::services::ServiceLocator::Exists()) { - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.RemoveNotifyTarget(*this); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.RemoveNotifyTarget(*this); } } diff --git a/src/ui/win32/CodeNotesDialog.hh b/src/ui/win32/CodeNotesDialog.hh index e889ddb39..61296b976 100644 --- a/src/ui/win32/CodeNotesDialog.hh +++ b/src/ui/win32/CodeNotesDialog.hh @@ -2,7 +2,7 @@ #define RA_UI_WIN32_DLG_CODENOTES_H #pragma once -#include "data/context/EmulatorContext.hh" +#include "context/IEmulatorMemoryContext.hh" #include "ui/viewmodels/CodeNotesViewModel.hh" @@ -45,7 +45,7 @@ protected: private: class CodeNotesGridBinding : public ra::ui::win32::bindings::MultiLineGridBinding, - protected ra::data::context::EmulatorContext::NotifyTarget + protected ra::context::IEmulatorMemoryContext::NotifyTarget { public: explicit CodeNotesGridBinding(ViewModelBase& vmViewModel); diff --git a/src/ui/win32/MemoryBookmarksDialog.cpp b/src/ui/win32/MemoryBookmarksDialog.cpp index 33fb16fb1..a3a340b4e 100644 --- a/src/ui/win32/MemoryBookmarksDialog.cpp +++ b/src/ui/win32/MemoryBookmarksDialog.cpp @@ -57,16 +57,16 @@ void MemoryBookmarksDialog::Presenter::OnClosed() noexcept { m_pDialog.reset(); MemoryBookmarksDialog::BookmarksGridBinding::BookmarksGridBinding(ViewModelBase& vmViewModel) : ra::ui::win32::bindings::GridBinding(vmViewModel) { - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.AddNotifyTarget(*this); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.AddNotifyTarget(*this); } MemoryBookmarksDialog::BookmarksGridBinding::~BookmarksGridBinding() { - if (ra::services::ServiceLocator::Exists()) + if (ra::services::ServiceLocator::Exists()) { - auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - pEmulatorContext.RemoveNotifyTarget(*this); + auto& pMemoryContext = ra::services::ServiceLocator::GetMutable(); + pMemoryContext.RemoveNotifyTarget(*this); } } diff --git a/src/ui/win32/MemoryBookmarksDialog.hh b/src/ui/win32/MemoryBookmarksDialog.hh index a118be233..f929fb68b 100644 --- a/src/ui/win32/MemoryBookmarksDialog.hh +++ b/src/ui/win32/MemoryBookmarksDialog.hh @@ -2,7 +2,7 @@ #define RA_UI_WIN32_DLG_MEMORYBOOKMARKS_H #pragma once -#include "data/context/EmulatorContext.hh" +#include "context/IEmulatorMemoryContext.hh" #include "ui/viewmodels/MemoryBookmarksViewModel.hh" #include "ui/win32/bindings/GridBinding.hh" @@ -41,7 +41,7 @@ protected: private: class BookmarksGridBinding : public ra::ui::win32::bindings::GridBinding, - protected ra::data::context::EmulatorContext::NotifyTarget + protected ra::context::IEmulatorMemoryContext::NotifyTarget { public: explicit BookmarksGridBinding(ViewModelBase& vmViewModel); diff --git a/src/ui/win32/MemoryInspectorDialog.cpp b/src/ui/win32/MemoryInspectorDialog.cpp index f5c67806a..c63811822 100644 --- a/src/ui/win32/MemoryInspectorDialog.cpp +++ b/src/ui/win32/MemoryInspectorDialog.cpp @@ -481,9 +481,9 @@ INT_PTR CALLBACK MemoryInspectorDialog::DialogProc(HWND hDlg, UINT uMsg, WPARAM if (wParam != 1) break; - // ignore if memory not avaialble - const auto& pEmulatorContext = ra::services::ServiceLocator::GetMutable(); - if (pEmulatorContext.TotalMemorySize() == 0) + // ignore if memory not available + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + if (pMemoryContext.TotalMemorySize() == 0) break; // ignore if not 8-bit mode diff --git a/src/ui/win32/bindings/GridAddressColumnBinding.cpp b/src/ui/win32/bindings/GridAddressColumnBinding.cpp index 326b8d13e..de7d50f2b 100644 --- a/src/ui/win32/bindings/GridAddressColumnBinding.cpp +++ b/src/ui/win32/bindings/GridAddressColumnBinding.cpp @@ -38,8 +38,8 @@ unsigned GridAddressColumnBinding::CalculateWidth() { unsigned nMaxChars = 6; // 0x1234 - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - const auto nTotalMemorySize = pEmulatorContext.TotalMemorySize(); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nTotalMemorySize = pMemoryContext.TotalMemorySize(); if (nTotalMemorySize > 0x1000000) nMaxChars = 10; // 0x12345678 else if (nTotalMemorySize > 0x10000) diff --git a/src/ui/win32/bindings/MemoryViewerControlBinding.cpp b/src/ui/win32/bindings/MemoryViewerControlBinding.cpp index b95d23d94..035714986 100644 --- a/src/ui/win32/bindings/MemoryViewerControlBinding.cpp +++ b/src/ui/win32/bindings/MemoryViewerControlBinding.cpp @@ -205,8 +205,8 @@ bool MemoryViewerControlBinding::HandleNavigation(UINT nChar) case VK_END: if (bControlHeld) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - const auto nTotalBytes = gsl::narrow(pEmulatorContext.TotalMemorySize()); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + const auto nTotalBytes = gsl::narrow(pMemoryContext.TotalMemorySize()); m_pViewModel.SetFirstAddress(nTotalBytes & ~0x0F); m_pViewModel.SetAddress(nTotalBytes - 1); diff --git a/tests/Exports_Tests.cpp b/tests/Exports_Tests.cpp index 521b273c9..b9c02aeaa 100644 --- a/tests/Exports_Tests.cpp +++ b/tests/Exports_Tests.cpp @@ -7,10 +7,10 @@ #include "RA_Resource.h" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockAudioSystem.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj index 7b6f5d32f..2b9d68d61 100644 --- a/tests/RA_Integration.Tests.vcxproj +++ b/tests/RA_Integration.Tests.vcxproj @@ -173,6 +173,7 @@ + diff --git a/tests/RA_Integration.Tests.vcxproj.filters b/tests/RA_Integration.Tests.vcxproj.filters index 81bfe992d..a079cdcaa 100644 --- a/tests/RA_Integration.Tests.vcxproj.filters +++ b/tests/RA_Integration.Tests.vcxproj.filters @@ -465,6 +465,9 @@ Code + + Code + diff --git a/tests/data/context/EmulatorContext_Tests.cpp b/tests/data/context/EmulatorContext_Tests.cpp index b647b4c01..adc4367b2 100644 --- a/tests/data/context/EmulatorContext_Tests.cpp +++ b/tests/data/context/EmulatorContext_Tests.cpp @@ -5,12 +5,13 @@ #include "tests\data\DataAsserts.hh" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\services\mocks\MockHttpRequester.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockGameContext.hh" @@ -34,6 +35,7 @@ TEST_CLASS(EmulatorContext_Tests) { public: ra::api::mocks::MockServer mockServer; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::context::mocks::MockRcClient mockRcClient; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; @@ -89,19 +91,6 @@ TEST_CLASS(EmulatorContext_Tests) ra::services::ServiceLocator::ServiceOverride m_Override; }; - class EmulatorContextNotifyHarness : public EmulatorContext::NotifyTarget - { - public: - void OnByteWritten(ra::data::ByteAddress nAddress, uint8_t nValue) noexcept override - { - nLastByteWrittenAddress = nAddress; - nLastByteWritten = nValue; - } - - ra::data::ByteAddress nLastByteWrittenAddress = 0xFFFFFFFFU; - uint8_t nLastByteWritten = 0xFF; - }; - public: TEST_METHOD(TestClientName) { @@ -1202,527 +1191,6 @@ TEST_CLASS(EmulatorContext_Tests) return nBytes; } - static void WriteMemory0(uint32_t nAddress, uint8_t nValue) noexcept { memory.at(nAddress) = nValue; } - static void WriteMemory1(uint32_t nAddress, uint8_t nValue) noexcept { memory.at(gsl::narrow_cast(nAddress) + 10) = nValue; } - static void WriteMemory2(uint32_t nAddress, uint8_t nValue) noexcept { memory.at(gsl::narrow_cast(nAddress) + 20) = nValue; } - static void WriteMemory3(uint32_t nAddress, uint8_t nValue) noexcept { memory.at(gsl::narrow_cast(nAddress) + 30) = nValue; } - - static void InitializeMemory() - { - for (size_t i = 0; i < memory.size(); ++i) - memory.at(i) = gsl::narrow_cast(i); - } - - TEST_METHOD(TestIsValidAddress) - { - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); - - Assert::IsTrue(emulator.IsValidAddress(12U)); - Assert::IsTrue(emulator.IsValidAddress(25U)); - Assert::IsTrue(emulator.IsValidAddress(29U)); - Assert::IsFalse(emulator.IsValidAddress(30U)); - } - - TEST_METHOD(TestReadMemoryByte) - { - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); - - Assert::AreEqual(12, static_cast(emulator.ReadMemoryByte(12U))); - Assert::AreEqual(25, static_cast(emulator.ReadMemoryByte(25U))); - Assert::AreEqual(4, static_cast(emulator.ReadMemoryByte(4U))); - Assert::AreEqual(29, static_cast(emulator.ReadMemoryByte(29U))); - Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(30U))); - } - - TEST_METHOD(TestAddMemoryBlocksOutOfOrder) - { - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); - - Assert::AreEqual(12, static_cast(emulator.ReadMemoryByte(12U))); - Assert::AreEqual(25, static_cast(emulator.ReadMemoryByte(25U))); - Assert::AreEqual(4, static_cast(emulator.ReadMemoryByte(4U))); - Assert::AreEqual(29, static_cast(emulator.ReadMemoryByte(29U))); - Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(30U))); - } - - TEST_METHOD(TestAddMemoryBlockDoesNotOverwrite) - { - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - emulator.AddMemoryBlock(0, 20, &ReadMemory3, &WriteMemory3); - Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); - - Assert::AreEqual(12, static_cast(emulator.ReadMemoryByte(12U))); - Assert::AreEqual(25, static_cast(emulator.ReadMemoryByte(25U))); - Assert::AreEqual(4, static_cast(emulator.ReadMemoryByte(4U))); - Assert::AreEqual(29, static_cast(emulator.ReadMemoryByte(29U))); - Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(30U))); - } - - TEST_METHOD(TestClearMemoryBlocks) - { - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - emulator.ClearMemoryBlocks(); - emulator.AddMemoryBlock(0, 20, &ReadMemory3, &WriteMemory3); - Assert::AreEqual({ 20U }, emulator.TotalMemorySize()); - - Assert::AreEqual(32, static_cast(emulator.ReadMemoryByte(2U))); - Assert::AreEqual(41, static_cast(emulator.ReadMemoryByte(11U))); - Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(55U))); - } - - TEST_METHOD(TestInvalidMemoryBlock) - { - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, nullptr, nullptr); - emulator.AddMemoryBlock(2, 10, &ReadMemory3, &WriteMemory3); - Assert::AreEqual({ 40U }, emulator.TotalMemorySize()); - - Assert::IsTrue(emulator.IsValidAddress(12U)); - Assert::IsTrue(emulator.IsValidAddress(19U)); - Assert::IsFalse(emulator.IsValidAddress(20U)); - Assert::IsFalse(emulator.IsValidAddress(29U)); - Assert::IsTrue(emulator.IsValidAddress(30U)); - Assert::IsTrue(emulator.IsValidAddress(39U)); - Assert::IsFalse(emulator.IsValidAddress(40U)); - - Assert::AreEqual(12, static_cast(emulator.ReadMemoryByte(12U))); - Assert::AreEqual(19, static_cast(emulator.ReadMemoryByte(19U))); - Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(20U))); - Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(29U))); - Assert::AreEqual(30, static_cast(emulator.ReadMemoryByte(30U))); - Assert::AreEqual(39, static_cast(emulator.ReadMemoryByte(39U))); - Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(40U))); - } - - TEST_METHOD(TestReadMemory) - { - memory.at(4) = 0xA8; - memory.at(5) = 0x00; - memory.at(6) = 0x37; - memory.at(7) = 0x2E; - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - - // ReadMemory calls ReadMemoryByte for small sizes - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit0))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit1))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit2))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit3))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit4))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit5))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit6))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit7))); - Assert::AreEqual(3, static_cast(emulator.ReadMemory(4U, Memory::Size::BitCount))); - Assert::AreEqual(8, static_cast(emulator.ReadMemory(4U, Memory::Size::NibbleLower))); - Assert::AreEqual(10, static_cast(emulator.ReadMemory(4U, Memory::Size::NibbleUpper))); - Assert::AreEqual(0xA8, static_cast(emulator.ReadMemory(4U, Memory::Size::EightBit))); - Assert::AreEqual(0xA8, static_cast(emulator.ReadMemory(4U, Memory::Size::SixteenBit))); - Assert::AreEqual(0x2E37, static_cast(emulator.ReadMemory(6U, Memory::Size::SixteenBit))); - Assert::AreEqual(0x2E3700, static_cast(emulator.ReadMemory(5U, Memory::Size::TwentyFourBit))); - Assert::AreEqual(0x2E3700A8, static_cast(emulator.ReadMemory(4U, Memory::Size::ThirtyTwoBit))); - Assert::AreEqual(0x372E, static_cast(emulator.ReadMemory(6U, Memory::Size::SixteenBitBigEndian))); - Assert::AreEqual(0x00372E, static_cast(emulator.ReadMemory(5U, Memory::Size::TwentyFourBitBigEndian))); - Assert::AreEqual(0xA800372EU, emulator.ReadMemory(4U, Memory::Size::ThirtyTwoBitBigEndian)); - - memory.at(4) ^= 0xFF; // toggle all bits and verify again - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit0))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit1))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit2))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit3))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit4))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit5))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit6))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit7))); - Assert::AreEqual(5, static_cast(emulator.ReadMemory(4U, Memory::Size::BitCount))); - Assert::AreEqual(7, static_cast(emulator.ReadMemory(4U, Memory::Size::NibbleLower))); - Assert::AreEqual(5, static_cast(emulator.ReadMemory(4U, Memory::Size::NibbleUpper))); - Assert::AreEqual(0x57, static_cast(emulator.ReadMemory(4U, Memory::Size::EightBit))); - } - - TEST_METHOD(TestReadMemoryBlock) - { - for (size_t i = 0; i < memory.size(); i++) - memory.at(i) = gsl::narrow_cast(i); - - memory.at(4) = 0xA8; - memory.at(5) = 0x00; - memory.at(6) = 0x37; - memory.at(7) = 0x2E; - - memory.at(14) = 0x57; - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory1, &WriteMemory0); // purposefully use ReadMemory1 to detect using byte reader for non-byte reads - emulator.AddMemoryBlockReader(0, &ReadMemoryBlock0); - - // ReadMemory calls ReadMemoryByte for small sizes - should call ReadMemory1 ($4 => $14) - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit0))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit1))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit2))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit3))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit4))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit5))); - Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit6))); - Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, Memory::Size::Bit7))); - Assert::AreEqual(5, static_cast(emulator.ReadMemory(4U, Memory::Size::BitCount))); - Assert::AreEqual(7, static_cast(emulator.ReadMemory(4U, Memory::Size::NibbleLower))); - Assert::AreEqual(5, static_cast(emulator.ReadMemory(4U, Memory::Size::NibbleUpper))); - Assert::AreEqual(0x57, static_cast(emulator.ReadMemory(4U, Memory::Size::EightBit))); - - // sizes larger than 8 bits should use the block reader ($4 => $4) - Assert::AreEqual(0xA8, static_cast(emulator.ReadMemory(4U, Memory::Size::SixteenBit))); - Assert::AreEqual(0x2E37, static_cast(emulator.ReadMemory(6U, Memory::Size::SixteenBit))); - Assert::AreEqual(0x2E3700, static_cast(emulator.ReadMemory(5U, Memory::Size::TwentyFourBit))); - Assert::AreEqual(0x2E3700A8, static_cast(emulator.ReadMemory(4U, Memory::Size::ThirtyTwoBit))); - Assert::AreEqual(0x372E, static_cast(emulator.ReadMemory(6U, Memory::Size::SixteenBitBigEndian))); - Assert::AreEqual(0x00372E, static_cast(emulator.ReadMemory(5U, Memory::Size::TwentyFourBitBigEndian))); - Assert::AreEqual(0xA800372EU, emulator.ReadMemory(4U, Memory::Size::ThirtyTwoBitBigEndian)); - - // test the block reader directly - uint8_t buffer[16]; - emulator.ReadMemory(0U, buffer, sizeof(buffer)); - for (size_t i = 0; i < sizeof(buffer); i++) - Assert::AreEqual(gsl::at(buffer, i), memory.at(i)); - - emulator.ReadMemory(4U, buffer, 1); - Assert::AreEqual(gsl::at(buffer, 0), memory.at(4)); - Assert::AreEqual(gsl::at(buffer, 1), memory.at(1)); - } - - TEST_METHOD(TestReadMemoryBuffer) - { - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); - - uint8_t buffer[32]; - - // simple read within a block - emulator.ReadMemory(6U, buffer, 12); - Assert::IsTrue(memcmp(buffer, &memory.at(6), 11) == 0); - - // read across block - emulator.ReadMemory(19U, buffer, 4); - Assert::IsTrue(memcmp(buffer, &memory.at(19), 4) == 0); - - // read end of block - emulator.ReadMemory(13U, buffer, 7); - Assert::IsTrue(memcmp(buffer, &memory.at(13), 7) == 0); - - // read start of block - emulator.ReadMemory(20U, buffer, 5); - Assert::IsTrue(memcmp(buffer, &memory.at(20), 5) == 0); - - // read passed end of total memory - emulator.ReadMemory(28U, buffer, 4); - Assert::AreEqual(28, static_cast(buffer[0])); - Assert::AreEqual(29, static_cast(buffer[1])); - Assert::AreEqual(0, static_cast(buffer[2])); - Assert::AreEqual(0, static_cast(buffer[3])); - - // read outside memory - buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xFF; - emulator.ReadMemory(37U, buffer, 4); - Assert::AreEqual(0, static_cast(buffer[0])); - Assert::AreEqual(0, static_cast(buffer[1])); - Assert::AreEqual(0, static_cast(buffer[2])); - Assert::AreEqual(0, static_cast(buffer[3])); - } - - TEST_METHOD(TestReadMemoryBufferInvalidMemoryBlock) - { - constexpr uint8_t zero = 0; - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, nullptr, nullptr); - emulator.AddMemoryBlock(2, 10, &ReadMemory3, &WriteMemory3); - Assert::AreEqual({ 40U }, emulator.TotalMemorySize()); - - uint8_t buffer[32]; - - // simple read within valid block - emulator.ReadMemory(6U, buffer, 12); - Assert::IsTrue(memcmp(buffer, &memory.at(6), 11) == 0); - - // simple read within invalid block - emulator.ReadMemory(22U, buffer, 4); - Assert::AreEqual(zero, buffer[0]); - Assert::AreEqual(zero, buffer[1]); - Assert::AreEqual(zero, buffer[2]); - Assert::AreEqual(zero, buffer[3]); - - // read across block (valid -> invalid) - emulator.ReadMemory(16U, buffer, 8); - Assert::AreEqual(memory.at(16), buffer[0]); - Assert::AreEqual(memory.at(17), buffer[1]); - Assert::AreEqual(memory.at(18), buffer[2]); - Assert::AreEqual(memory.at(19), buffer[3]); - Assert::AreEqual(zero, buffer[4]); - Assert::AreEqual(zero, buffer[5]); - Assert::AreEqual(zero, buffer[6]); - Assert::AreEqual(zero, buffer[7]); - - // read across block (invalid -> valid) - emulator.ReadMemory(26U, buffer, 8); - Assert::AreEqual(zero, buffer[0]); - Assert::AreEqual(zero, buffer[1]); - Assert::AreEqual(zero, buffer[2]); - Assert::AreEqual(zero, buffer[3]); - Assert::AreEqual(memory.at(30), buffer[4]); - Assert::AreEqual(memory.at(31), buffer[5]); - Assert::AreEqual(memory.at(32), buffer[6]); - Assert::AreEqual(memory.at(33), buffer[7]); - } - - TEST_METHOD(TestWriteMemoryByte) - { - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); - - // attempt to write all 64 bytes - for (ra::data::ByteAddress i = 0; i < memory.size(); ++i) - emulator.WriteMemoryByte(i, gsl::narrow_cast(i + 4)); - - // only the 30 mapped bytes should be updated - for (uint8_t i = 0; i < emulator.TotalMemorySize(); ++i) - Assert::AreEqual(static_cast(i + 4), memory.at(i)); - - // the others should have their original values - for (uint8_t i = gsl::narrow_cast(emulator.TotalMemorySize()); i < memory.size(); ++i) - Assert::AreEqual(i, memory.at(i)); - } - - TEST_METHOD(TestWriteMemoryByteEvents) - { - InitializeMemory(); - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); - - EmulatorContextNotifyHarness notify; - emulator.AddNotifyTarget(notify); - - // write to first block - uint8_t nByte = 0xCE; - emulator.WriteMemoryByte(6U, nByte); - Assert::AreEqual(6U, notify.nLastByteWrittenAddress); - Assert::AreEqual(nByte, notify.nLastByteWritten); - - // write to second block - nByte = 0xEE; - emulator.WriteMemoryByte(26U, nByte); - Assert::AreEqual(26U, notify.nLastByteWrittenAddress); - Assert::AreEqual(nByte, notify.nLastByteWritten); - - // write to invalid address - emulator.WriteMemoryByte(36U, nByte + 3); - Assert::AreEqual(26U, notify.nLastByteWrittenAddress); - Assert::AreEqual(nByte, notify.nLastByteWritten); - - // write partial value - nByte = 0xC4; - emulator.WriteMemory(6U, Memory::Size::NibbleLower, 0x04); - Assert::AreEqual(6U, notify.nLastByteWrittenAddress); - Assert::AreEqual(nByte, notify.nLastByteWritten); - } - - TEST_METHOD(TestWriteMemory) - { - memory.at(4) = 0xA8; - memory.at(5) = 0x60; - memory.at(6) = 0x37; - memory.at(7) = 0x2E; - memory.at(8) = 0x04; - - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - - emulator.WriteMemory(4U, Memory::Size::EightBit, 0xFC); - Assert::AreEqual((uint8_t)0xFC, memory.at(4)); - Assert::AreEqual((uint8_t)0x60, memory.at(5)); - - emulator.WriteMemory(4U, Memory::Size::EightBit, 0x12345678); - Assert::AreEqual((uint8_t)0x78, memory.at(4)); - Assert::AreEqual((uint8_t)0x60, memory.at(5)); - - emulator.WriteMemory(4U, Memory::Size::SixteenBit, 0xABCD); - Assert::AreEqual((uint8_t)0xCD, memory.at(4)); - Assert::AreEqual((uint8_t)0xAB, memory.at(5)); - Assert::AreEqual((uint8_t)0x37, memory.at(6)); - - emulator.WriteMemory(4U, Memory::Size::SixteenBit, 0x12345678); - Assert::AreEqual((uint8_t)0x78, memory.at(4)); - Assert::AreEqual((uint8_t)0x56, memory.at(5)); - Assert::AreEqual((uint8_t)0x37, memory.at(6)); - - emulator.WriteMemory(4U, Memory::Size::TwentyFourBit, 0x12345678); - Assert::AreEqual((uint8_t)0x78, memory.at(4)); - Assert::AreEqual((uint8_t)0x56, memory.at(5)); - Assert::AreEqual((uint8_t)0x34, memory.at(6)); - Assert::AreEqual((uint8_t)0x2E, memory.at(7)); - - emulator.WriteMemory(4U, Memory::Size::ThirtyTwoBit, 0x76543210); - Assert::AreEqual((uint8_t)0x10, memory.at(4)); - Assert::AreEqual((uint8_t)0x32, memory.at(5)); - Assert::AreEqual((uint8_t)0x54, memory.at(6)); - Assert::AreEqual((uint8_t)0x76, memory.at(7)); - Assert::AreEqual((uint8_t)0x04, memory.at(8)); - - emulator.WriteMemory(4U, Memory::Size::SixteenBitBigEndian, 0x12345678); - Assert::AreEqual((uint8_t)0x56, memory.at(4)); - Assert::AreEqual((uint8_t)0x78, memory.at(5)); - Assert::AreEqual((uint8_t)0x54, memory.at(6)); - - emulator.WriteMemory(4U, Memory::Size::TwentyFourBitBigEndian, 0x12345678); - Assert::AreEqual((uint8_t)0x34, memory.at(4)); - Assert::AreEqual((uint8_t)0x56, memory.at(5)); - Assert::AreEqual((uint8_t)0x78, memory.at(6)); - Assert::AreEqual((uint8_t)0x76, memory.at(7)); - - emulator.WriteMemory(4U, Memory::Size::ThirtyTwoBitBigEndian, 0x76543210); - Assert::AreEqual((uint8_t)0x76, memory.at(4)); - Assert::AreEqual((uint8_t)0x54, memory.at(5)); - Assert::AreEqual((uint8_t)0x32, memory.at(6)); - Assert::AreEqual((uint8_t)0x10, memory.at(7)); - Assert::AreEqual((uint8_t)0x04, memory.at(8)); - - memory.at(4) = 0xFF; - emulator.WriteMemory(4U, Memory::Size::Bit0, 0x00); - Assert::AreEqual((uint8_t)0xFE, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::Bit0, 0x01); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::Bit1, 0x00); - Assert::AreEqual((uint8_t)0xFD, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::Bit1, 0x01); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::Bit2, 0x00); - Assert::AreEqual((uint8_t)0xFB, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::Bit2, 0x01); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::Bit3, 0x00); - Assert::AreEqual((uint8_t)0xF7, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::Bit3, 0x01); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::Bit4, 0x00); - Assert::AreEqual((uint8_t)0xEF, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::Bit4, 0x01); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::Bit5, 0x00); - Assert::AreEqual((uint8_t)0xDF, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::Bit5, 0x01); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::Bit6, 0x00); - Assert::AreEqual((uint8_t)0xBF, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::Bit6, 0x01); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::Bit7, 0x00); - Assert::AreEqual((uint8_t)0x7F, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::Bit7, 0x01); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::NibbleLower, 0x00); - Assert::AreEqual((uint8_t)0xF0, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::NibbleLower, 0x0F); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::NibbleUpper, 0x00); - Assert::AreEqual((uint8_t)0x0F, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::NibbleUpper, 0x0F); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - - emulator.WriteMemory(4U, Memory::Size::BitCount, 0x00); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - emulator.WriteMemory(4U, Memory::Size::BitCount, 0x02); - Assert::AreEqual((uint8_t)0xFF, memory.at(4)); - } - - TEST_METHOD(TestIsMemoryInsecureCached) - { - EmulatorContextHarness emulator; - Assert::IsFalse(emulator.IsMemoryInsecure()); - - emulator.mockDesktop.SetDebuggerPresent(true); - Assert::IsFalse(emulator.IsMemoryInsecure()); - - emulator.mockClock.AdvanceTime(std::chrono::seconds(5)); - Assert::IsFalse(emulator.IsMemoryInsecure()); - - emulator.mockClock.AdvanceTime(std::chrono::seconds(6)); - Assert::IsTrue(emulator.IsMemoryInsecure()); - } - - TEST_METHOD(TestIsMemoryInsecureRememberedUntilReset) - { - EmulatorContextHarness emulator; - emulator.mockDesktop.SetDebuggerPresent(true); - Assert::IsTrue(emulator.IsMemoryInsecure()); - - emulator.mockDesktop.SetDebuggerPresent(false); - Assert::IsTrue(emulator.IsMemoryInsecure()); - - emulator.mockClock.AdvanceTime(std::chrono::seconds(100)); - Assert::IsTrue(emulator.IsMemoryInsecure()); - - emulator.ResetMemoryModified(); - Assert::IsFalse(emulator.IsMemoryInsecure()); - } - - TEST_METHOD(TestIsMemoryInsecureRecheckedWhenReset) - { - EmulatorContextHarness emulator; - emulator.mockDesktop.SetDebuggerPresent(true); - Assert::IsTrue(emulator.IsMemoryInsecure()); - - emulator.mockClock.AdvanceTime(std::chrono::seconds(100)); - Assert::IsTrue(emulator.IsMemoryInsecure()); - - emulator.ResetMemoryModified(); - Assert::IsTrue(emulator.IsMemoryInsecure()); - } - TEST_METHOD(TestEnableHardcoreModeUnfreezesBookmarks) { EmulatorContextHarness emulator; @@ -1812,182 +1280,8 @@ TEST_CLASS(EmulatorContext_Tests) Assert::AreEqual(ra::data::models::AssetState::Inactive, vmAchievement46->GetState()); Assert::AreEqual(ra::data::models::AssetState::Inactive, vmAchievement47->GetState()); } - - TEST_METHOD(TestFormatAddress) - { - EmulatorContextHarness emulator; - emulator.AddMemoryBlock(0, 0x80, nullptr, nullptr); - - Assert::AreEqual(std::string("0x0000"), emulator.FormatAddress(0x00000000U)); - Assert::AreEqual(std::string("0x00ff"), emulator.FormatAddress(0x000000FFU)); - Assert::AreEqual(std::string("0x0100"), emulator.FormatAddress(0x00000100U)); - Assert::AreEqual(std::string("0xffff"), emulator.FormatAddress(0x0000FFFFU)); - Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); - Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); - Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); - Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); - - emulator.AddMemoryBlock(1, 0x80, nullptr, nullptr); // total size = 0x100 - Assert::AreEqual(std::string("0x0000"), emulator.FormatAddress(0x00000000U)); - Assert::AreEqual(std::string("0x00ff"), emulator.FormatAddress(0x000000FFU)); - Assert::AreEqual(std::string("0x0100"), emulator.FormatAddress(0x00000100U)); - Assert::AreEqual(std::string("0xffff"), emulator.FormatAddress(0x0000FFFFU)); - Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); - Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); - Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); - Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); - - emulator.AddMemoryBlock(2, 0xFF00, nullptr, nullptr); // total size = 0x10000 - Assert::AreEqual(std::string("0x0000"), emulator.FormatAddress(0x00000000U)); - Assert::AreEqual(std::string("0x00ff"), emulator.FormatAddress(0x000000FFU)); - Assert::AreEqual(std::string("0x0100"), emulator.FormatAddress(0x00000100U)); - Assert::AreEqual(std::string("0xffff"), emulator.FormatAddress(0x0000FFFFU)); - Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); - Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); - Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); - Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); - - emulator.AddMemoryBlock(3, 1, nullptr, nullptr); // total size = 0x10001 - Assert::AreEqual(std::string("0x000000"), emulator.FormatAddress(0x00000000U)); - Assert::AreEqual(std::string("0x0000ff"), emulator.FormatAddress(0x000000FFU)); - Assert::AreEqual(std::string("0x000100"), emulator.FormatAddress(0x00000100U)); - Assert::AreEqual(std::string("0x00ffff"), emulator.FormatAddress(0x0000FFFFU)); - Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); - Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); - Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); - Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); - - emulator.AddMemoryBlock(4, 0xFEFFFF, nullptr, nullptr); // total size = 0x1000000 - Assert::AreEqual(std::string("0x000000"), emulator.FormatAddress(0x00000000U)); - Assert::AreEqual(std::string("0x0000ff"), emulator.FormatAddress(0x000000FFU)); - Assert::AreEqual(std::string("0x000100"), emulator.FormatAddress(0x00000100U)); - Assert::AreEqual(std::string("0x00ffff"), emulator.FormatAddress(0x0000FFFFU)); - Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); - Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); - Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); - Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); - - emulator.AddMemoryBlock(5, 1, nullptr, nullptr); // total size = 0x1000001 - Assert::AreEqual(std::string("0x00000000"), emulator.FormatAddress(0x00000000U)); - Assert::AreEqual(std::string("0x000000ff"), emulator.FormatAddress(0x000000FFU)); - Assert::AreEqual(std::string("0x00000100"), emulator.FormatAddress(0x00000100U)); - Assert::AreEqual(std::string("0x0000ffff"), emulator.FormatAddress(0x0000FFFFU)); - Assert::AreEqual(std::string("0x00010000"), emulator.FormatAddress(0x00010000U)); - Assert::AreEqual(std::string("0x00ffffff"), emulator.FormatAddress(0x00FFFFFFU)); - Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); - Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); - } - - TEST_METHOD(TestCaptureMemory) - { - EmulatorContextHarness emulator; - - InitializeMemory(); - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - - std::vector vBlocks; - emulator.CaptureMemory(vBlocks, 0, 30, 0); - Assert::AreEqual({ 2 }, vBlocks.size()); - - Assert::AreEqual(20U, vBlocks.at(0).GetBytesSize()); - const auto* pBytes = vBlocks.at(0).GetBytes(); - for (size_t i = 0; i < 20; i++) - Assert::AreEqual(memory.at(i), pBytes[i]); - - Assert::AreEqual(10U, vBlocks.at(1).GetBytesSize()); - pBytes = vBlocks.at(1).GetBytes(); - for (size_t i = 0; i < 10; i++) - Assert::AreEqual(memory.at(i + 20), pBytes[i]); - } - - TEST_METHOD(TestCaptureMemoryOffset) - { - EmulatorContextHarness emulator; - - InitializeMemory(); - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - - std::vector vBlocks; - emulator.CaptureMemory(vBlocks, 8, 20, 0); - Assert::AreEqual({ 2 }, vBlocks.size()); - - Assert::AreEqual(12U, vBlocks.at(0).GetBytesSize()); - const auto* pBytes = vBlocks.at(0).GetBytes(); - for (size_t i = 0; i < 12; i++) - Assert::AreEqual(memory.at(i + 8), pBytes[i]); - - Assert::AreEqual(8U, vBlocks.at(1).GetBytesSize()); - pBytes = vBlocks.at(1).GetBytes(); - for (size_t i = 0; i < 8; i++) - Assert::AreEqual(memory.at(i + 20), pBytes[i]); - } - - TEST_METHOD(TestCaptureMemorySecondBlockOnly) - { - EmulatorContextHarness emulator; - - InitializeMemory(); - emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); - - std::vector vBlocks; - emulator.CaptureMemory(vBlocks, 20, 10, 0); - Assert::AreEqual({ 1 }, vBlocks.size()); - - Assert::AreEqual(10U, vBlocks.at(0).GetBytesSize()); - const auto* pBytes = vBlocks.at(0).GetBytes(); - for (size_t i = 0; i < 10; i++) - Assert::AreEqual(memory.at(i + 20), pBytes[i]); - } - - TEST_METHOD(TestCaptureMemoryGap) - { - EmulatorContextHarness emulator; - - InitializeMemory(); - emulator.AddMemoryBlock(0, 10, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, nullptr, nullptr); - emulator.AddMemoryBlock(2, 10, &ReadMemory2, &WriteMemory2); - - std::vector vBlocks; - emulator.CaptureMemory(vBlocks, 0, 30, 0); - Assert::AreEqual({ 2 }, vBlocks.size()); - - Assert::AreEqual(10U, vBlocks.at(0).GetBytesSize()); - const auto* pBytes = vBlocks.at(0).GetBytes(); - for (size_t i = 0; i < 10; i++) - Assert::AreEqual(memory.at(i), pBytes[i]); - - Assert::AreEqual(10U, vBlocks.at(1).GetBytesSize()); - pBytes = vBlocks.at(1).GetBytes(); - for (size_t i = 0; i < 10; i++) - Assert::AreEqual(memory.at(i + 20), pBytes[i]); - } - - TEST_METHOD(TestCaptureMemoryGapBoundary) - { - EmulatorContextHarness emulator; - - InitializeMemory(); - emulator.AddMemoryBlock(0, 10, &ReadMemory0, &WriteMemory0); - emulator.AddMemoryBlock(1, 10, nullptr, nullptr); - emulator.AddMemoryBlock(2, 10, &ReadMemory2, &WriteMemory2); - - std::vector vBlocks; - emulator.CaptureMemory(vBlocks, 20, 10, 0); - Assert::AreEqual({ 1 }, vBlocks.size()); - - Assert::AreEqual(10U, vBlocks.at(0).GetBytesSize()); - const auto* pBytes = vBlocks.at(0).GetBytes(); - for (size_t i = 0; i < 10; i++) - Assert::AreEqual(memory.at(i + 20), pBytes[i]); - } }; -std::array EmulatorContext_Tests::memory; - } // namespace tests } // namespace context } // namespace data diff --git a/tests/data/context/GameContext_Tests.cpp b/tests/data/context/GameContext_Tests.cpp index eac3bc8c0..ff81be5ad 100644 --- a/tests/data/context/GameContext_Tests.cpp +++ b/tests/data/context/GameContext_Tests.cpp @@ -16,12 +16,13 @@ #include "tests\ui\UIAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockAudioSystem.hh" #include "tests\mocks\MockEmulatorContext.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockFrameEventQueue.hh" @@ -63,6 +64,7 @@ TEST_CLASS(GameContext_Tests) } ra::api::mocks::MockServer mockServer; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::context::mocks::MockRcClient mockRcClient; ra::services::mocks::MockClock mockClock; ra::services::mocks::MockConfiguration mockConfiguration; diff --git a/tests/data/context/SessionTracker_Tests.cpp b/tests/data/context/SessionTracker_Tests.cpp index 385e0e32d..038eac55a 100644 --- a/tests/data/context/SessionTracker_Tests.cpp +++ b/tests/data/context/SessionTracker_Tests.cpp @@ -6,9 +6,9 @@ #include "tests\data\DataAsserts.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockLocalStorage.hh" diff --git a/tests/data/models/AchievementModel_Tests.cpp b/tests/data/models/AchievementModel_Tests.cpp index 091f2a3f8..3e3259791 100644 --- a/tests/data/models/AchievementModel_Tests.cpp +++ b/tests/data/models/AchievementModel_Tests.cpp @@ -9,8 +9,8 @@ #include "tests\data\DataAsserts.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\mocks\MockAchievementRuntime.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockGameContext.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; diff --git a/tests/data/models/CodeNoteModel_Tests.cpp b/tests/data/models/CodeNoteModel_Tests.cpp index 6e84c2a17..e7b6b9b50 100644 --- a/tests/data/models/CodeNoteModel_Tests.cpp +++ b/tests/data/models/CodeNoteModel_Tests.cpp @@ -8,10 +8,10 @@ #include "tests\data\DataAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockDesktop.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockServer.hh" #include "tests\mocks\MockUserContext.hh" @@ -29,7 +29,7 @@ TEST_CLASS(CodeNoteModel_Tests) { public: ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; }; void TestCodeNoteSize(const std::wstring& sNote, unsigned int nExpectedBytes, Memory::Size nExpectedSize) @@ -644,14 +644,14 @@ TEST_CLASS(CodeNoteModel_Tests) memory.at(0x07) = 0x80; memory.at(0x14) = 0x20; // pointer@0x14 = 0x80000020 memory.at(0x17) = 0x80; - note.mockEmulatorContext.MockMemory(memory); + note.mockEmulatorMemoryContext.MockMemory(memory); const std::wstring sNote = L"[32-bit pointer] root\r\n" L"+0x80000004 = [32-bit pointer] nested\r\n" L"++0x80000006 = data (8-bit)"; note.SetAddress(0x04); note.SetNote(sNote); - note.UpdateRawPointerValue(0x04, note.mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x04, note.mockEmulatorMemoryContext, nullptr); Assert::AreEqual(Memory::Size::ThirtyTwoBit, note.GetMemSize()); @@ -674,14 +674,14 @@ TEST_CLASS(CodeNoteModel_Tests) memory.at(0x07) = 0x80; memory.at(0x08) = 0x20; // pointer@0x08 = 0x80000020 memory.at(0x0B) = 0x80; - note.mockEmulatorContext.MockMemory(memory); + note.mockEmulatorMemoryContext.MockMemory(memory); const std::wstring sNote = L"[32-bit pointer] root\r\n" L"+0xFFFFFFF8 = [32-bit pointer] nested\r\n" L"++0x80000006 = data (8-bit)"; note.SetAddress(0x04); note.SetNote(sNote); - note.UpdateRawPointerValue(0x04, note.mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x04, note.mockEmulatorMemoryContext, nullptr); Assert::AreEqual(Memory::Size::ThirtyTwoBit, note.GetMemSize()); @@ -710,13 +710,13 @@ TEST_CLASS(CodeNoteModel_Tests) note.SetNote(sNote); std::array memory{}; - note.mockEmulatorContext.MockMemory(memory); + note.mockEmulatorMemoryContext.MockMemory(memory); memory.at(4) = 8; // pointer = 8 memory.at(8) = 20; // obj1 pointer = 20 memory.at(12) = 28; // obj2 pointer = 28 - note.UpdateRawPointerValue(4U, note.mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(4U, note.mockEmulatorMemoryContext, nullptr); Assert::AreEqual(8U, note.GetPointerAddress()); const auto* pObj1Note = note.GetPointerNoteAtOffset(0); diff --git a/tests/data/models/CodeNotesModel_Tests.cpp b/tests/data/models/CodeNotesModel_Tests.cpp index ca444c3e2..1738ea71b 100644 --- a/tests/data/models/CodeNotesModel_Tests.cpp +++ b/tests/data/models/CodeNotesModel_Tests.cpp @@ -8,10 +8,10 @@ #include "tests\data\DataAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockDesktop.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockServer.hh" #include "tests\mocks\MockUserContext.hh" @@ -30,7 +30,7 @@ TEST_CLASS(CodeNotesModel_Tests) public: ra::api::mocks::MockServer mockServer; ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockThreadPool mockThreadPool; ra::ui::mocks::MockDesktop mockDesktop; @@ -425,7 +425,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"+04 - Bomb Timer"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 0x04; notes.DoFrame(); @@ -446,7 +446,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"---FRAGGER_HEAD = Fragger Helmet"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 0x04; notes.DoFrame(); @@ -467,7 +467,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"+0x8033 = [16-bit] Total race time"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 0x04; notes.DoFrame(); @@ -491,7 +491,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"+0x1B5CE = Lap"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 0x04; notes.DoFrame(); @@ -516,7 +516,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"+22 = Skill Points (8-bit)"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 0x04; notes.DoFrame(); @@ -541,7 +541,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"-- +2 | Flag"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 0x10; memory.at(0x10+4) = 0x20; memory.at(0x10+8) = 0x28; @@ -566,7 +566,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"+5E = Left Leg Health {16-bit}"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 4; notes.DoFrame(); @@ -588,7 +588,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"+0x1B5CE = Lap"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 4; notes.DoFrame(); @@ -612,7 +612,7 @@ TEST_CLASS(CodeNotesModel_Tests) L"+10 = Very Large (8 bytes)"; notes.AddCodeNote(12, "Author", sNote); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(12) = 0x10; notes.DoFrame(); @@ -645,7 +645,7 @@ TEST_CLASS(CodeNotesModel_Tests) CodeNotesModelHarness notes; notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) const std::wstring sPointerNote = @@ -698,7 +698,7 @@ TEST_CLASS(CodeNotesModel_Tests) memory.at(4) = 8; // pointer = 8 memory.at(8) = 20; // obj1 pointer = 20 memory.at(12) = 28; // obj2 pointer = 28 - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); notes.DoFrame(); @@ -816,7 +816,7 @@ TEST_CLASS(CodeNotesModel_Tests) { CodeNotesModelHarness notes; std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(120) = 0x02; // start with initial value for pointer const std::wstring sPointerNote = @@ -876,7 +876,7 @@ TEST_CLASS(CodeNotesModel_Tests) CodeNotesModelHarness notes; notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) const std::wstring sPointerNote = @@ -945,7 +945,7 @@ TEST_CLASS(CodeNotesModel_Tests) std::array memory{}; for (uint8_t i = 0; i < memory.size(); i++) memory.at(i) = i; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(0) = 16; // start with initial value for pointer const std::wstring sNote = @@ -1018,7 +1018,7 @@ TEST_CLASS(CodeNotesModel_Tests) std::array memory{}; for (uint8_t i = 4; i < memory.size(); i++) memory.at(i) = i; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(0) = 0x90; // start with initial value for pointer (real address = 0x90, RA address = 0x10) const std::wstring sNote = @@ -1066,7 +1066,7 @@ TEST_CLASS(CodeNotesModel_Tests) std::array memory{}; for (uint8_t i = 4; i < memory.size(); i++) memory.at(i) = i; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(3) = 0x90; // start with initial value for pointer (real address = 0x90, RA address = 0x10) const std::wstring sNote = @@ -1114,7 +1114,7 @@ TEST_CLASS(CodeNotesModel_Tests) std::array memory{}; for (uint8_t i = 4; i < memory.size(); i++) memory.at(i) = i; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(0) = 0x90; // start with initial value for pointer (real address = 0x90, RA address = 0x10) const std::wstring sNote = @@ -1161,7 +1161,7 @@ TEST_CLASS(CodeNotesModel_Tests) std::array memory{}; for (uint8_t i = 0; i < memory.size(); i++) memory.at(i) = i; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(0) = 16; // start with initial value for pointer const std::wstring sNote = @@ -1189,7 +1189,7 @@ TEST_CLASS(CodeNotesModel_Tests) CodeNotesModelHarness notes; notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) const std::wstring sPointerNote = @@ -1223,7 +1223,7 @@ TEST_CLASS(CodeNotesModel_Tests) std::array memory{}; for (uint8_t i = 0; i < memory.size(); i++) memory.at(i) = i; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(0) = 16; // start with initial value for pointer const std::wstring sNote = @@ -1255,7 +1255,7 @@ TEST_CLASS(CodeNotesModel_Tests) CodeNotesModelHarness notes; notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(4) = 0x90; // start with initial value for pointer (real address = 0x90, RA address = 0x10) const std::wstring sNote = @@ -1441,7 +1441,7 @@ TEST_CLASS(CodeNotesModel_Tests) CodeNotesModelHarness notes; notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) const std::wstring sPointerNote = @@ -1504,7 +1504,7 @@ TEST_CLASS(CodeNotesModel_Tests) CodeNotesModelHarness notes; notes.mockConsoleContext.AddMemoryRegion(0, 31, ra::data::MemoryRegion::Type::SystemRAM, 0x80); std::array memory{}; - notes.mockEmulatorContext.MockMemory(memory); + notes.mockEmulatorMemoryContext.MockMemory(memory); memory.at(4) = 0x88; // start with initial value for pointer (real address = 0x88, RA address = 0x08) const std::wstring sPointerNote = diff --git a/tests/data/models/MemoryRegionsModel_Tests.cpp b/tests/data/models/MemoryRegionsModel_Tests.cpp index cc3495d79..531103e81 100644 --- a/tests/data/models/MemoryRegionsModel_Tests.cpp +++ b/tests/data/models/MemoryRegionsModel_Tests.cpp @@ -7,7 +7,7 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\data\DataAsserts.hh" -#include "tests\mocks\MockEmulatorContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -112,8 +112,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeEmpty) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsTrue(MemoryRegionsModel::ParseFilterRange(L"", nStartAddress, nEndAddress)); @@ -123,8 +123,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeHexPrefix) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsTrue(MemoryRegionsModel::ParseFilterRange(L"0xbeef-0xfeed", nStartAddress, nEndAddress)); @@ -134,8 +134,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeDollarPrefix) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsTrue(MemoryRegionsModel::ParseFilterRange(L"$beef-$feed", nStartAddress, nEndAddress)); @@ -145,8 +145,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeNoPrefix) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsTrue(MemoryRegionsModel::ParseFilterRange(L"1234-face", nStartAddress, nEndAddress)); @@ -156,8 +156,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeWhitespace) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsTrue(MemoryRegionsModel::ParseFilterRange(L"0xbeef - 0xfeed", nStartAddress, nEndAddress)); @@ -167,8 +167,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeNoHyphen) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsTrue(MemoryRegionsModel::ParseFilterRange(L"8765", nStartAddress, nEndAddress)); @@ -178,8 +178,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeNoStart) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsFalse(MemoryRegionsModel::ParseFilterRange(L"-8765", nStartAddress, nEndAddress)); @@ -189,8 +189,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeNoEnd) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsFalse(MemoryRegionsModel::ParseFilterRange(L"8765-", nStartAddress, nEndAddress)); @@ -200,8 +200,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeNotHex) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsFalse(MemoryRegionsModel::ParseFilterRange(L"banana", nStartAddress, nEndAddress)); @@ -211,8 +211,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeEndOutOfRange) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsTrue(MemoryRegionsModel::ParseFilterRange(L"0xF000-0x10000", nStartAddress, nEndAddress)); @@ -222,8 +222,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeStartOutOfRange) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsFalse(MemoryRegionsModel::ParseFilterRange(L"0x10000-0x1FFFF", nStartAddress, nEndAddress)); @@ -233,8 +233,8 @@ TEST_CLASS(MemoryRegionsModel_Tests) TEST_METHOD(TestParseFilterRangeStartAfterEnd) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); ra::data::ByteAddress nStartAddress, nEndAddress; Assert::IsTrue(MemoryRegionsModel::ParseFilterRange(L"0x9876-0x1234", nStartAddress, nEndAddress)); diff --git a/tests/data/models/TriggerValidation_Tests.cpp b/tests/data/models/TriggerValidation_Tests.cpp index 2eee3657c..9555ad8cd 100644 --- a/tests/data/models/TriggerValidation_Tests.cpp +++ b/tests/data/models/TriggerValidation_Tests.cpp @@ -3,8 +3,8 @@ #include "data\models\TriggerValidation.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\mocks\MockGameContext.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockUserContext.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -156,10 +156,10 @@ TEST_CLASS(TriggerValidation_Tests) // instead, max valid address is determined by how much memory the emulator/core exposes ra::context::mocks::MockConsoleContext mockConsoleContext(Arcade, L"Arcade"); Assert::AreEqual(0U, mockConsoleContext.MaxAddress()); - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; unsigned char pMemory[256]; - mockEmulatorContext.MockMemory(pMemory, sizeof(pMemory)); - Assert::AreEqual({ 256U }, mockEmulatorContext.TotalMemorySize()); + mockEmulatorMemoryContext.MockMemory(pMemory, sizeof(pMemory)); + Assert::AreEqual({ 256U }, mockEmulatorMemoryContext.TotalMemorySize()); AssertValidation("0xH12>0xH34", L""); AssertValidation("0xH123>0xH34", L"Condition 1: Address 0123 out of range (max 00FF)"); diff --git a/tests/devkit/RADevKit.Tests.vcxproj.vcxproj b/tests/devkit/RADevKit.Tests.vcxproj.vcxproj index 56b44fba7..c1e13015a 100644 --- a/tests/devkit/RADevKit.Tests.vcxproj.vcxproj +++ b/tests/devkit/RADevKit.Tests.vcxproj.vcxproj @@ -62,13 +62,17 @@ + + + + diff --git a/tests/devkit/RADevKit.Tests.vcxproj.vcxproj.filters b/tests/devkit/RADevKit.Tests.vcxproj.vcxproj.filters index 309e96a6a..d1ce42eae 100644 --- a/tests/devkit/RADevKit.Tests.vcxproj.vcxproj.filters +++ b/tests/devkit/RADevKit.Tests.vcxproj.vcxproj.filters @@ -34,6 +34,12 @@ context\impl + + context\impl + + + context\mocks + @@ -95,5 +101,11 @@ context\mocks + + services\mocks + + + context\mocks + \ No newline at end of file diff --git a/tests/devkit/context/impl/EmulatorMemoryContext_Tests.cpp b/tests/devkit/context/impl/EmulatorMemoryContext_Tests.cpp new file mode 100644 index 000000000..e4a5346d6 --- /dev/null +++ b/tests/devkit/context/impl/EmulatorMemoryContext_Tests.cpp @@ -0,0 +1,771 @@ +#include "context/impl/EmulatorMemoryContext.hh" + +#include "tests/devkit/services/mocks/MockClock.hh" +#include "tests/devkit/services/mocks/MockDebuggerDetector.hh" + +#include "testutil\CppUnitTest.hh" + +namespace ra { +namespace context { +namespace impl { +namespace tests { + +TEST_CLASS(EmulatorMemoryContext_Tests) +{ +private: + class EmulatorMemoryContextHarness : public EmulatorMemoryContext + { + public: + ra::services::mocks::MockClock mockClock; + ra::services::mocks::MockDebuggerDetector mockDebuggerDetector; + + GSL_SUPPRESS_F6 EmulatorMemoryContextHarness() noexcept + : m_Override(this) + { + } + + private: + ra::services::ServiceLocator::ServiceOverride m_Override; + }; + + class EmulatorMemoryContextNotifyHarness : public EmulatorMemoryContext::NotifyTarget + { + public: + void OnByteWritten(ra::data::ByteAddress nAddress, uint8_t nValue) noexcept override + { + nLastByteWrittenAddress = nAddress; + nLastByteWritten = nValue; + } + + ra::data::ByteAddress nLastByteWrittenAddress = 0xFFFFFFFFU; + uint8_t nLastByteWritten = 0xFF; + }; + + static std::array memory; + + static uint8_t ReadMemory0(uint32_t nAddress) noexcept { return memory.at(nAddress); } + static uint8_t ReadMemory1(uint32_t nAddress) noexcept { return memory.at(gsl::narrow_cast(nAddress) + 10); } + static uint8_t ReadMemory2(uint32_t nAddress) noexcept { return memory.at(gsl::narrow_cast(nAddress) + 20); } + static uint8_t ReadMemory3(uint32_t nAddress) noexcept { return memory.at(gsl::narrow_cast(nAddress) + 30); } + + static uint32_t ReadMemoryBlock0(uint32_t nAddress, uint8_t* pBuffer, uint32_t nBytes) noexcept + { + memcpy(pBuffer, &memory.at(nAddress), nBytes); + return nBytes; + } + + static uint32_t ReadMemoryBlock1(uint32_t nAddress, uint8_t* pBuffer, uint32_t nBytes) noexcept + { + memcpy(pBuffer, &memory.at(gsl::narrow_cast(nAddress)) + 10, nBytes); + return nBytes; + } + + static void WriteMemory0(uint32_t nAddress, uint8_t nValue) noexcept { memory.at(nAddress) = nValue; } + static void WriteMemory1(uint32_t nAddress, uint8_t nValue) noexcept { memory.at(gsl::narrow_cast(nAddress) + 10) = nValue; } + static void WriteMemory2(uint32_t nAddress, uint8_t nValue) noexcept { memory.at(gsl::narrow_cast(nAddress) + 20) = nValue; } + static void WriteMemory3(uint32_t nAddress, uint8_t nValue) noexcept { memory.at(gsl::narrow_cast(nAddress) + 30) = nValue; } + + static void InitializeMemory() + { + for (size_t i = 0; i < memory.size(); ++i) + memory.at(i) = gsl::narrow_cast(i); + } + +public: + TEST_METHOD(TestIsValidAddress) + { + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); + + Assert::IsTrue(emulator.IsValidAddress(12U)); + Assert::IsTrue(emulator.IsValidAddress(25U)); + Assert::IsTrue(emulator.IsValidAddress(29U)); + Assert::IsFalse(emulator.IsValidAddress(30U)); + } + + TEST_METHOD(TestReadMemoryByte) + { + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); + + Assert::AreEqual(12, static_cast(emulator.ReadMemoryByte(12U))); + Assert::AreEqual(25, static_cast(emulator.ReadMemoryByte(25U))); + Assert::AreEqual(4, static_cast(emulator.ReadMemoryByte(4U))); + Assert::AreEqual(29, static_cast(emulator.ReadMemoryByte(29U))); + Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(30U))); + } + + TEST_METHOD(TestAddMemoryBlocksOutOfOrder) + { + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); + + Assert::AreEqual(12, static_cast(emulator.ReadMemoryByte(12U))); + Assert::AreEqual(25, static_cast(emulator.ReadMemoryByte(25U))); + Assert::AreEqual(4, static_cast(emulator.ReadMemoryByte(4U))); + Assert::AreEqual(29, static_cast(emulator.ReadMemoryByte(29U))); + Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(30U))); + } + + TEST_METHOD(TestAddMemoryBlockDoesNotOverwrite) + { + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + emulator.AddMemoryBlock(0, 20, &ReadMemory3, &WriteMemory3); + Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); + + Assert::AreEqual(12, static_cast(emulator.ReadMemoryByte(12U))); + Assert::AreEqual(25, static_cast(emulator.ReadMemoryByte(25U))); + Assert::AreEqual(4, static_cast(emulator.ReadMemoryByte(4U))); + Assert::AreEqual(29, static_cast(emulator.ReadMemoryByte(29U))); + Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(30U))); + } + + TEST_METHOD(TestClearMemoryBlocks) + { + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + emulator.ClearMemoryBlocks(); + emulator.AddMemoryBlock(0, 20, &ReadMemory3, &WriteMemory3); + Assert::AreEqual({ 20U }, emulator.TotalMemorySize()); + + Assert::AreEqual(32, static_cast(emulator.ReadMemoryByte(2U))); + Assert::AreEqual(41, static_cast(emulator.ReadMemoryByte(11U))); + Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(55U))); + } + + TEST_METHOD(TestInvalidMemoryBlock) + { + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, nullptr, nullptr); + emulator.AddMemoryBlock(2, 10, &ReadMemory3, &WriteMemory3); + Assert::AreEqual({ 40U }, emulator.TotalMemorySize()); + + Assert::IsTrue(emulator.IsValidAddress(12U)); + Assert::IsTrue(emulator.IsValidAddress(19U)); + Assert::IsFalse(emulator.IsValidAddress(20U)); + Assert::IsFalse(emulator.IsValidAddress(29U)); + Assert::IsTrue(emulator.IsValidAddress(30U)); + Assert::IsTrue(emulator.IsValidAddress(39U)); + Assert::IsFalse(emulator.IsValidAddress(40U)); + + Assert::AreEqual(12, static_cast(emulator.ReadMemoryByte(12U))); + Assert::AreEqual(19, static_cast(emulator.ReadMemoryByte(19U))); + Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(20U))); + Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(29U))); + Assert::AreEqual(30, static_cast(emulator.ReadMemoryByte(30U))); + Assert::AreEqual(39, static_cast(emulator.ReadMemoryByte(39U))); + Assert::AreEqual(0, static_cast(emulator.ReadMemoryByte(40U))); + } + + TEST_METHOD(TestReadMemory) + { + memory.at(4) = 0xA8; + memory.at(5) = 0x00; + memory.at(6) = 0x37; + memory.at(7) = 0x2E; + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + + // ReadMemory calls ReadMemoryByte for small sizes + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit0))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit1))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit2))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit3))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit4))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit5))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit6))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit7))); + Assert::AreEqual(3, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::BitCount))); + Assert::AreEqual(8, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::NibbleLower))); + Assert::AreEqual(10, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::NibbleUpper))); + Assert::AreEqual(0xA8, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::EightBit))); + Assert::AreEqual(0xA8, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::SixteenBit))); + Assert::AreEqual(0x2E37, static_cast(emulator.ReadMemory(6U, ra::data::Memory::Size::SixteenBit))); + Assert::AreEqual(0x2E3700, static_cast(emulator.ReadMemory(5U, ra::data::Memory::Size::TwentyFourBit))); + Assert::AreEqual(0x2E3700A8, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::ThirtyTwoBit))); + Assert::AreEqual(0x372E, static_cast(emulator.ReadMemory(6U, ra::data::Memory::Size::SixteenBitBigEndian))); + Assert::AreEqual(0x00372E, static_cast(emulator.ReadMemory(5U, ra::data::Memory::Size::TwentyFourBitBigEndian))); + Assert::AreEqual(0xA800372EU, emulator.ReadMemory(4U, ra::data::Memory::Size::ThirtyTwoBitBigEndian)); + + memory.at(4) ^= 0xFF; // toggle all bits and verify again + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit0))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit1))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit2))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit3))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit4))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit5))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit6))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit7))); + Assert::AreEqual(5, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::BitCount))); + Assert::AreEqual(7, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::NibbleLower))); + Assert::AreEqual(5, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::NibbleUpper))); + Assert::AreEqual(0x57, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::EightBit))); + } + + TEST_METHOD(TestReadMemoryBlock) + { + for (size_t i = 0; i < memory.size(); i++) + memory.at(i) = gsl::narrow_cast(i); + + memory.at(4) = 0xA8; + memory.at(5) = 0x00; + memory.at(6) = 0x37; + memory.at(7) = 0x2E; + + memory.at(14) = 0x57; + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory1, &WriteMemory0); // purposefully use ReadMemory1 to detect using byte reader for non-byte reads + emulator.AddMemoryBlockReader(0, &ReadMemoryBlock0); + + // ReadMemory calls ReadMemoryByte for small sizes - should call ReadMemory1 ($4 => $14) + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit0))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit1))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit2))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit3))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit4))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit5))); + Assert::AreEqual(1, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit6))); + Assert::AreEqual(0, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::Bit7))); + Assert::AreEqual(5, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::BitCount))); + Assert::AreEqual(7, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::NibbleLower))); + Assert::AreEqual(5, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::NibbleUpper))); + Assert::AreEqual(0x57, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::EightBit))); + + // sizes larger than 8 bits should use the block reader ($4 => $4) + Assert::AreEqual(0xA8, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::SixteenBit))); + Assert::AreEqual(0x2E37, static_cast(emulator.ReadMemory(6U, ra::data::Memory::Size::SixteenBit))); + Assert::AreEqual(0x2E3700, static_cast(emulator.ReadMemory(5U, ra::data::Memory::Size::TwentyFourBit))); + Assert::AreEqual(0x2E3700A8, static_cast(emulator.ReadMemory(4U, ra::data::Memory::Size::ThirtyTwoBit))); + Assert::AreEqual(0x372E, static_cast(emulator.ReadMemory(6U, ra::data::Memory::Size::SixteenBitBigEndian))); + Assert::AreEqual(0x00372E, static_cast(emulator.ReadMemory(5U, ra::data::Memory::Size::TwentyFourBitBigEndian))); + Assert::AreEqual(0xA800372EU, emulator.ReadMemory(4U, ra::data::Memory::Size::ThirtyTwoBitBigEndian)); + + // test the block reader directly + uint8_t buffer[16]; + emulator.ReadMemory(0U, buffer, sizeof(buffer)); + for (size_t i = 0; i < sizeof(buffer); i++) + Assert::AreEqual(gsl::at(buffer, i), memory.at(i)); + + emulator.ReadMemory(4U, buffer, 1); + Assert::AreEqual(gsl::at(buffer, 0), memory.at(4)); + Assert::AreEqual(gsl::at(buffer, 1), memory.at(1)); + } + + TEST_METHOD(TestReadMemoryBuffer) + { + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); + + uint8_t buffer[32]; + + // simple read within a block + emulator.ReadMemory(6U, buffer, 12); + Assert::IsTrue(memcmp(buffer, &memory.at(6), 11) == 0); + + // read across block + emulator.ReadMemory(19U, buffer, 4); + Assert::IsTrue(memcmp(buffer, &memory.at(19), 4) == 0); + + // read end of block + emulator.ReadMemory(13U, buffer, 7); + Assert::IsTrue(memcmp(buffer, &memory.at(13), 7) == 0); + + // read start of block + emulator.ReadMemory(20U, buffer, 5); + Assert::IsTrue(memcmp(buffer, &memory.at(20), 5) == 0); + + // read passed end of total memory + emulator.ReadMemory(28U, buffer, 4); + Assert::AreEqual(28, static_cast(buffer[0])); + Assert::AreEqual(29, static_cast(buffer[1])); + Assert::AreEqual(0, static_cast(buffer[2])); + Assert::AreEqual(0, static_cast(buffer[3])); + + // read outside memory + buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xFF; + emulator.ReadMemory(37U, buffer, 4); + Assert::AreEqual(0, static_cast(buffer[0])); + Assert::AreEqual(0, static_cast(buffer[1])); + Assert::AreEqual(0, static_cast(buffer[2])); + Assert::AreEqual(0, static_cast(buffer[3])); + } + + TEST_METHOD(TestReadMemoryBufferInvalidMemoryBlock) + { + constexpr uint8_t zero = 0; + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, nullptr, nullptr); + emulator.AddMemoryBlock(2, 10, &ReadMemory3, &WriteMemory3); + Assert::AreEqual({ 40U }, emulator.TotalMemorySize()); + + uint8_t buffer[32]; + + // simple read within valid block + emulator.ReadMemory(6U, buffer, 12); + Assert::IsTrue(memcmp(buffer, &memory.at(6), 11) == 0); + + // simple read within invalid block + emulator.ReadMemory(22U, buffer, 4); + Assert::AreEqual(zero, buffer[0]); + Assert::AreEqual(zero, buffer[1]); + Assert::AreEqual(zero, buffer[2]); + Assert::AreEqual(zero, buffer[3]); + + // read across block (valid -> invalid) + emulator.ReadMemory(16U, buffer, 8); + Assert::AreEqual(memory.at(16), buffer[0]); + Assert::AreEqual(memory.at(17), buffer[1]); + Assert::AreEqual(memory.at(18), buffer[2]); + Assert::AreEqual(memory.at(19), buffer[3]); + Assert::AreEqual(zero, buffer[4]); + Assert::AreEqual(zero, buffer[5]); + Assert::AreEqual(zero, buffer[6]); + Assert::AreEqual(zero, buffer[7]); + + // read across block (invalid -> valid) + emulator.ReadMemory(26U, buffer, 8); + Assert::AreEqual(zero, buffer[0]); + Assert::AreEqual(zero, buffer[1]); + Assert::AreEqual(zero, buffer[2]); + Assert::AreEqual(zero, buffer[3]); + Assert::AreEqual(memory.at(30), buffer[4]); + Assert::AreEqual(memory.at(31), buffer[5]); + Assert::AreEqual(memory.at(32), buffer[6]); + Assert::AreEqual(memory.at(33), buffer[7]); + } + + TEST_METHOD(TestWriteMemoryByte) + { + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); + + // attempt to write all 64 bytes + for (ra::data::ByteAddress i = 0; i < memory.size(); ++i) + emulator.WriteMemoryByte(i, gsl::narrow_cast(i + 4)); + + // only the 30 mapped bytes should be updated + for (uint8_t i = 0; i < emulator.TotalMemorySize(); ++i) + Assert::AreEqual(static_cast(i + 4), memory.at(i)); + + // the others should have their original values + for (uint8_t i = gsl::narrow_cast(emulator.TotalMemorySize()); i < memory.size(); ++i) + Assert::AreEqual(i, memory.at(i)); + } + + TEST_METHOD(TestWriteMemoryByteEvents) + { + InitializeMemory(); + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + Assert::AreEqual({ 30U }, emulator.TotalMemorySize()); + + EmulatorMemoryContextNotifyHarness notify; + emulator.AddNotifyTarget(notify); + + // write to first block + uint8_t nByte = 0xCE; + emulator.WriteMemoryByte(6U, nByte); + Assert::AreEqual(6U, notify.nLastByteWrittenAddress); + Assert::AreEqual(nByte, notify.nLastByteWritten); + + // write to second block + nByte = 0xEE; + emulator.WriteMemoryByte(26U, nByte); + Assert::AreEqual(26U, notify.nLastByteWrittenAddress); + Assert::AreEqual(nByte, notify.nLastByteWritten); + + // write to invalid address + emulator.WriteMemoryByte(36U, nByte + 3); + Assert::AreEqual(26U, notify.nLastByteWrittenAddress); + Assert::AreEqual(nByte, notify.nLastByteWritten); + + // write partial value + nByte = 0xC4; + emulator.WriteMemory(6U, ra::data::Memory::Size::NibbleLower, 0x04); + Assert::AreEqual(6U, notify.nLastByteWrittenAddress); + Assert::AreEqual(nByte, notify.nLastByteWritten); + } + + TEST_METHOD(TestWriteMemory) + { + memory.at(4) = 0xA8; + memory.at(5) = 0x60; + memory.at(6) = 0x37; + memory.at(7) = 0x2E; + memory.at(8) = 0x04; + + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + + emulator.WriteMemory(4U, ra::data::Memory::Size::EightBit, 0xFC); + Assert::AreEqual((uint8_t)0xFC, memory.at(4)); + Assert::AreEqual((uint8_t)0x60, memory.at(5)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::EightBit, 0x12345678); + Assert::AreEqual((uint8_t)0x78, memory.at(4)); + Assert::AreEqual((uint8_t)0x60, memory.at(5)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::SixteenBit, 0xABCD); + Assert::AreEqual((uint8_t)0xCD, memory.at(4)); + Assert::AreEqual((uint8_t)0xAB, memory.at(5)); + Assert::AreEqual((uint8_t)0x37, memory.at(6)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::SixteenBit, 0x12345678); + Assert::AreEqual((uint8_t)0x78, memory.at(4)); + Assert::AreEqual((uint8_t)0x56, memory.at(5)); + Assert::AreEqual((uint8_t)0x37, memory.at(6)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::TwentyFourBit, 0x12345678); + Assert::AreEqual((uint8_t)0x78, memory.at(4)); + Assert::AreEqual((uint8_t)0x56, memory.at(5)); + Assert::AreEqual((uint8_t)0x34, memory.at(6)); + Assert::AreEqual((uint8_t)0x2E, memory.at(7)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::ThirtyTwoBit, 0x76543210); + Assert::AreEqual((uint8_t)0x10, memory.at(4)); + Assert::AreEqual((uint8_t)0x32, memory.at(5)); + Assert::AreEqual((uint8_t)0x54, memory.at(6)); + Assert::AreEqual((uint8_t)0x76, memory.at(7)); + Assert::AreEqual((uint8_t)0x04, memory.at(8)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::SixteenBitBigEndian, 0x12345678); + Assert::AreEqual((uint8_t)0x56, memory.at(4)); + Assert::AreEqual((uint8_t)0x78, memory.at(5)); + Assert::AreEqual((uint8_t)0x54, memory.at(6)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::TwentyFourBitBigEndian, 0x12345678); + Assert::AreEqual((uint8_t)0x34, memory.at(4)); + Assert::AreEqual((uint8_t)0x56, memory.at(5)); + Assert::AreEqual((uint8_t)0x78, memory.at(6)); + Assert::AreEqual((uint8_t)0x76, memory.at(7)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::ThirtyTwoBitBigEndian, 0x76543210); + Assert::AreEqual((uint8_t)0x76, memory.at(4)); + Assert::AreEqual((uint8_t)0x54, memory.at(5)); + Assert::AreEqual((uint8_t)0x32, memory.at(6)); + Assert::AreEqual((uint8_t)0x10, memory.at(7)); + Assert::AreEqual((uint8_t)0x04, memory.at(8)); + + memory.at(4) = 0xFF; + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit0, 0x00); + Assert::AreEqual((uint8_t)0xFE, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit0, 0x01); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit1, 0x00); + Assert::AreEqual((uint8_t)0xFD, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit1, 0x01); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit2, 0x00); + Assert::AreEqual((uint8_t)0xFB, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit2, 0x01); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit3, 0x00); + Assert::AreEqual((uint8_t)0xF7, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit3, 0x01); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit4, 0x00); + Assert::AreEqual((uint8_t)0xEF, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit4, 0x01); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit5, 0x00); + Assert::AreEqual((uint8_t)0xDF, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit5, 0x01); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit6, 0x00); + Assert::AreEqual((uint8_t)0xBF, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit6, 0x01); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit7, 0x00); + Assert::AreEqual((uint8_t)0x7F, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::Bit7, 0x01); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::NibbleLower, 0x00); + Assert::AreEqual((uint8_t)0xF0, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::NibbleLower, 0x0F); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::NibbleUpper, 0x00); + Assert::AreEqual((uint8_t)0x0F, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::NibbleUpper, 0x0F); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + + emulator.WriteMemory(4U, ra::data::Memory::Size::BitCount, 0x00); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + emulator.WriteMemory(4U, ra::data::Memory::Size::BitCount, 0x02); + Assert::AreEqual((uint8_t)0xFF, memory.at(4)); + } + + TEST_METHOD(TestIsMemoryInsecureCached) + { + EmulatorMemoryContextHarness emulator; + Assert::IsFalse(emulator.IsMemoryInsecure()); + + emulator.mockDebuggerDetector.SetDebuggerPresent(true); + Assert::IsFalse(emulator.IsMemoryInsecure()); + + emulator.mockClock.AdvanceTime(std::chrono::seconds(5)); + Assert::IsFalse(emulator.IsMemoryInsecure()); + + emulator.mockClock.AdvanceTime(std::chrono::seconds(6)); + Assert::IsTrue(emulator.IsMemoryInsecure()); + } + + TEST_METHOD(TestIsMemoryInsecureRememberedUntilReset) + { + EmulatorMemoryContextHarness emulator; + emulator.mockDebuggerDetector.SetDebuggerPresent(true); + Assert::IsTrue(emulator.IsMemoryInsecure()); + + emulator.mockDebuggerDetector.SetDebuggerPresent(false); + Assert::IsTrue(emulator.IsMemoryInsecure()); + + emulator.mockClock.AdvanceTime(std::chrono::seconds(100)); + Assert::IsTrue(emulator.IsMemoryInsecure()); + + emulator.ResetMemoryModified(); + Assert::IsFalse(emulator.IsMemoryInsecure()); + } + + TEST_METHOD(TestIsMemoryInsecureRecheckedWhenReset) + { + EmulatorMemoryContextHarness emulator; + emulator.mockDebuggerDetector.SetDebuggerPresent(true); + Assert::IsTrue(emulator.IsMemoryInsecure()); + + emulator.mockClock.AdvanceTime(std::chrono::seconds(100)); + Assert::IsTrue(emulator.IsMemoryInsecure()); + + emulator.ResetMemoryModified(); + Assert::IsTrue(emulator.IsMemoryInsecure()); + } + + TEST_METHOD(TestFormatAddress) + { + EmulatorMemoryContextHarness emulator; + emulator.AddMemoryBlock(0, 0x80, nullptr, nullptr); + + Assert::AreEqual(std::string("0x0000"), emulator.FormatAddress(0x00000000U)); + Assert::AreEqual(std::string("0x00ff"), emulator.FormatAddress(0x000000FFU)); + Assert::AreEqual(std::string("0x0100"), emulator.FormatAddress(0x00000100U)); + Assert::AreEqual(std::string("0xffff"), emulator.FormatAddress(0x0000FFFFU)); + Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); + Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); + Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); + Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); + + emulator.AddMemoryBlock(1, 0x80, nullptr, nullptr); // total size = 0x100 + Assert::AreEqual(std::string("0x0000"), emulator.FormatAddress(0x00000000U)); + Assert::AreEqual(std::string("0x00ff"), emulator.FormatAddress(0x000000FFU)); + Assert::AreEqual(std::string("0x0100"), emulator.FormatAddress(0x00000100U)); + Assert::AreEqual(std::string("0xffff"), emulator.FormatAddress(0x0000FFFFU)); + Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); + Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); + Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); + Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); + + emulator.AddMemoryBlock(2, 0xFF00, nullptr, nullptr); // total size = 0x10000 + Assert::AreEqual(std::string("0x0000"), emulator.FormatAddress(0x00000000U)); + Assert::AreEqual(std::string("0x00ff"), emulator.FormatAddress(0x000000FFU)); + Assert::AreEqual(std::string("0x0100"), emulator.FormatAddress(0x00000100U)); + Assert::AreEqual(std::string("0xffff"), emulator.FormatAddress(0x0000FFFFU)); + Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); + Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); + Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); + Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); + + emulator.AddMemoryBlock(3, 1, nullptr, nullptr); // total size = 0x10001 + Assert::AreEqual(std::string("0x000000"), emulator.FormatAddress(0x00000000U)); + Assert::AreEqual(std::string("0x0000ff"), emulator.FormatAddress(0x000000FFU)); + Assert::AreEqual(std::string("0x000100"), emulator.FormatAddress(0x00000100U)); + Assert::AreEqual(std::string("0x00ffff"), emulator.FormatAddress(0x0000FFFFU)); + Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); + Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); + Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); + Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); + + emulator.AddMemoryBlock(4, 0xFEFFFF, nullptr, nullptr); // total size = 0x1000000 + Assert::AreEqual(std::string("0x000000"), emulator.FormatAddress(0x00000000U)); + Assert::AreEqual(std::string("0x0000ff"), emulator.FormatAddress(0x000000FFU)); + Assert::AreEqual(std::string("0x000100"), emulator.FormatAddress(0x00000100U)); + Assert::AreEqual(std::string("0x00ffff"), emulator.FormatAddress(0x0000FFFFU)); + Assert::AreEqual(std::string("0x010000"), emulator.FormatAddress(0x00010000U)); + Assert::AreEqual(std::string("0xffffff"), emulator.FormatAddress(0x00FFFFFFU)); + Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); + Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); + + emulator.AddMemoryBlock(5, 1, nullptr, nullptr); // total size = 0x1000001 + Assert::AreEqual(std::string("0x00000000"), emulator.FormatAddress(0x00000000U)); + Assert::AreEqual(std::string("0x000000ff"), emulator.FormatAddress(0x000000FFU)); + Assert::AreEqual(std::string("0x00000100"), emulator.FormatAddress(0x00000100U)); + Assert::AreEqual(std::string("0x0000ffff"), emulator.FormatAddress(0x0000FFFFU)); + Assert::AreEqual(std::string("0x00010000"), emulator.FormatAddress(0x00010000U)); + Assert::AreEqual(std::string("0x00ffffff"), emulator.FormatAddress(0x00FFFFFFU)); + Assert::AreEqual(std::string("0x01000000"), emulator.FormatAddress(0x01000000U)); + Assert::AreEqual(std::string("0xffffffff"), emulator.FormatAddress(0xFFFFFFFFU)); + } + + TEST_METHOD(TestCaptureMemory) + { + EmulatorMemoryContextHarness emulator; + + InitializeMemory(); + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + + std::vector vBlocks; + emulator.CaptureMemory(vBlocks, 0, 30, 0); + Assert::AreEqual({ 2 }, vBlocks.size()); + + Assert::AreEqual(20U, vBlocks.at(0).GetBytesSize()); + const auto* pBytes = vBlocks.at(0).GetBytes(); + Expects(pBytes != nullptr); + for (size_t i = 0; i < 20; i++) + Assert::AreEqual(memory.at(i), pBytes[i]); + + Assert::AreEqual(10U, vBlocks.at(1).GetBytesSize()); + pBytes = vBlocks.at(1).GetBytes(); + Expects(pBytes != nullptr); + for (size_t i = 0; i < 10; i++) + Assert::AreEqual(memory.at(i + 20), pBytes[i]); + } + + TEST_METHOD(TestCaptureMemoryOffset) + { + EmulatorMemoryContextHarness emulator; + + InitializeMemory(); + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + + std::vector vBlocks; + emulator.CaptureMemory(vBlocks, 8, 20, 0); + Assert::AreEqual({ 2 }, vBlocks.size()); + + Assert::AreEqual(12U, vBlocks.at(0).GetBytesSize()); + const auto* pBytes = vBlocks.at(0).GetBytes(); + Expects(pBytes != nullptr); + for (size_t i = 0; i < 12; i++) + Assert::AreEqual(memory.at(i + 8), pBytes[i]); + + Assert::AreEqual(8U, vBlocks.at(1).GetBytesSize()); + pBytes = vBlocks.at(1).GetBytes(); + Expects(pBytes != nullptr); + for (size_t i = 0; i < 8; i++) + Assert::AreEqual(memory.at(i + 20), pBytes[i]); + } + + TEST_METHOD(TestCaptureMemorySecondBlockOnly) + { + EmulatorMemoryContextHarness emulator; + + InitializeMemory(); + emulator.AddMemoryBlock(0, 20, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, &ReadMemory2, &WriteMemory2); + + std::vector vBlocks; + emulator.CaptureMemory(vBlocks, 20, 10, 0); + Assert::AreEqual({ 1 }, vBlocks.size()); + + Assert::AreEqual(10U, vBlocks.at(0).GetBytesSize()); + const auto* pBytes = vBlocks.at(0).GetBytes(); + Expects(pBytes != nullptr); + for (size_t i = 0; i < 10; i++) + Assert::AreEqual(memory.at(i + 20), pBytes[i]); + } + + TEST_METHOD(TestCaptureMemoryGap) + { + EmulatorMemoryContextHarness emulator; + + InitializeMemory(); + emulator.AddMemoryBlock(0, 10, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, nullptr, nullptr); + emulator.AddMemoryBlock(2, 10, &ReadMemory2, &WriteMemory2); + + std::vector vBlocks; + emulator.CaptureMemory(vBlocks, 0, 30, 0); + Assert::AreEqual({ 2 }, vBlocks.size()); + + Assert::AreEqual(10U, vBlocks.at(0).GetBytesSize()); + const auto* pBytes = vBlocks.at(0).GetBytes(); + Expects(pBytes != nullptr); + for (size_t i = 0; i < 10; i++) + Assert::AreEqual(memory.at(i), pBytes[i]); + + Assert::AreEqual(10U, vBlocks.at(1).GetBytesSize()); + pBytes = vBlocks.at(1).GetBytes(); + Expects(pBytes != nullptr); + for (size_t i = 0; i < 10; i++) + Assert::AreEqual(memory.at(i + 20), pBytes[i]); + } + + TEST_METHOD(TestCaptureMemoryGapBoundary) + { + EmulatorMemoryContextHarness emulator; + + InitializeMemory(); + emulator.AddMemoryBlock(0, 10, &ReadMemory0, &WriteMemory0); + emulator.AddMemoryBlock(1, 10, nullptr, nullptr); + emulator.AddMemoryBlock(2, 10, &ReadMemory2, &WriteMemory2); + + std::vector vBlocks; + emulator.CaptureMemory(vBlocks, 20, 10, 0); + Assert::AreEqual({ 1 }, vBlocks.size()); + + Assert::AreEqual(10U, vBlocks.at(0).GetBytesSize()); + const auto* pBytes = vBlocks.at(0).GetBytes(); + Expects(pBytes != nullptr); + for (size_t i = 0; i < 10; i++) + Assert::AreEqual(memory.at(i + 20), pBytes[i]); + } +}; + +std::array EmulatorMemoryContext_Tests::memory; + +} // namespace tests +} // namespace impl +} // namespace context +} // namespace ra diff --git a/tests/devkit/context/mocks/MockEmulatorMemoryContext.cpp b/tests/devkit/context/mocks/MockEmulatorMemoryContext.cpp new file mode 100644 index 000000000..28d5c5331 --- /dev/null +++ b/tests/devkit/context/mocks/MockEmulatorMemoryContext.cpp @@ -0,0 +1,94 @@ +#include "MockEmulatorMemoryContext.hh" + +#include "context/IRcClient.hh" + +#include + +namespace ra { +namespace context { +namespace mocks { + +void MockEmulatorMemoryContext::MockMemory(uint8_t pMemory[], size_t nBytes) +{ + m_pMemory = pMemory; + m_mMemoryValues.clear(); + + ClearMemoryBlocks(); + AddMemoryBlock(0, nBytes, ReadMemoryHelper, WriteMemoryHelper); + + if (ra::services::ServiceLocator::Exists()) + { + auto* pClient = ra::services::ServiceLocator::Get().GetClient(); + auto* pGame = pClient->game; + if (pGame && pGame->max_valid_address == 0U) + pGame->max_valid_address = gsl::narrow_cast(nBytes); + } +} + +void MockEmulatorMemoryContext::MockTotalMemorySizeChanged(size_t nNewSize) +{ + m_nTotalMemorySize = nNewSize; + + if (m_vNotifyTargets.LockIfNotEmpty()) + { + for (auto& target : m_vNotifyTargets.Targets()) + target.OnTotalMemorySizeChanged(); + + m_vNotifyTargets.Unlock(); + } +} + +uint8_t MockEmulatorMemoryContext::ReadMemoryHelper(uint32_t nAddress) +{ + const auto* mockEmulator = + dynamic_cast(&ra::services::ServiceLocator::Get()); + + if (!mockEmulator) + return 0; + + if (!mockEmulator->m_mMemoryValues.empty()) + { + auto iter = mockEmulator->m_mMemoryValues.lower_bound(nAddress); + if (iter != mockEmulator->m_mMemoryValues.end() && nAddress == iter->first) + return iter->second & 0xFF; + + if (iter != mockEmulator->m_mMemoryValues.begin()) + { + --iter; + if (nAddress - iter->first < 4) + { + uint32_t nValue = iter->second; + while (nAddress > iter->first) + { + nValue >>= 8; + nAddress--; + } + + return nValue & 0xFF; + } + } + + return 0; + } + + if (nAddress >= mockEmulator->m_nTotalMemorySize) + return 0; + + return mockEmulator->m_pMemory[nAddress]; +} + +void MockEmulatorMemoryContext::WriteMemoryHelper(uint32_t nAddress, uint8_t nValue) +{ + const auto* mockEmulator = + dynamic_cast(&ra::services::ServiceLocator::GetMutable()); + + if (!mockEmulator) + return; + + if (nAddress < mockEmulator->m_nTotalMemorySize) + mockEmulator->m_pMemory[nAddress] = nValue; +} + +} // namespace mocks +} // namespace context +} // namespace ra diff --git a/tests/devkit/context/mocks/MockEmulatorMemoryContext.hh b/tests/devkit/context/mocks/MockEmulatorMemoryContext.hh new file mode 100644 index 000000000..026f6ebf6 --- /dev/null +++ b/tests/devkit/context/mocks/MockEmulatorMemoryContext.hh @@ -0,0 +1,75 @@ +#ifndef RA_CONTEXT_MOCK_EMULATORMEMORYCONTEXT_HH +#define RA_CONTEXT_MOCK_EMULATORMEMORYCONTEXT_HH +#pragma once + +#include "context/impl/EmulatorMemoryContext.hh" + +#include "services/ServiceLocator.hh" + +#pragma warning(push) +#pragma warning(disable: 26440) +#include +#pragma warning(pop) + +#include + +namespace ra { +namespace context { +namespace mocks { + +class MockEmulatorMemoryContext : public impl::EmulatorMemoryContext +{ +public: + MockEmulatorMemoryContext() noexcept + : m_Override(this) + { + } + + template + void MockMemory(std::array& arr) + { + MockMemory(arr.data(), N); + } + + void MockMemory(uint8_t pMemory[], size_t nBytes); + + /// + /// Mocks a specific memory address without having to allocate the entire memory space + /// + void MockMemoryValue(uint32_t nAddress, uint32_t nValue) + { + m_mMemoryValues[nAddress] = nValue; + + if (gsl::narrow_cast(nAddress) + 4 > m_nTotalMemorySize) + { + const size_t nNewMemorySize = gsl::narrow_cast(nAddress) + 4; + ClearMemoryBlocks(); + AddMemoryBlock(0, nNewMemorySize, ReadMemoryHelper, WriteMemoryHelper); + } + } + + void MockMemoryModified(bool bModified) noexcept + { + m_bMemoryModified = bModified; + } + + void MockTotalMemorySizeChanged(size_t nNewSize); + + void MockMemoryInsecure(bool bValue) noexcept { m_bMemoryInsecure = bValue; } + bool IsMemoryInsecure() const noexcept override { return m_bMemoryInsecure; } + +private: + static uint8_t ReadMemoryHelper(uint32_t nAddress); + static void WriteMemoryHelper(uint32_t nAddress, uint8_t nValue); + + ra::services::ServiceLocator::ServiceOverride m_Override; + uint8_t* m_pMemory = nullptr; + + std::map m_mMemoryValues; +}; + +} // namespace mocks +} // namespace context +} // namespace ra + +#endif // !RA_CONTEXT_MOCK_EMULATORMEMORYCONTEXT_HH diff --git a/tests/mocks/MockClock.hh b/tests/devkit/services/mocks/MockClock.hh similarity index 100% rename from tests/mocks/MockClock.hh rename to tests/devkit/services/mocks/MockClock.hh diff --git a/tests/devkit/services/mocks/MockDebuggerDetector.hh b/tests/devkit/services/mocks/MockDebuggerDetector.hh new file mode 100644 index 000000000..8d4ec16e4 --- /dev/null +++ b/tests/devkit/services/mocks/MockDebuggerDetector.hh @@ -0,0 +1,33 @@ +#ifndef RA_SERVICES_MOCK_DEBUGGER_DETECTOR_HH +#define RA_SERVICES_MOCK_DEBUGGER_DETECTOR_HH +#pragma once + +#include "services/IDebuggerDetector.hh" +#include "services/ServiceLocator.hh" + +namespace ra { +namespace services { +namespace mocks { + +class MockDebuggerDetector : public IDebuggerDetector +{ +public: + explicit MockDebuggerDetector() noexcept + : m_Override(this) + { + } + + bool IsDebuggerPresent() const noexcept override { return m_bDebuggerPresent; } + void SetDebuggerPresent(bool bValue) noexcept { m_bDebuggerPresent = bValue; } + +private: + ra::services::ServiceLocator::ServiceOverride m_Override; + + bool m_bDebuggerPresent = false; +}; + +} // namespace mocks +} // namespace services +} // namespace ra + +#endif // !RA_SERVICES_MOCK_DEBUGGER_DETECTOR_HH diff --git a/tests/mocks/MockAchievementRuntime.cpp b/tests/mocks/MockAchievementRuntime.cpp index 8c22d22df..b08a91880 100644 --- a/tests/mocks/MockAchievementRuntime.cpp +++ b/tests/mocks/MockAchievementRuntime.cpp @@ -315,17 +315,6 @@ namespace data { namespace context { namespace mocks { -void MockEmulatorContext::SetRuntimeMemorySize(size_t nBytes) -{ - if (ra::services::ServiceLocator::Exists()) - { - auto* pClient = ra::services::ServiceLocator::Get().GetClient(); - auto* pGame = pClient->game; - if (pGame && pGame->max_valid_address == 0U) - pGame->max_valid_address = gsl::narrow_cast(nBytes); - } -} - void MockGameContext::InitializeFromAchievementRuntime() { auto* pMockRuntime = dynamic_cast( diff --git a/tests/mocks/MockEmulatorContext.hh b/tests/mocks/MockEmulatorContext.hh index 3198d45d7..6676fa078 100644 --- a/tests/mocks/MockEmulatorContext.hh +++ b/tests/mocks/MockEmulatorContext.hh @@ -81,113 +81,13 @@ public: return true; } - void MockMemory(gsl::span pMemory) - { - m_pMemory = pMemory; - m_mMemoryValues.clear(); - - ClearMemoryBlocks(); - AddMemoryBlock(0, m_pMemory.size_bytes(), ReadMemoryHelper, WriteMemoryHelper); - - SetRuntimeMemorySize(m_pMemory.size_bytes()); - } - - void MockMemory(unsigned char pMemory[], size_t nBytes) - { - m_pMemory = gsl::make_span(pMemory, nBytes); - m_mMemoryValues.clear(); - - ClearMemoryBlocks(); - AddMemoryBlock(0, nBytes, ReadMemoryHelper, WriteMemoryHelper); - - SetRuntimeMemorySize(nBytes); - } - - void MockMemoryValue(uint32_t nAddress, uint32_t nValue) - { - m_mMemoryValues[nAddress] = nValue; - - if (gsl::narrow_cast(nAddress) + 4 > m_nTotalMemorySize) - { - const size_t nNewMemorySize = gsl::narrow_cast(nAddress) + 4; - ClearMemoryBlocks(); - AddMemoryBlock(0, nNewMemorySize, ReadMemoryHelper, WriteMemoryHelper); - } - } - - void MockMemoryModified(bool bModified) noexcept - { - m_bMemoryModified = bModified; - } - - void MockTotalMemorySizeChanged(size_t nNewSize) - { - m_nTotalMemorySize = nNewSize; - OnTotalMemorySizeChanged(); - } - - void MockMemoryInsecure(bool bValue) noexcept { m_bMemoryInsecure = bValue; } - bool IsMemoryInsecure() const noexcept override { return m_bMemoryInsecure; } - private: - static uint8_t ReadMemoryHelper(uint32_t nAddress) - { - const auto* mockEmulator = - dynamic_cast(&ra::services::ServiceLocator::Get()); - - if (!mockEmulator) - return 0; - - if (!mockEmulator->m_mMemoryValues.empty()) - { - auto iter = mockEmulator->m_mMemoryValues.lower_bound(nAddress); - if (iter != mockEmulator->m_mMemoryValues.end() && nAddress == iter->first) - return iter->second & 0xFF; - - if (iter != mockEmulator->m_mMemoryValues.begin()) - { - --iter; - if (nAddress - iter->first < 4) - { - uint32_t nValue = iter->second; - while (nAddress > iter->first) - { - nValue >>= 8; - nAddress--; - } - - return nValue & 0xFF; - } - } - - return 0; - } - - return mockEmulator->m_pMemory.at(nAddress); - } - - static void WriteMemoryHelper(uint32_t nAddress, uint8_t nValue) - { - auto* mockEmulator = - dynamic_cast(&ra::services::ServiceLocator::GetMutable()); - - if (!mockEmulator) - return; - - mockEmulator->m_pMemory.at(nAddress) = nValue; - } - - static void SetRuntimeMemorySize(size_t nBytes); - bool m_bInvalid = false; std::string m_sWarnDisableHardcoreActivity; ra::ui::DialogResult m_nWarnDisableHardcoreResult = ra::ui::DialogResult::No; ra::services::ServiceLocator::ServiceOverride m_Override; - gsl::span m_pMemory; - - std::map m_mMemoryValues; }; } // namespace mocks diff --git a/tests/mocks/MockGameContext.hh b/tests/mocks/MockGameContext.hh index 9c0539618..068000ce8 100644 --- a/tests/mocks/MockGameContext.hh +++ b/tests/mocks/MockGameContext.hh @@ -103,8 +103,8 @@ public: auto* pNote = const_cast(pCodeNotes->FindCodeNoteModel(nAddress, false)); if (pNote && pNote->IsPointer()) { - const auto& pEmulatorContext = ra::services::ServiceLocator::Get(); - pNote->UpdateRawPointerValue(nAddress, pEmulatorContext, nullptr); + const auto& pMemoryContext = ra::services::ServiceLocator::Get(); + pNote->UpdateRawPointerValue(nAddress, pMemoryContext, nullptr); } } diff --git a/tests/services/AchievementLogicSerializer_Tests.cpp b/tests/services/AchievementLogicSerializer_Tests.cpp index d9b2cb3a0..f34e85f34 100644 --- a/tests/services/AchievementLogicSerializer_Tests.cpp +++ b/tests/services/AchievementLogicSerializer_Tests.cpp @@ -6,7 +6,7 @@ #include "tests\data\DataAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" -#include "tests\mocks\MockEmulatorContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -20,7 +20,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain) { ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::models::CodeNoteModel note; const std::wstring sNote = @@ -35,7 +35,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) L"+0x448 | [32-bit BE] Not-nested number"; note.SetNote(sNote); note.SetAddress(0x1234); - note.UpdateRawPointerValue(0x1234, mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x1234, mockEmulatorMemoryContext, nullptr); const auto* note2 = note.GetPointerNoteAtOffset(0x438); Assert::IsNotNull(note2); @@ -49,7 +49,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain24Bit) { ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; mockConsoleContext.SetId(ConsoleID::PlayStation); // 24-bit read ra::data::models::CodeNoteModel note; @@ -59,7 +59,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) L"++0x24C | [16-bit] State"; note.SetNote(sNote); note.SetAddress(0x1234); - note.UpdateRawPointerValue(0x1234, mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x1234, mockEmulatorMemoryContext, nullptr); const auto* note2 = note.GetPointerNoteAtOffset(0x428); Assert::IsNotNull(note2); @@ -73,7 +73,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain25Bit) { ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; mockConsoleContext.SetId(ConsoleID::PSP); // 25-bit read ra::data::models::CodeNoteModel note; @@ -83,7 +83,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) L"++0x24C | [16-bit] State"; note.SetNote(sNote); note.SetAddress(0x1234); - note.UpdateRawPointerValue(0x1234, mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x1234, mockEmulatorMemoryContext, nullptr); const auto* note2 = note.GetPointerNoteAtOffset(0x428); Assert::IsNotNull(note2); @@ -97,7 +97,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain25BitBE) { ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; mockConsoleContext.SetId(ConsoleID::GameCube); // 25-bit BE read ra::data::models::CodeNoteModel note; @@ -107,7 +107,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) L"++0x24C | [16-bit BE] State"; note.SetNote(sNote); note.SetAddress(0x1234); - note.UpdateRawPointerValue(0x1234, mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x1234, mockEmulatorMemoryContext, nullptr); const auto* note2 = note.GetPointerNoteAtOffset(0x428); Assert::IsNotNull(note2); @@ -121,7 +121,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChain25BitOverflowOffset) { ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; mockConsoleContext.SetId(ConsoleID::GameCube); // 25-bit BE read ra::data::models::CodeNoteModel note; @@ -131,7 +131,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) L"++0x8000024C | [16-bit BE] State"; note.SetNote(sNote); note.SetAddress(0x1234); - note.UpdateRawPointerValue(0x1234, mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x1234, mockEmulatorMemoryContext, nullptr); const auto* note2 = note.GetPointerNoteAtOffset(0x80000428); Assert::IsNotNull(note2); @@ -145,7 +145,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChainGBA) { ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; mockConsoleContext.SetId(ConsoleID::GBA); // 24-bit read with explicit offset in note ra::data::models::CodeNoteModel note; @@ -155,7 +155,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) L"++0x824C | [16-bit] State"; note.SetNote(sNote); note.SetAddress(0x1234); - note.UpdateRawPointerValue(0x1234, mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x1234, mockEmulatorMemoryContext, nullptr); const auto* note2 = note.GetPointerNoteAtOffset(0x8428); Assert::IsNotNull(note2); @@ -169,7 +169,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) TEST_METHOD(TestBuildMemRefChainNegativeOffset) { ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; mockConsoleContext.SetId(ConsoleID::GameCube); // 29-bit BE read ra::data::models::CodeNoteModel note; @@ -179,7 +179,7 @@ TEST_CLASS(AchievementLogicSerializer_Tests) L"++0x824C | [16-bit] State"; note.SetNote(sNote); note.SetAddress(0x1234); - note.UpdateRawPointerValue(0x1234, mockEmulatorContext, nullptr); + note.UpdateRawPointerValue(0x1234, mockEmulatorMemoryContext, nullptr); const auto* note2 = note.GetPointerNoteAtOffset(0xFFFFFFF8); Assert::IsNotNull(note2); diff --git a/tests/services/AchievementRuntimeExports_Tests.cpp b/tests/services/AchievementRuntimeExports_Tests.cpp index e1c05f1b6..a3f0d502a 100644 --- a/tests/services/AchievementRuntimeExports_Tests.cpp +++ b/tests/services/AchievementRuntimeExports_Tests.cpp @@ -5,6 +5,7 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" @@ -62,6 +63,7 @@ class AchievementRuntimeExportsHarness : public AchievementRuntime AchievementRuntimeExportsHarness(AchievementRuntimeExportsHarness&&) noexcept = delete; AchievementRuntimeExportsHarness& operator=(AchievementRuntimeExportsHarness&&) noexcept = delete; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::context::mocks::MockRcClient mockRcClient; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockUserContext mockUserContext; @@ -476,17 +478,17 @@ TEST_CLASS(AchievementRuntimeExports_Tests) runtime.InitializeMemoryFunctions(); Assert::AreEqual({0}, runtime.GetMemoryByte(1)); - Assert::AreEqual({0}, runtime.mockEmulatorContext.ReadMemoryByte(1)); + Assert::AreEqual({0}, runtime.mockEmulatorMemoryContext.ReadMemoryByte(1)); - runtime.mockEmulatorContext.WriteMemoryByte(1, 3); + runtime.mockEmulatorMemoryContext.WriteMemoryByte(1, 3); Assert::AreEqual({3}, runtime.GetMemoryByte(1)); - Assert::AreEqual({3}, runtime.mockEmulatorContext.ReadMemoryByte(1)); + Assert::AreEqual({3}, runtime.mockEmulatorMemoryContext.ReadMemoryByte(1)); - runtime.mockEmulatorContext.WriteMemoryByte(2, 7); + runtime.mockEmulatorMemoryContext.WriteMemoryByte(2, 7); Assert::AreEqual({7}, runtime.GetMemoryByte(2)); - Assert::AreEqual({7}, runtime.mockEmulatorContext.ReadMemoryByte(2)); - Assert::AreEqual({0x0703}, runtime.mockEmulatorContext.ReadMemory(1, ra::data::Memory::Size::SixteenBit)); + Assert::AreEqual({7}, runtime.mockEmulatorMemoryContext.ReadMemoryByte(2)); + Assert::AreEqual({0x0703}, runtime.mockEmulatorMemoryContext.ReadMemory(1, ra::data::Memory::Size::SixteenBit)); } TEST_METHOD(TestPauseEvent) diff --git a/tests/services/AchievementRuntime_Tests.cpp b/tests/services/AchievementRuntime_Tests.cpp index ca9958f15..b6957452b 100644 --- a/tests/services/AchievementRuntime_Tests.cpp +++ b/tests/services/AchievementRuntime_Tests.cpp @@ -3,12 +3,13 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\data\DataAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\services\mocks\MockHttpRequester.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAudioSystem.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" @@ -58,6 +59,7 @@ class AchievementRuntimeHarness : public AchievementRuntime rc_client_set_userdata(GetClient(), this); } + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::context::mocks::MockRcClient mockRcClient; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; @@ -688,7 +690,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{ 0x00 }; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); runtime.MockAchievement(6U, "0xH0000=1"); // expect no events for untriggered achievement @@ -712,7 +714,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{ 0x00 }; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); runtime.MockAchievement(6U, "0xH0000=1"); runtime.SetPaused(true); @@ -761,7 +763,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pAchievement = runtime.MockAchievement(6U, "0xH0000=1"); // expect no events for untriggered achievement @@ -811,7 +813,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); runtime.MockAchievement(4U, "M:0xH0002=100"); // value did not change, expect no event from initialization @@ -848,7 +850,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{ 0x00 }; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* sTrigger = "0xH0000=1"; // achievement not active, should not raise events @@ -1112,7 +1114,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pLeaderboard = runtime.MockLeaderboard(6U, "STA:0xH00=1::CAN:0xH00=2::SUB:0xH00=3::VAL:0xH02"); // expect no events for inactive leaderboard @@ -1199,7 +1201,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); Assert::IsFalse(runtime.HasRichPresence()); const char* pRichPresence = "Format:Num\nFormatType:Value\n\nDisplay:\n@Num(0xH01) @Num(d0xH01)\n"; @@ -1237,7 +1239,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); Assert::IsFalse(runtime.HasRichPresence()); runtime.ActivateRichPresence("Display:\nHello, World\n"); @@ -1258,7 +1260,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); const char* pRichPresence = "Format:Num\nFormatType:Value\n\nDisplay:\n@Num(0H01) @Num(d0xH01)\n"; runtime.ActivateRichPresence(pRichPresence); @@ -1272,7 +1274,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pAchievement = runtime.MockAchievement(6U, "0xH0000=1"); auto* vmAchievement = runtime.WrapAchievement(pAchievement); @@ -1315,7 +1317,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pAchievement = runtime.MockAchievement(4U, "1=1.3._R:0xH0000=1"); auto* vmAchievement = runtime.WrapAchievement(pAchievement); @@ -1361,7 +1363,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{ 0x00, 0x00 }; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pLeaderboard = runtime.MockLeaderboard(6U, "STA:0xH0000=0_0xH0000=9_R:0xH0001=1::SUB:0xH0000=1::CAN:0xH0000=2::VAL:0xH0000"); auto* vmLeaderboard = runtime.WrapLeaderboard(pLeaderboard); @@ -1407,7 +1409,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x00}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pLeaderboard = runtime.MockLeaderboard(6U, "STA:0xH0000=1::SUB:0xH0000=0_0xH0000=9_R:0xH0001=1::CAN:0xH0000=2::VAL:0xH0000"); auto* vmLeaderboard = runtime.WrapLeaderboard(pLeaderboard); @@ -1453,7 +1455,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x00}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pLeaderboard = runtime.MockLeaderboard(6U, "STA:0xH0000=1::SUB:0xH0000=2::CAN:0xH0000=0_0xH0000=9_R:0xH0001=1::VAL:0xH0000"); auto* vmLeaderboard = runtime.WrapLeaderboard(pLeaderboard); @@ -1499,7 +1501,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x00, 0x00}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pLeaderboard = runtime.MockLeaderboard(6U, "STA:0xH0000=0::SUB:0xH0000=2::CAN:0xH0000=3::VAL:R:0xH0001=1_M:0xH0002=0"); auto* vmLeaderboard = runtime.WrapLeaderboard(pLeaderboard); @@ -1549,7 +1551,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x00}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pLeaderboard = runtime.MockLeaderboard(6U, "STA:0xH0000=1::SUB:0xH0000=2::CAN:0xH0000=3::VAL:0xH0001"); auto* vmLeaderboard = runtime.WrapLeaderboard(pLeaderboard); @@ -1591,7 +1593,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x00}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pLeaderboard = runtime.MockLeaderboard(6U, "STA:0xH0000=1::SUB:0xH0000=2::CAN:0xH0000=3::VAL:0xH0001"); auto* vmLeaderboard = runtime.WrapLeaderboard(pLeaderboard); @@ -1638,7 +1640,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x00}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pLeaderboard = runtime.MockLeaderboard(6U, "STA:0xH0000=1::SUB:0xH0000=2::CAN:0xH0000=3::VAL:0xH0001"); auto* vmLeaderboard = runtime.WrapLeaderboard(pLeaderboard); @@ -1684,7 +1686,7 @@ TEST_CLASS(AchievementRuntime_Tests) std::array memory{0x00, 0x00}; AchievementRuntimeHarness runtime; - runtime.mockEmulatorContext.MockMemory(memory); + runtime.mockEmulatorMemoryContext.MockMemory(memory); auto* pAch6 = runtime.MockAchievement(6U, "0xH0004=1"); runtime.SyncToRuntime(); auto* vmAch6 = runtime.WrapAchievement(pAch6); @@ -2011,7 +2013,7 @@ TEST_CLASS(AchievementRuntime_Tests) auto* vmAch6 = runtime.WrapAchievement(pAch6); runtime.mockGameContext.SetRichPresenceDisplayString(L"Titles"); runtime.mockGameContext.Assets().FindRichPresence()->Activate(); - runtime.mockEmulatorContext.SetMemoryModified(); + runtime.mockEmulatorMemoryContext.SetMemoryModified(); runtime.mockConfiguration.SetPopupLocation(ra::ui::viewmodels::Popup::AchievementTriggered, ra::ui::viewmodels::PopupLocation::BottomLeft); @@ -2046,7 +2048,7 @@ TEST_CLASS(AchievementRuntime_Tests) runtime.GetClient()->state.hardcore = 1; runtime.mockGameContext.SetRichPresenceDisplayString(L"Titles"); runtime.mockGameContext.Assets().FindRichPresence()->Activate(); - runtime.mockEmulatorContext.MockMemoryInsecure(true); + runtime.mockEmulatorMemoryContext.MockMemoryInsecure(true); runtime.mockConfiguration.SetPopupLocation(ra::ui::viewmodels::Popup::AchievementTriggered, ra::ui::viewmodels::PopupLocation::BottomLeft); @@ -2083,7 +2085,7 @@ TEST_CLASS(AchievementRuntime_Tests) runtime.GetClient()->state.hardcore = 0; runtime.mockGameContext.SetRichPresenceDisplayString(L"Titles"); runtime.mockGameContext.Assets().FindRichPresence()->Activate(); - runtime.mockEmulatorContext.MockMemoryInsecure(true); + runtime.mockEmulatorMemoryContext.MockMemoryInsecure(true); runtime.mockConfiguration.SetPopupLocation(ra::ui::viewmodels::Popup::AchievementTriggered, ra::ui::viewmodels::PopupLocation::BottomLeft); @@ -2837,7 +2839,7 @@ TEST_CLASS(AchievementRuntime_Tests) auto* pLbd4 = runtime.MockLeaderboard(4U, "STA:0xH0000=1::CAN:0xH0000=1::SUB:0xH0000=2::VAL:0xH0001"); pLbd4->public_.tracker_value = "1:23.45"; runtime.WrapLeaderboard(pLbd4); - runtime.mockEmulatorContext.MockMemoryModified(true); + runtime.mockEmulatorMemoryContext.MockMemoryModified(true); runtime.mockConfiguration.SetFeatureEnabled(ra::services::Feature::Leaderboards, true); runtime.mockConfiguration.SetPopupLocation(ra::ui::viewmodels::Popup::LeaderboardScoreboard, ra::ui::viewmodels::PopupLocation::BottomRight); @@ -2898,7 +2900,7 @@ TEST_CLASS(AchievementRuntime_Tests) auto* pLbd4 = runtime.MockLeaderboard(4U, "STA:0xH0000=1::CAN:0xH0000=1::SUB:0xH0000=2::VAL:0xH0001"); pLbd4->public_.tracker_value = "1:23.45"; runtime.WrapLeaderboard(pLbd4); - runtime.mockEmulatorContext.MockMemoryInsecure(true); + runtime.mockEmulatorMemoryContext.MockMemoryInsecure(true); runtime.mockConfiguration.SetFeatureEnabled(ra::services::Feature::Leaderboards, true); runtime.mockConfiguration.SetPopupLocation(ra::ui::viewmodels::Popup::LeaderboardScoreboard, ra::ui::viewmodels::PopupLocation::BottomRight); diff --git a/tests/services/FileLocalStorage_Tests.cpp b/tests/services/FileLocalStorage_Tests.cpp index cf7f47ae2..cf394e1f3 100644 --- a/tests/services/FileLocalStorage_Tests.cpp +++ b/tests/services/FileLocalStorage_Tests.cpp @@ -1,7 +1,7 @@ #include "services\impl\FileLocalStorage.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" -#include "tests\mocks\MockClock.hh" #include "tests\RA_UnitTestHelpers.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; diff --git a/tests/services/FileLogger_Tests.cpp b/tests/services/FileLogger_Tests.cpp index 94df55b0a..1243bbf4e 100644 --- a/tests/services/FileLogger_Tests.cpp +++ b/tests/services/FileLogger_Tests.cpp @@ -1,7 +1,7 @@ #include "services\impl\FileLogger.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" -#include "tests\mocks\MockClock.hh" #include "tests\RA_UnitTestHelpers.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; diff --git a/tests/services/GameIdentifier_Tests.cpp b/tests/services/GameIdentifier_Tests.cpp index 1df0526a3..4d9b460b1 100644 --- a/tests/services/GameIdentifier_Tests.cpp +++ b/tests/services/GameIdentifier_Tests.cpp @@ -6,11 +6,12 @@ #include "tests\ui\UIAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockAudioSystem.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" @@ -74,8 +75,9 @@ class GameIdentifierHarness : public GameIdentifier } ra::api::mocks::MockServer mockServer; - ra::context::mocks::MockRcClient mockRcClient; ra::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + ra::context::mocks::MockRcClient mockRcClient; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockSessionTracker mockSessionTracker; diff --git a/tests/services/SearchResults_Tests.cpp b/tests/services/SearchResults_Tests.cpp index 1b37dcb0d..18619ad27 100644 --- a/tests/services/SearchResults_Tests.cpp +++ b/tests/services/SearchResults_Tests.cpp @@ -1,7 +1,7 @@ #include "services\SearchResults.h" #include "tests\RA_UnitTestHelpers.h" -#include "tests\mocks\MockEmulatorContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -28,8 +28,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryEightBit) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -62,8 +62,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemorySixteenBit) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 3U, ra::services::SearchType::SixteenBit); @@ -90,8 +90,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryThirtyTwoBit) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 4U, ra::services::SearchType::ThirtyTwoBit); @@ -112,8 +112,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemorySixteenBitAligned) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, 4U, ra::services::SearchType::SixteenBitAligned); @@ -141,8 +141,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryThirtyTwoBitAligned) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD, 0x44, 0x20 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, 8U, ra::services::SearchType::ThirtyTwoBitAligned); @@ -173,8 +173,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemorySixteenBitBigEndian) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 3U, ra::services::SearchType::SixteenBitBigEndian); @@ -201,8 +201,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryThirtyTwoBitBigEndian) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 4U, ra::services::SearchType::ThirtyTwoBitBigEndian); @@ -223,8 +223,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemorySixteenBitBigEndianAligned) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, 4U, ra::services::SearchType::SixteenBitBigEndianAligned); @@ -252,8 +252,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryThirtyTwoBitBigEndianAligned) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD, 0x44, 0x20 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, 8U, ra::services::SearchType::ThirtyTwoBitBigEndianAligned); @@ -284,8 +284,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryNibble) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 3U, ra::services::SearchType::FourBit); @@ -334,8 +334,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemorySixteenBitBounded) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 8U, ra::services::SearchType::SixteenBit); @@ -368,8 +368,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitEqualsConstant) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -395,8 +395,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitEqualsInvalidConstant) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -414,8 +414,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitEqualsConstantGap) { std::array memory{ 0x00, 0x12, 0x00, 0x00, 0x56, 0x00 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 6U, ra::services::SearchType::EightBit); @@ -458,8 +458,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitNotEqualsConstant) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -490,8 +490,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitNotEqualsConstantGap) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -522,8 +522,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitGreaterThanConstant) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -549,8 +549,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitGreaterThanOrEqualConstant) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -581,8 +581,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitLessThanConstant) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -608,8 +608,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitLessThanOrEqualConstant) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -640,8 +640,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitEqualsConstantModified) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -670,8 +670,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitEqualsPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 5U, ra::services::SearchType::EightBit); @@ -727,8 +727,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitNotEqualsPrevious) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -766,10 +766,10 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitNotEqualsPreviousLargeData) { std::array memory{}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; for (unsigned int i = 0; i < memory.size(); ++i) GSL_SUPPRESS_BOUNDS4 memory[i] = (i % 256); - mockEmulatorContext.MockMemory(memory); + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 1024U, ra::services::SearchType::EightBit); @@ -821,8 +821,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitEqualsPreviousPlusTwo) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -855,8 +855,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitEqualsPreviousMinusTwo) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -889,8 +889,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsEightBitGreaterThanPreviousPlusTwo) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -918,8 +918,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsSixteenBitNotEqualPrevious) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 4U, ra::services::SearchType::SixteenBit); @@ -950,8 +950,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsThirtyTwoBitNotEqualPrevious) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 5U, ra::services::SearchType::ThirtyTwoBit); @@ -975,8 +975,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsSixteenBitAlignedNotEqualPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 4U, ra::services::SearchType::SixteenBitAligned); @@ -1019,8 +1019,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsThirtyTwoBitAlignedNotEqualPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD, 0x44, 0x20 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 8U, ra::services::SearchType::ThirtyTwoBitAligned); @@ -1066,8 +1066,8 @@ TEST_CLASS(SearchResults_Tests) auto memory = std::move(std::make_unique(BIG_BLOCK_SIZE)); for (unsigned int i = 0; i < BIG_BLOCK_SIZE; ++i) GSL_SUPPRESS_BOUNDS4 memory[i] = (i % 256); - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory.get(), BIG_BLOCK_SIZE); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory.get(), BIG_BLOCK_SIZE); SearchResults results; results.Initialize(0U, BIG_BLOCK_SIZE, ra::services::SearchType::ThirtyTwoBitAligned); @@ -1113,8 +1113,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsThirtyTwoBitAlignedOffset) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD, 0x44, 0x20, 0x11, 0x22, 0x33, 0x44 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(4U, 12U, ra::services::SearchType::ThirtyTwoBitAligned); @@ -1147,8 +1147,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsSixteenBitBigEndianNotEqualPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 4U, ra::services::SearchType::SixteenBitBigEndian); @@ -1179,8 +1179,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsThirtyTwoBitBigEndianNotEqualPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 5U, ra::services::SearchType::ThirtyTwoBitBigEndian); @@ -1204,8 +1204,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsThirtyTwoBitBigEndianLessThanPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 5U, ra::services::SearchType::ThirtyTwoBitBigEndian); @@ -1229,8 +1229,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsSixteenBitBigEndianAlignedNotEqualPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 4U, ra::services::SearchType::SixteenBitBigEndianAligned); @@ -1273,8 +1273,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsThirtyTwoBitBigEndianAlignedNotEqualPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0xCD, 0x44, 0x20 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 8U, ra::services::SearchType::ThirtyTwoBitBigEndianAligned); @@ -1317,8 +1317,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsFourBitNotEqualsPrevious) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::FourBit); @@ -1356,8 +1356,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsFourBitEqualsSameByte) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 3U, ra::services::SearchType::FourBit); @@ -1394,8 +1394,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsWithAddressLimits) { std::array memory{0x00, 0x12, 0x04, 0x16, 0x08}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 5U, ra::services::SearchType::EightBit); @@ -1433,8 +1433,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestExcludeAddressEightBit) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -1475,8 +1475,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestExcludeAddressFourBit) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::FourBit); @@ -1532,8 +1532,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestExcludeAddressSixteenBitAligned) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56, 0x88 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 5U, ra::services::SearchType::SixteenBitAligned); @@ -1576,8 +1576,8 @@ TEST_CLASS(SearchResults_Tests) auto memory = std::make_unique(BIG_BLOCK_SIZE); for (unsigned int i = 0; i < BIG_BLOCK_SIZE; ++i) GSL_SUPPRESS_BOUNDS4 memory[i] = (i % 256); - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory.get(), BIG_BLOCK_SIZE); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory.get(), BIG_BLOCK_SIZE); SearchResults results; results.Initialize(0U, BIG_BLOCK_SIZE, ra::services::SearchType::EightBit); @@ -1613,8 +1613,8 @@ TEST_CLASS(SearchResults_Tests) auto memory = std::make_unique(BIG_BLOCK_SIZE); for (unsigned int i = 0; i < BIG_BLOCK_SIZE; ++i) GSL_SUPPRESS_BOUNDS4 memory[i] = (i % 256); - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory.get(), BIG_BLOCK_SIZE); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory.get(), BIG_BLOCK_SIZE); SearchResults results; results.Initialize(0U, BIG_BLOCK_SIZE, ra::services::SearchType::SixteenBit); @@ -1648,8 +1648,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemorySixteenBitZeroBytes) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, 0U, ra::services::SearchType::SixteenBit); @@ -1664,8 +1664,8 @@ TEST_CLASS(SearchResults_Tests) 'l', 'l', 's', ' ', 'b', 'y', ' ', 't', 'h', 'e', ' ', 's', 'e', 'a', 's', 'h', 'o', 'r', 'e', '.' }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::AsciiText); @@ -1694,8 +1694,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryFloat) { std::array memory{ 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x46, 0x41 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Float); @@ -1726,8 +1726,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryFloatAligned) { std::array memory{ 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x46, 0x41 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::FloatAligned); @@ -1758,8 +1758,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryFloatBE) { std::array memory{ 0xC0, 0x00, 0x00, 0x00, 0x41, 0x46, 0x00, 0x00 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::FloatBigEndian); @@ -1790,8 +1790,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryFloatBEAligned) { std::array memory{ 0xC0, 0x00, 0x00, 0x00, 0x41, 0x46, 0x00, 0x00 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::FloatBigEndianAligned); @@ -1823,8 +1823,8 @@ TEST_CLASS(SearchResults_Tests) { std::array memory{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, // -2.0 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x28, 0x40}; // 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Double32); @@ -1858,8 +1858,8 @@ TEST_CLASS(SearchResults_Tests) { std::array memory{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, // -2.0 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x28, 0x40}; // 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Double32Aligned); @@ -1893,8 +1893,8 @@ TEST_CLASS(SearchResults_Tests) { std::array memory{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // -2.0 0x40, 0x28, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00}; // 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Double32BigEndian); @@ -1928,8 +1928,8 @@ TEST_CLASS(SearchResults_Tests) { std::array memory{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // -2.0 0x40, 0x28, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00}; // 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Double32BigEndianAligned); @@ -1962,8 +1962,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryMBF32) { std::array memory{ 0x87, 0x46, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00 }; // 99.0, -0.5 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::MBF32); @@ -1994,8 +1994,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryMBF32LE) { std::array memory{ 0x00, 0x00, 0x46, 0x87, 0x00, 0x00, 0x80, 0x80 }; // 99.0, -0.5 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::MBF32LE); @@ -2030,8 +2030,8 @@ TEST_CLASS(SearchResults_Tests) 'l', 'l', 's', ' ', 'b', 'y', ' ', 't', 'h', 'e', ' ', 's', 'e', 'a', 's', 'h', 'o', 'r', 'e', '.' }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, memory.size(), ra::services::SearchType::AsciiText); @@ -2078,8 +2078,8 @@ TEST_CLASS(SearchResults_Tests) 'l', 'l', 's', ' ', 'b', 'y', ' ', 't', 'h', 'e', ' ', 's', 'e', 'a', 's', 'h', 'o', 'r', 'e', '.' }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, memory.size(), ra::services::SearchType::AsciiText); @@ -2102,8 +2102,8 @@ TEST_CLASS(SearchResults_Tests) 'l', 'l', 's', ' ', 'b', 'y', ' ', 't', 'h', 'e', ' ', 's', 'e', 'a', 's', 'h', 'o', 'r', 'e', '.' }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, memory.size(), ra::services::SearchType::AsciiText); @@ -2173,8 +2173,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsFloatEqualsConstant) { std::array memory{ 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x46, 0x41 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Float); @@ -2195,8 +2195,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsFloatGreaterThanLast) { std::array memory{ 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x46, 0x41 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Float); @@ -2220,8 +2220,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsFloatAlignedGreaterThanLast) { std::array memory{ 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x46, 0x41 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::FloatAligned); @@ -2245,8 +2245,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsFloatBEGreaterThanLast) { std::array memory{ 0xC0, 0x00, 0x00, 0x00, 0x41, 0x46, 0x00, 0x00 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::FloatBigEndian); @@ -2271,8 +2271,8 @@ TEST_CLASS(SearchResults_Tests) { std::array memory{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, // -2.0 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x28, 0x40}; // 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Double32Aligned); @@ -2297,8 +2297,8 @@ TEST_CLASS(SearchResults_Tests) { std::array memory{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // -2.0 0x40, 0x28, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00}; // 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::Double32BigEndianAligned); @@ -2322,8 +2322,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsMBF32EqualsConstant) { std::array memory{ 0x87, 0x46, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00 }; // 99.0, -0.5 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::MBF32); @@ -2344,8 +2344,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsMBF32GreaterThanLast) { std::array memory{ 0x87, 0x46, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00 }; // 99.0, -0.5 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::MBF32); @@ -2368,8 +2368,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsMBF32LEEqualsConstant) { std::array memory{ 0x00, 0x00, 0x46, 0x87, 0x00, 0x00, 0x80, 0x80 }; // 99.0, -0.5 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::MBF32LE); @@ -2390,8 +2390,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsMBF32LEGreaterThanLast) { std::array memory{ 0x00, 0x00, 0x46, 0x87, 0x00, 0x00, 0x80, 0x80 }; // 99.0, -0.5 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(0U, memory.size(), ra::services::SearchType::MBF32LE); @@ -2414,8 +2414,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestCopyConstructor) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -2456,8 +2456,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestGetFormattedValueEightBit) { std::array memory{ 0x00, 0x02, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -2472,8 +2472,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestGetFormattedValueSixteenBit) { std::array memory{ 0x00, 0x02, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::SixteenBit); @@ -2488,8 +2488,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestGetFormattedValueFourBit) { std::array memory{ 0x00, 0x02, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(1U, 3U, ra::services::SearchType::FourBit); @@ -2510,8 +2510,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestGetFormattedValueFloat) { std::array memory{ 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x46, 0x41 }; // -2.0, 12.375 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 8U, ra::services::SearchType::Float); @@ -2526,8 +2526,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestGetFormattedValueMBF32) { std::array memory{ 0x87, 0x46, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00 }; // 99.0, -0.5 - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 8U, ra::services::SearchType::MBF32); @@ -2542,8 +2542,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestMatchesFilterEightBitGreaterThanLast) { std::array memory{ 6, 12, 18, 24, 30 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1, results2; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -2571,8 +2571,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestMatchesFilterEightBitGreaterThanLastPlus) { std::array memory{ 6, 12, 18, 24, 30 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1, results2; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -2600,8 +2600,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestMatchesFilterEightBitGreaterThanLastMinus) { std::array memory{ 6, 12, 18, 24, 30 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1, results2; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -2629,8 +2629,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestMatchesFilterEightBitGreaterThanConstant) { std::array memory{ 6, 12, 18, 24, 30 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1, results2; results1.Initialize(1U, 3U, ra::services::SearchType::EightBit); @@ -2649,8 +2649,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryAsciiEmpty) { - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - Assert::AreEqual({0U}, mockEmulatorContext.TotalMemorySize()); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + Assert::AreEqual({0U}, mockMemoryContext.TotalMemorySize()); SearchResults results; results.Initialize(0U, 16, ra::services::SearchType::AsciiText); @@ -2663,8 +2663,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromMemoryBitCount) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results; results.Initialize(1U, 3U, ra::services::SearchType::BitCount); @@ -2697,8 +2697,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsBitCountEqualsPrevious) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 5U, ra::services::SearchType::BitCount); @@ -2743,8 +2743,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromResultsBitCountEqualsPreviousPlusOne) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 5U, ra::services::SearchType::BitCount); @@ -2773,8 +2773,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestGetFormattedValueBitCount) { std::array memory{ 0x00, 0x12, 0x34, 0xAB, 0x56 }; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); SearchResults results1; results1.Initialize(0U, 8U, ra::services::SearchType::BitCount); @@ -2791,15 +2791,15 @@ TEST_CLASS(SearchResults_Tests) std::wstring sFormattedValue; SearchResult pResult; results1.GetMatchingAddress(3, pResult); - Assert::IsTrue(results1.UpdateValue(pResult, &sFormattedValue, mockEmulatorContext)); + Assert::IsTrue(results1.UpdateValue(pResult, &sFormattedValue, mockMemoryContext)); Assert::AreEqual(std::wstring(L"5 (00111011)"), sFormattedValue); } TEST_METHOD(TestInitializeFromListEightBit) { std::array memory{0x00, 0x12, 0x34, 0xAB, 0x56}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); std::vector vResults; vResults.push_back({2, 0x07, ra::data::Memory::Size::Unknown}); @@ -2831,8 +2831,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromListThirtyTwoBit) { std::array memory{}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); std::vector vResults; vResults.push_back({2, 0x12345678, ra::data::Memory::Size::Unknown}); @@ -2870,8 +2870,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromListThirtyTwoBitAligned) { std::array memory{}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); std::vector vResults; vResults.push_back({2, 0x12345678, ra::data::Memory::Size::Unknown}); // not aligned - should be ignored @@ -2904,8 +2904,8 @@ TEST_CLASS(SearchResults_Tests) TEST_METHOD(TestInitializeFromListThirtyTwoBitBigEndian) { std::array memory{}; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; - mockEmulatorContext.MockMemory(memory); + ra::context::mocks::MockEmulatorMemoryContext mockMemoryContext; + mockMemoryContext.MockMemory(memory); std::vector vResults; vResults.push_back({2, 0x12345678, ra::data::Memory::Size::Unknown}); diff --git a/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp b/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp index e3ad578a7..4c5e98cc4 100644 --- a/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp +++ b/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp @@ -11,12 +11,13 @@ #include "tests\data\DataAsserts.hh" #include "tests\ui\viewmodels\TriggerConditionAsserts.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockClipboard.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" @@ -65,6 +66,7 @@ TEST_CLASS(AssetEditorViewModel_Tests) AssetEditorViewModelHarness(AssetEditorViewModelHarness&&) noexcept = delete; AssetEditorViewModelHarness& operator=(AssetEditorViewModelHarness&&) noexcept = delete; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::context::mocks::MockRcClient mockRcClient; ra::services::mocks::MockAchievementRuntime mockRuntime; ra::services::mocks::MockClock mockClock; diff --git a/tests/ui/viewmodels/AssetListViewModel_Tests.cpp b/tests/ui/viewmodels/AssetListViewModel_Tests.cpp index eff493259..ecb0da28e 100644 --- a/tests/ui/viewmodels/AssetListViewModel_Tests.cpp +++ b/tests/ui/viewmodels/AssetListViewModel_Tests.cpp @@ -14,11 +14,12 @@ #include "tests\data\DataAsserts.hh" #include "tests\ui\UIAsserts.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" @@ -160,6 +161,7 @@ TEST_CLASS(AssetListViewModel_Tests) class AssetListViewModelHarness : public AssetListViewModel { public: + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::context::mocks::MockRcClient mockRcClient; ra::services::mocks::MockAchievementRuntime mockRuntime; ra::services::mocks::MockClock mockClock; @@ -5489,17 +5491,17 @@ TEST_CLASS(AssetListViewModel_Tests) AssetListViewModelHarness vmAssetList; Assert::IsTrue(vmAssetList.IsProcessingActive()); Assert::IsFalse(vmAssetList.mockRuntime.IsPaused()); - Assert::IsFalse(vmAssetList.mockEmulatorContext.WasMemoryModified()); + Assert::IsFalse(vmAssetList.mockEmulatorMemoryContext.WasMemoryModified()); vmAssetList.SetProcessingActive(false); Assert::IsFalse(vmAssetList.IsProcessingActive()); Assert::IsTrue(vmAssetList.mockRuntime.IsPaused()); - Assert::IsTrue(vmAssetList.mockEmulatorContext.WasMemoryModified()); + Assert::IsTrue(vmAssetList.mockEmulatorMemoryContext.WasMemoryModified()); vmAssetList.SetProcessingActive(true); Assert::IsTrue(vmAssetList.IsProcessingActive()); Assert::IsFalse(vmAssetList.mockRuntime.IsPaused()); - Assert::IsTrue(vmAssetList.mockEmulatorContext.WasMemoryModified()); + Assert::IsTrue(vmAssetList.mockEmulatorMemoryContext.WasMemoryModified()); } TEST_METHOD(TestOpenEditorNonHardcore) diff --git a/tests/ui/viewmodels/CodeNotesViewModel_Tests.cpp b/tests/ui/viewmodels/CodeNotesViewModel_Tests.cpp index a17602a77..b9fab6060 100644 --- a/tests/ui/viewmodels/CodeNotesViewModel_Tests.cpp +++ b/tests/ui/viewmodels/CodeNotesViewModel_Tests.cpp @@ -7,11 +7,11 @@ #include "tests\ui\UIAsserts.hh" #include "tests\RA_UnitTestHelpers.h" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockLocalStorage.hh" #include "tests\mocks\MockServer.hh" @@ -33,7 +33,7 @@ TEST_CLASS(CodeNotesViewModel_Tests) public: ra::api::mocks::MockServer mockServer; ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockConfiguration mockConfiguration; @@ -75,7 +75,7 @@ TEST_CLASS(CodeNotesViewModel_Tests) std::array memory = {}; for (uint8_t i = 0; i < memory.size(); ++i) memory.at(i) = i; - mockEmulatorContext.MockMemory(memory); + mockEmulatorMemoryContext.MockMemory(memory); } void PreparePublish() diff --git a/tests/ui/viewmodels/IntegrationMenuViewModel_Tests.cpp b/tests/ui/viewmodels/IntegrationMenuViewModel_Tests.cpp index 2dec8b356..40c9be02d 100644 --- a/tests/ui/viewmodels/IntegrationMenuViewModel_Tests.cpp +++ b/tests/ui/viewmodels/IntegrationMenuViewModel_Tests.cpp @@ -18,6 +18,7 @@ #include "tests\data\DataAsserts.hh" #include "tests\ui\UIAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" @@ -45,8 +46,9 @@ TEST_CLASS(IntegrationMenuViewModel_Tests) { public: ra::api::mocks::MockServer mockServer; - ra::context::mocks::MockRcClient mockRcClient; ra::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; + ra::context::mocks::MockRcClient mockRcClient; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; diff --git a/tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp index bb64af75d..95ef719e2 100644 --- a/tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryBookmarksViewModel_Tests.cpp @@ -7,13 +7,13 @@ #include "tests\ui\UIAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockFrameEventQueue.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockLocalStorage.hh" @@ -60,8 +60,8 @@ TEST_CLASS(MemoryBookmarksViewModel_Tests) class MemoryBookmarksViewModelHarness : public MemoryBookmarksViewModel { public: + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorContext; ra::context::mocks::MockRcClient mockRcClient; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; diff --git a/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp index a8e2e5e52..49bf13036 100644 --- a/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryInspectorViewModel_Tests.cpp @@ -9,13 +9,13 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockLocalStorage.hh" #include "tests\mocks\MockUserContext.hh" @@ -38,7 +38,7 @@ TEST_CLASS(MemoryInspectorViewModel_Tests) ra::api::mocks::MockServer mockServer; ra::context::mocks::MockRcClient mockRcClient; ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockConfiguration mockConfiguration; diff --git a/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp index 8212947d9..6b7d3719b 100644 --- a/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryRegionsViewModel_Tests.cpp @@ -4,6 +4,7 @@ #include "ui\viewmodels\MemoryRegionsViewModel.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\ui\UIAsserts.hh" #include "tests\RA_UnitTestHelpers.h" #include "tests\mocks\MockConfiguration.hh" @@ -27,6 +28,7 @@ TEST_CLASS(MemoryRegionsViewModel_Tests) { public: ra::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::services::mocks::MockConfiguration mockConfiguration; diff --git a/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp b/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp index 726351e31..ea3a826d2 100644 --- a/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp @@ -7,12 +7,12 @@ #include "tests\ui\UIAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockUserContext.hh" #include "tests\mocks\MockWindowManager.hh" @@ -90,7 +90,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) } ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockClock mockClock; @@ -106,7 +106,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) for (size_t i = 0; i < memory.size(); ++i) memory.at(i) = gsl::narrow_cast(i); - mockEmulatorContext.MockMemory(memory); + mockEmulatorMemoryContext.MockMemory(memory); } void InitializeAsciiMemory() @@ -119,7 +119,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) for (size_t i = 0; i < memory.size(); ++i) memory.at(i) = text.at(i); - mockEmulatorContext.MockMemory(memory); + mockEmulatorMemoryContext.MockMemory(memory); } bool CanBeginNewSearch() const { return GetValue(CanBeginNewSearchProperty); } @@ -1393,7 +1393,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) // only system range defined MemorySearchViewModelHarness search; search.mockConsoleContext.AddMemoryRegion(0U, 0xFFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 2U }, search.PredefinedFilterRanges().Count()); Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId()); @@ -1408,7 +1408,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) MemorySearchViewModelHarness search; search.mockConsoleContext.AddMemoryRegion(0U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM"); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 4U }, search.PredefinedFilterRanges().Count()); Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId()); @@ -1429,7 +1429,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) search.mockConsoleContext.AddMemoryRegion(0x8000U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM"); search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM"); search.mockConsoleContext.AddMemoryRegion(0xF000U, 0xFFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM"); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 4U }, search.PredefinedFilterRanges().Count()); Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId()); @@ -1450,7 +1450,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) search.mockConsoleContext.AddMemoryRegion(0x8000U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM 2"); search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM 1"); search.mockConsoleContext.AddMemoryRegion(0xF000U, 0xFFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM 2"); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 8U }, search.PredefinedFilterRanges().Count()); Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId()); @@ -1491,7 +1491,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) search.mockConsoleContext.AddMemoryRegion(0xFF00U, 0xFF7FU, ra::data::MemoryRegion::Type::HardwareController, L"Hardware I/O"); search.mockConsoleContext.AddMemoryRegion(0xFF80U, 0xFFFEU, ra::data::MemoryRegion::Type::SystemRAM, L"Quick RAM"); search.mockConsoleContext.AddMemoryRegion(0xFFFFU, 0xFFFFU, ra::data::MemoryRegion::Type::HardwareController, L"Interrupt Enable"); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); Assert::AreEqual({ 6U }, search.PredefinedFilterRanges().Count()); Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId()); @@ -1513,7 +1513,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) MemorySearchViewModelHarness search; search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM); search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); search.SetFilterRange(L"0x0000-0x1FFF"); search.SetPredefinedFilterRange(0); @@ -1525,7 +1525,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) MemorySearchViewModelHarness search; search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM); search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); search.SetFilterRange(L"0x0000-0x1FFF"); search.SetPredefinedFilterRange(1); @@ -1537,7 +1537,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) MemorySearchViewModelHarness search; search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM); search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); search.SetFilterRange(L"0x0000-0x1FFF"); search.SetPredefinedFilterRange(2); @@ -1549,7 +1549,7 @@ TEST_CLASS(MemorySearchViewModel_Tests) MemorySearchViewModelHarness search; search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM); search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM); - search.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000U); + search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U); search.SetFilterRange(L"0x0000-0x1FFF"); search.SetPredefinedFilterRange(0); diff --git a/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp index 65bc8d297..b3f769816 100644 --- a/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp @@ -6,6 +6,7 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" @@ -34,7 +35,7 @@ TEST_CLASS(MemoryViewerViewModel_Tests) { public: ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::ui::viewmodels::mocks::MockWindowManager mockWindowManager; diff --git a/tests/ui/viewmodels/MemoryWatchListViewModel_Tests.cpp b/tests/ui/viewmodels/MemoryWatchListViewModel_Tests.cpp index b1ae67cfb..1bd7ac4f6 100644 --- a/tests/ui/viewmodels/MemoryWatchListViewModel_Tests.cpp +++ b/tests/ui/viewmodels/MemoryWatchListViewModel_Tests.cpp @@ -6,13 +6,13 @@ #include "tests\ui\UIAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockAchievementRuntime.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockFrameEventQueue.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockLocalStorage.hh" @@ -32,8 +32,8 @@ TEST_CLASS(MemoryWatchListViewModel_Tests) class MemoryWatchListViewModelHarness : public MemoryWatchListViewModel { public: + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorContext; ra::context::mocks::MockRcClient mockRcClient; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::context::mocks::MockConsoleContext mockConsoleContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; diff --git a/tests/ui/viewmodels/OverlayAchievementsPageViewModel_Tests.cpp b/tests/ui/viewmodels/OverlayAchievementsPageViewModel_Tests.cpp index d59799290..71a0ab31e 100644 --- a/tests/ui/viewmodels/OverlayAchievementsPageViewModel_Tests.cpp +++ b/tests/ui/viewmodels/OverlayAchievementsPageViewModel_Tests.cpp @@ -3,9 +3,9 @@ #include "ui\viewmodels\OverlayAchievementsPageViewModel.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockImageRepository.hh" #include "tests\mocks\MockOverlayManager.hh" diff --git a/tests/ui/viewmodels/OverlayFriendsPageViewModel_Tests.cpp b/tests/ui/viewmodels/OverlayFriendsPageViewModel_Tests.cpp index c2e3b4219..ff18494e5 100644 --- a/tests/ui/viewmodels/OverlayFriendsPageViewModel_Tests.cpp +++ b/tests/ui/viewmodels/OverlayFriendsPageViewModel_Tests.cpp @@ -2,8 +2,8 @@ #include "ui\viewmodels\OverlayFriendsPageViewModel.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockImageRepository.hh" #include "tests\mocks\MockOverlayManager.hh" #include "tests\mocks\MockServer.hh" diff --git a/tests/ui/viewmodels/OverlayManager_Tests.cpp b/tests/ui/viewmodels/OverlayManager_Tests.cpp index 943d53661..06c65e656 100644 --- a/tests/ui/viewmodels/OverlayManager_Tests.cpp +++ b/tests/ui/viewmodels/OverlayManager_Tests.cpp @@ -5,9 +5,9 @@ #include "ui\OverlayTheme.hh" #include "tests\devkit\context\mocks\MockRcClient.hh" +#include "tests\devkit\services\mocks\MockClock.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\mocks\MockAchievementRuntime.hh" -#include "tests\mocks\MockClock.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockEmulatorContext.hh" diff --git a/tests/ui/viewmodels/PointerFinderViewModel_Tests.cpp b/tests/ui/viewmodels/PointerFinderViewModel_Tests.cpp index 18801dbb6..261e8b3a1 100644 --- a/tests/ui/viewmodels/PointerFinderViewModel_Tests.cpp +++ b/tests/ui/viewmodels/PointerFinderViewModel_Tests.cpp @@ -7,9 +7,9 @@ #include "tests\RA_UnitTestHelpers.h" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\services\mocks\MockFileSystem.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockWindowManager.hh" @@ -27,7 +27,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) class PointerFinderViewModelHarness : public PointerFinderViewModel { public: - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::services::mocks::MockConfiguration mockConfiguration; ra::services::mocks::MockFileSystem mockFileSystem; @@ -102,7 +102,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) PointerFinderViewModelHarness vmPointerFinder; vmPointerFinder.mockGameContext.SetGameId(1U); std::array pMemory{}; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); bool bDialogSeen = false; vmPointerFinder.mockDesktop.ExpectWindow([&bDialogSeen](MessageBoxViewModel& vmMessageBox) { @@ -155,7 +155,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) { PointerFinderViewModelHarness vmPointerFinder; vmPointerFinder.mockGameContext.SetGameId(1U); - vmPointerFinder.mockEmulatorContext.MockTotalMemorySizeChanged(0x10000); + vmPointerFinder.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000); for (auto& pState : vmPointerFinder.States()) { @@ -215,7 +215,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) PointerFinderViewModelHarness vmPointerFinder; vmPointerFinder.mockGameContext.SetGameId(1U); std::array pMemory{}; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); bool bDialogSeen = false; vmPointerFinder.mockDesktop.ExpectWindow([&bDialogSeen](MessageBoxViewModel& vmMessageBox) { @@ -240,7 +240,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) PointerFinderViewModelHarness vmPointerFinder; vmPointerFinder.mockGameContext.SetGameId(1U); std::array pMemory{}; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); bool bDialogSeen = false; vmPointerFinder.mockDesktop.ExpectWindow([&bDialogSeen](MessageBoxViewModel& vmMessageBox) { @@ -272,7 +272,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) pMemory.at(0x08) = 0x1c; pMemory.at(0x1c) = 0x55; pMemory.at(0x1d) = 0x46; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x1c"); vmPointerFinder.States().at(0).ToggleCapture(); @@ -301,7 +301,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) pMemory.at(0x08) = 0x1c; pMemory.at(0x1c) = 0x55; pMemory.at(0x1d) = 0x46; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x20"); vmPointerFinder.States().at(0).ToggleCapture(); @@ -330,7 +330,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) pMemory.at(0x08) = 0x1c; pMemory.at(0x1c) = 0x55; pMemory.at(0x1d) = 0x46; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x18"); vmPointerFinder.States().at(0).ToggleCapture(); @@ -361,7 +361,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) pMemory.at(0x1d) = 0x46; pMemory.at(0x70) = 0x1c; pMemory.at(0x9c) = 0x20; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x20"); vmPointerFinder.States().at(0).ToggleCapture(); @@ -395,7 +395,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) pMemory.at(0x70) = 0x1c; pMemory.at(0x9c) = 0x20; pMemory.at(0xa4) = 0x20; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x20"); vmPointerFinder.States().at(0).ToggleCapture(); @@ -432,7 +432,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) std::array pMemory{}; pMemory.at(0x08) = 0x1c; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x18"); vmPointerFinder.States().at(0).ToggleCapture(); @@ -468,7 +468,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) pMemory.at(0x08) = 0x1c; pMemory.at(0x70) = 0x1c; pMemory.at(0x9c) = 0x20; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x20"); vmPointerFinder.States().at(0).ToggleCapture(); @@ -509,7 +509,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) pMemory.at(0x08) = 0x1c; pMemory.at(0x70) = 0x1c; pMemory.at(0x9c) = 0x20; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x20"); vmPointerFinder.States().at(0).ToggleCapture(); @@ -562,7 +562,7 @@ TEST_CLASS(PointerFinderViewModel_Tests) pMemory.at(0x08) = 0x1c; pMemory.at(0x70) = 0x1c; pMemory.at(0x9c) = 0x20; - vmPointerFinder.mockEmulatorContext.MockMemory(pMemory); + vmPointerFinder.mockEmulatorMemoryContext.MockMemory(pMemory); vmPointerFinder.States().at(0).SetAddress(L"0x20"); vmPointerFinder.States().at(0).ToggleCapture(); diff --git a/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp b/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp index 561fc3378..d9002b8d0 100644 --- a/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp +++ b/tests/ui/viewmodels/PointerInspectorViewModel_Tests.cpp @@ -9,12 +9,12 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\services\mocks\MockThreadPool.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockClipboard.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockLocalStorage.hh" #include "tests\mocks\MockUserContext.hh" @@ -35,9 +35,9 @@ TEST_CLASS(PointerInspectorViewModel_Tests) { public: ra::context::mocks::MockConsoleContext mockConsoleContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; ra::services::mocks::MockClipboard mockClipboard; ra::services::mocks::MockLocalStorage mockLocalStorage; diff --git a/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp b/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp index 458823778..cdc5807a5 100644 --- a/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp +++ b/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp @@ -8,9 +8,9 @@ #include "tests\RA_UnitTestHelpers.h" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\devkit\testutil\MemoryAsserts.hh" #include "tests\mocks\MockConfiguration.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockGameContext.hh" #include "tests\mocks\MockUserContext.hh" #include "tests\ui\viewmodels\TriggerConditionAsserts.hh" @@ -760,14 +760,14 @@ TEST_CLASS(TriggerConditionViewModel_Tests) class IndirectAddressTriggerViewModelHarness : public TriggerViewModel { public: - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockConfiguration mockConfiguration; void Parse(const std::string& sInput) { - mockEmulatorContext.MockMemory(m_pMemory); + mockEmulatorMemoryContext.MockMemory(m_pMemory); ra::data::models::CapturedTriggerHits pCapturedHits; InitializeFrom(sInput, pCapturedHits); @@ -1475,9 +1475,9 @@ TEST_CLASS(TriggerConditionViewModel_Tests) // ... ... // Parse registers the default memory. Replace it with specific values - vmTrigger.mockEmulatorContext.MockMemoryValue(0x001234, 0xa05bb680); - vmTrigger.mockEmulatorContext.MockMemoryValue(0x002222, 0x00c0d6ac); - vmTrigger.mockEmulatorContext.MockMemoryValue(0xb65ba8, 0xc02e3980); + vmTrigger.mockEmulatorMemoryContext.MockMemoryValue(0x001234, 0xa05bb680); + vmTrigger.mockEmulatorMemoryContext.MockMemoryValue(0x002222, 0x00c0d6ac); + vmTrigger.mockEmulatorMemoryContext.MockMemoryValue(0xb65ba8, 0xc02e3980); auto* pTrigger = vmTrigger.GetTriggerFromString(); auto* pMemrefs = rc_trigger_get_memrefs(pTrigger); diff --git a/tests/ui/viewmodels/TriggerViewModel_Tests.cpp b/tests/ui/viewmodels/TriggerViewModel_Tests.cpp index bd9934a04..04da9d768 100644 --- a/tests/ui/viewmodels/TriggerViewModel_Tests.cpp +++ b/tests/ui/viewmodels/TriggerViewModel_Tests.cpp @@ -4,11 +4,11 @@ #include "tests\ui\UIAsserts.hh" #include "tests\devkit\context\mocks\MockConsoleContext.hh" +#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh" #include "tests\mocks\MockClipboard.hh" #include "tests\mocks\MockConfiguration.hh" #include "tests\mocks\MockDesktop.hh" #include "tests\mocks\MockGameContext.hh" -#include "tests\mocks\MockEmulatorContext.hh" #include "tests\mocks\MockImageRepository.hh" #include "tests\mocks\MockUserContext.hh" #include "tests\mocks\MockWindowManager.hh" @@ -27,7 +27,7 @@ TEST_CLASS(TriggerViewModel_Tests) { public: ra::context::mocks::MockConsoleContext mockConsoleContext; - ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext; ra::data::context::mocks::MockGameContext mockGameContext; ra::data::context::mocks::MockUserContext mockUserContext; ra::services::mocks::MockClipboard mockClipboard; @@ -40,7 +40,7 @@ TEST_CLASS(TriggerViewModel_Tests) { // make sure to hook up the memory inspector first or we won't be able to set an address mockWindowManager.MemoryInspector.Viewer().InitializeNotifyTargets(); - mockEmulatorContext.MockMemory(pMemory, nMemorySize); + mockEmulatorMemoryContext.MockMemory(pMemory, nMemorySize); } const std::set& GetSelectedItems() const noexcept From 1377dd5556b76d01cba8f03e3cb5f8866e02fdad Mon Sep 17 00:00:00 2001 From: Jamiras Date: Thu, 8 Jan 2026 21:09:57 -0700 Subject: [PATCH 5/5] prevent exception at shutdown --- src/services/Initialization.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/Initialization.cpp b/src/services/Initialization.cpp index a5b04351d..1640f985e 100644 --- a/src/services/Initialization.cpp +++ b/src/services/Initialization.cpp @@ -243,9 +243,9 @@ void Initialization::Shutdown() // explicitly deregister it to prevent exceptions when closing down the application. ra::services::ServiceLocator::Provide(nullptr); - // GridBinding subclass destructors may try to use the EmulatorContext if they think it still exists. + // GridBinding subclass destructors may try to use the EmulatorMemoryContext if they think it still exists. // explicitly deregister it to prevent exceptions when closing down the application. - ra::services::ServiceLocator::Provide(nullptr); + ra::services::ServiceLocator::Provide(nullptr); // clear out the IThreadPool and IConfiguration services to indicate things have been de-initialized ra::services::ServiceLocator::Provide(nullptr);