Repository: RetroAchievements/RAIntegration
Pull request #679 (2021-02-13 18:12:32)

change category on LocalBadgesModel to Local
prevent non-hardcore warning from being displayed when opening a game without any core achievements


Patch:
diff --git a/src/data/context/EmulatorContext.cpp b/src/data/context/EmulatorContext.cpp
index 1649ab16..ccb60bdf 100644
--- a/src/data/context/EmulatorContext.cpp
+++ b/src/data/context/EmulatorContext.cpp
@@ -590,13 +590,21 @@ void EmulatorContext::ReadMemory(ra::ByteAddress nAddress, uint8_t pBuffer[], si
             continue;
         }
 
+        const size_t nBlockRemaining = pBlock.size - nAddress;
+
         if (!pBlock.read)
         {
             ra::services::ServiceLocator::GetMutable<ra::services::AchievementRuntime>().InvalidateAddress(nOriginalAddress);
-            break;
+            if (nCount <= nBlockRemaining)
+                break;
+
+            memset(pBuffer, 0, nBlockRemaining);
+            pBuffer += nBlockRemaining;
+            nCount -= nBlockRemaining;
+            nAddress = 0;
+            continue;
         }
 
-        const size_t nBlockRemaining = pBlock.size - nAddress;
         size_t nToRead = std::min(nCount, nBlockRemaining);
         nCount -= nToRead;
 
diff --git a/src/data/context/GameAssets.cpp b/src/data/context/GameAssets.cpp
index 25ce9108..344bcb5b 100644
--- a/src/data/context/GameAssets.cpp
+++ b/src/data/context/GameAssets.cpp
@@ -129,6 +129,10 @@ void GameAssets::ReloadAssets(const std::vector<ra::data::models::AssetModelBase
                 if (pAsset->GetChanges() != ra::data::models::AssetChanges::None ||
                     pAsset->GetCategory() == ra::data::models::AssetCategory::Local)
                 {
+                    // ignore LocalBadges container
+                    if (pAsset->GetType() == ra::data::models::AssetType::LocalBadges)
+                        continue;
+
                     vRemainingAssetsToReload.push_back(pAsset);
                 }
             }
diff --git a/src/data/models/LocalBadgesModel.cpp b/src/data/models/LocalBadgesModel.cpp
index f20a1e1c..094a55ab 100644
--- a/src/data/models/LocalBadgesModel.cpp
+++ b/src/data/models/LocalBadgesModel.cpp
@@ -14,6 +14,7 @@ namespace models {
 LocalBadgesModel::LocalBadgesModel() noexcept
 {
     GSL_SUPPRESS_F6 SetValue(TypeProperty, ra::etoi(AssetType::LocalBadges));
+    GSL_SUPPRESS_F6 SetValue(CategoryProperty, ra::etoi(AssetCategory::Local));
     GSL_SUPPRESS_F6 SetName(L"Local Badges");
 }
 


Test patch:
diff --git a/tests/data/context/EmulatorContext_Tests.cpp b/tests/data/context/EmulatorContext_Tests.cpp
index 50f5a8d5..89d4fe68 100644
--- a/tests/data/context/EmulatorContext_Tests.cpp
+++ b/tests/data/context/EmulatorContext_Tests.cpp
@@ -1117,6 +1117,53 @@ public:
         Assert::AreEqual(0, static_cast<int>(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();
diff --git a/tests/data/models/LocalBadgesModel_Tests.cpp b/tests/data/models/LocalBadgesModel_Tests.cpp
index 482e44f5..902a032c 100644
--- a/tests/data/models/LocalBadgesModel_Tests.cpp
+++ b/tests/data/models/LocalBadgesModel_Tests.cpp
@@ -40,7 +40,7 @@ public:
         Assert::AreEqual(0U, badges.GetID());
         Assert::AreEqual(std::wstring(L"Local Badges"), badges.GetName());
         Assert::AreEqual(std::wstring(L""), badges.GetDescription());
-        Assert::AreEqual(AssetCategory::Core, badges.GetCategory());
+        Assert::AreEqual(AssetCategory::Local, badges.GetCategory());
         Assert::AreEqual(AssetState::Inactive, badges.GetState());
         Assert::AreEqual(AssetChanges::None, badges.GetChanges());
         Assert::IsFalse(badges.NeedsSerialized());