Repository: RetroAchievements/RAIntegration
Pull request #1176 (2025-05-18 00:31:27)

fix delta/prior not showing up for last element of a chain
fixes https://discord.com/channels/310192285306454017/1149693430306447380/1373404810312945804

The new runtime is optimizing an AddSource chain of deltas to just use the delta of the AddSource chain of non-deltas. As a result, the final element of the chain doesn't appear as a delta when extracting the non-combining operand and needs to be massaged back into a delta.


Patch:
diff --git a/.gitmodules b/.gitmodules
index 1964e87b..1e3865cb 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,9 +4,6 @@
 [submodule "rcheevos"]
 	path = rcheevos
 	url = https://github.com/RetroAchievements/rcheevos.git
-[submodule "lua"]
-	path = lua
-	url = https://github.com/lua/lua.git
 [submodule "GSL"]
 	path = GSL
 	url = https://github.com/Microsoft/GSL.git
diff --git a/lua b/lua
deleted file mode 160000
index e354c635..00000000
--- a/lua
+++ /dev/null
@@ -1,1 +0,0 @@
-Subproject commit e354c6355e7f48e087678ec49e340ca0696725b1
diff --git a/rcheevos b/rcheevos
index 8a0178d5..e34aff3f 160000
--- a/rcheevos
+++ b/rcheevos
@@ -1,1 +1,1 @@
-Subproject commit 8a0178d5eec92ddd3cc06872678dc792b766fa54
+Subproject commit e34aff3f3cc382190b274b7a1af4ec3f395bb9b2
diff --git a/src/base.props b/src/base.props
index a2ec7a91..61b5617b 100644
--- a/src/base.props
+++ b/src/base.props
@@ -8,8 +8,7 @@
     <RAInterface_IncludePath>$(RA_DIR)RAInterface</RAInterface_IncludePath>
     <RA_SourceDir>$(RA_DIR)src\</RA_SourceDir>
     <GSL_IncludeDir>$(RA_DIR)GSL\include\</GSL_IncludeDir>
-    <Lua_Dir>$(RA_DIR)lua\</Lua_Dir>
-    <RA_IncludePath>$(RA_DIR);$(RA_SourceDir);$(RAInterface_IncludePath);$(RapidJSON_IncludeDir);$(rcheevos_IncludePath);$(Lua_Dir);$(GSL_IncludeDir)</RA_IncludePath>
+    <RA_IncludePath>$(RA_DIR);$(RA_SourceDir);$(RAInterface_IncludePath);$(RapidJSON_IncludeDir);$(rcheevos_IncludePath);$(GSL_IncludeDir)</RA_IncludePath>
     <XPDeprecationWarning>true</XPDeprecationWarning>
   </PropertyGroup>
   <PropertyGroup>
@@ -33,7 +32,7 @@
       <PrecompiledHeader>Use</PrecompiledHeader>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
       <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
-      <PreprocessorDefinitions>_ARCH=$(PlatformArchitecture);RC_CLIENT_SUPPORTS_HASH;RC_DISABLE_LUA;RA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_ARCH=$(PlatformArchitecture);RC_CLIENT_SUPPORTS_HASH;RA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
     </ClCompile>
@@ -79,10 +78,6 @@
       <Value>$(GSL_IncludeDir)</Value>
       <EnvironmentVariable>true</EnvironmentVariable>
     </BuildMacro>
-    <BuildMacro Include="Lua_Dir">
-      <Value>$(Lua_Dir)</Value>
-      <EnvironmentVariable>true</EnvironmentVariable>
-    </BuildMacro>
     <BuildMacro Include="RA_IncludePath">
       <Value>$(RA_IncludePath)</Value>
       <EnvironmentVariable>true</EnvironmentVariable>
diff --git a/src/rcheevos.vcxproj b/src/rcheevos.vcxproj
index ec3d7c5b..f2a8cd35 100644
--- a/src/rcheevos.vcxproj
+++ b/src/rcheevos.vcxproj
@@ -65,9 +65,9 @@
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;RC_DISABLE_LUA;RC_CLIENT_SUPPORTS_HASH;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;RC_CLIENT_SUPPORTS_HASH;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <CompileAs>CompileAsC</CompileAs>
-      <AdditionalIncludeDirectories>$(SolutionDir)lua;$(SolutionDir)rcheevos\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)rcheevos\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ExceptionHandling>false</ExceptionHandling>
       <ConformanceMode>true</ConformanceMode>
       <WarningLevel>Level3</WarningLevel>
@@ -89,9 +89,9 @@
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;RC_DISABLE_LUA;RC_CLIENT_SUPPORTS_HASH;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;RC_CLIENT_SUPPORTS_HASH;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <CompileAs>CompileAsC</CompileAs>
-      <AdditionalIncludeDirectories>$(SolutionDir)lua;$(SolutionDir)rcheevos\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)rcheevos\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ExceptionHandling>false</ExceptionHandling>
       <ConformanceMode>true</ConformanceMode>
       <WarningLevel>Level3</WarningLevel>
@@ -112,9 +112,9 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;RC_DISABLE_LUA;RC_CLIENT_SUPPORTS_HASH;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;RC_CLIENT_SUPPORTS_HASH;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <CompileAs>CompileAsC</CompileAs>
-      <AdditionalIncludeDirectories>$(SolutionDir)lua;$(SolutionDir)rcheevos\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)rcheevos\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ExceptionHandling>false</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <ConformanceMode>true</ConformanceMode>
@@ -130,9 +130,9 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;RC_DISABLE_LUA;RC_CLIENT_SUPPORTS_HASH;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;RC_CLIENT_SUPPORTS_HASH;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <CompileAs>CompileAsC</CompileAs>
-      <AdditionalIncludeDirectories>$(SolutionDir)lua;$(SolutionDir)rcheevos\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)rcheevos\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ExceptionHandling>false</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <ConformanceMode>true</ConformanceMode>
@@ -166,27 +166,6 @@
     <ClInclude Include="..\rcheevos\src\rcheevos\rc_internal.h" />
     <ClInclude Include="..\rcheevos\src\rc_client_external.h" />
     <ClInclude Include="..\rcheevos\src\rhash\md5.h" />
-    <ClCompile Include="..\lua\lapi.c" />
-    <ClCompile Include="..\lua\lauxlib.c" />
-    <ClCompile Include="..\lua\lcode.c" />
-    <ClCompile Include="..\lua\lctype.c" />
-    <ClCompile Include="..\lua\ldebug.c" />
-    <ClCompile Include="..\lua\ldo.c" />
-    <ClCompile Include="..\lua\ldump.c" />
-    <ClCompile Include="..\lua\lfunc.c" />
-    <ClCompile Include="..\lua\lgc.c" />
-    <ClCompile Include="..\lua\llex.c" />
-    <ClCompile Include="..\lua\lmem.c" />
-    <ClCompile Include="..\lua\lobject.c" />
-    <ClCompile Include="..\lua\lopcodes.c" />
-    <ClCompile Include="..\lua\lparser.c" />
-    <ClCompile Include="..\lua\lstate.c" />
-    <ClCompile Include="..\lua\lstring.c" />
-    <ClCompile Include="..\lua\ltable.c" />
-    <ClCompile Include="..\lua\ltm.c" />
-    <ClCompile Include="..\lua\lundump.c" />
-    <ClCompile Include="..\lua\lvm.c" />
-    <ClCompile Include="..\lua\lzio.c" />
     <ClCompile Include="..\rcheevos\src\rcheevos\alloc.c" />
     <ClCompile Include="..\rcheevos\src\rcheevos\condition.c" />
     <ClCompile Include="..\rcheevos\src\rcheevos\condset.c" />
diff --git a/src/rcheevos.vcxproj.filters b/src/rcheevos.vcxproj.filters
index a48d1342..49c0a604 100644
--- a/src/rcheevos.vcxproj.filters
+++ b/src/rcheevos.vcxproj.filters
@@ -1,69 +1,6 @@
 ﻿<?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <ClCompile Include="..\lua\lapi.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lauxlib.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lcode.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lctype.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\ldebug.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\ldo.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\ldump.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lfunc.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lgc.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\llex.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lmem.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lobject.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lopcodes.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lparser.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lstate.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lstring.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\ltable.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\ltm.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lundump.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lvm.c">
-      <Filter>lua</Filter>
-    </ClCompile>
-    <ClCompile Include="..\lua\lzio.c">
-      <Filter>lua</Filter>
-    </ClCompile>
     <ClCompile Include="..\rcheevos\src\rcheevos\value.c">
       <Filter>rcheevos</Filter>
     </ClCompile>
@@ -153,9 +90,6 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <Filter Include="lua">
-      <UniqueIdentifier>{34c1cfa0-13ee-4122-b223-0bbc286865e5}</UniqueIdentifier>
-    </Filter>
     <Filter Include="rcheevos">
       <UniqueIdentifier>{551d7e10-0699-4da6-9d2d-d992d7b26a3a}</UniqueIdentifier>
     </Filter>
diff --git a/src/ui/viewmodels/TriggerConditionViewModel.cpp b/src/ui/viewmodels/TriggerConditionViewModel.cpp
index e3b4c306..537cc25f 100644
--- a/src/ui/viewmodels/TriggerConditionViewModel.cpp
+++ b/src/ui/viewmodels/TriggerConditionViewModel.cpp
@@ -244,6 +244,16 @@ void TriggerConditionViewModel::InitializeFrom(const rc_condition_t& pCondition)
     const auto* pOperand = rc_condition_get_real_operand1(&pCondition);
     Expects(pOperand != nullptr);
     SetOperand(SourceTypeProperty, SourceSizeProperty, SourceValueProperty, *pOperand);
+
+    // if the runtime has optimized a delta into a delta read of a non-delta chain, we
+    // have to select the delta value manually
+    if (pOperand != &pCondition.operand1 &&
+        (pCondition.operand1.type == RC_OPERAND_DELTA || pCondition.operand1.type == RC_OPERAND_PRIOR))
+    {
+        const auto nType = static_cast<TriggerOperandType>(pCondition.operand1.type);
+        SetSourceType(nType);
+    }
+
     SetOperand(TargetTypeProperty, TargetSizeProperty, TargetValueProperty, pCondition.operand2);
 
     SetOperator(static_cast<TriggerOperatorType>(pCondition.oper));


Test patch:
diff --git a/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp b/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp
index 01a714a9..ac831825 100644
--- a/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp
+++ b/tests/ui/viewmodels/TriggerConditionViewModel_Tests.cpp
@@ -59,7 +59,7 @@ private:
 
     void ParseAndRegenerate(const std::string& sInput)
     {
-        unsigned char pBuffer[512] = {0};
+        unsigned char pBuffer[2048] = {0};
         const auto nSize = rc_trigger_size(sInput.c_str());
         Assert::IsTrue(nSize > 0 && nSize < sizeof(pBuffer));
 
@@ -580,7 +580,7 @@ public:
         Assert::AreEqual(std::string("K:0xH1234"), sSerialized);
     }
 
-    TEST_METHOD(TestSizes)
+    TEST_METHOD(TestParseAndRegenerateSizes)
     {
         ParseAndRegenerate("0xH1234=0xH2345"); // 8-bit
         ParseAndRegenerate("0x 1234=0x 2345"); // 16-bit
@@ -605,7 +605,7 @@ public:
         ParseAndRegenerate("fL1234=fL2345"); // mbf32le
     }
 
-    TEST_METHOD(TestOperandTypes)
+    TEST_METHOD(TestParseAndRegenerateOperandTypes)
     {
         ParseAndRegenerate("0xH1234=0xH1234"); // address
         ParseAndRegenerate("0xH1234=d0xH1234"); // delta
@@ -617,7 +617,7 @@ public:
         ParseAndRegenerate("0xH1234=f12.34"); // float
     }
 
-    TEST_METHOD(TestOperators)
+    TEST_METHOD(TestParseAndRegenerateOperators)
     {
         ParseAndRegenerate("0xH1234=5"); // equals
         ParseAndRegenerate("0xH1234!=5"); // not equals
@@ -634,7 +634,7 @@ public:
         ParseAndRegenerate("A:0xH1234&5"); // bitwise and
     }
 
-    TEST_METHOD(TestConditionTypes)
+    TEST_METHOD(TestParseAndRegenerateConditionTypes)
     {
         ParseAndRegenerate("0xH1234=5"); // none
         ParseAndRegenerate("R:0xH1234=5"); // reset if
@@ -653,10 +653,13 @@ public:
         ParseAndRegenerate("T:0xH1234=5"); // trigger
     }
 
-    TEST_METHOD(TestParseAndRegenerate)
+    TEST_METHOD(TestParseAndRegenerateHits)
     {
-        ParseAndRegenerate("0xH1234=5"); // simple
         ParseAndRegenerate("R:0xH1234=5.100."); // flag and 100 hits
+    }
+
+    TEST_METHOD(TestParseAndRegenerateValue)
+    {
         ParseAndRegenerateValue("M:0xH1234=5"); // measured without hit target
         ParseAndRegenerateValue("M:0xH1234"); // measured without comparison
         ParseAndRegenerateValue("M:0xH1234/5"); // measured with modifier
diff --git a/tests/ui/viewmodels/TriggerViewModel_Tests.cpp b/tests/ui/viewmodels/TriggerViewModel_Tests.cpp
index dbb79123..c1a77551 100644
--- a/tests/ui/viewmodels/TriggerViewModel_Tests.cpp
+++ b/tests/ui/viewmodels/TriggerViewModel_Tests.cpp
@@ -268,6 +268,15 @@ public:
         ParseAndRegenerate("0xH1234=0xH2345SI:0x 1234_A:0xH2345_0xH7777=345"); // addsource/addaddress chain
     }
 
+    TEST_METHOD(TestParseAndRegenerateComplex)
+    {
+        ParseAndRegenerate("R:0xH1234=5.100.");                               // flag and 100 hits
+        ParseAndRegenerate("A:0xH1234_A:0xH1236_A:0xH1237_M:0xH1238=99");     // addsource chain
+        ParseAndRegenerate("A:d0xH1234_A:d0xH1236_A:d0xH1237_M:d0xH1238=99"); // addsource delta chain
+        ParseAndRegenerate("A:p0xH1234_A:p0xH1236_A:p0xH1237_M:p0xH1238=99"); // addsource prior chain
+        ParseAndRegenerate("I:0xX1234_0xH0010=1");                            // addaddress chain
+    }
+
     TEST_METHOD(TestParseAndRegenerateValue)
     {
         ParseAndRegenerateValue(""); // empty