|
10 | 10 | #include "Log.h" |
11 | 11 | #include "PS2VM.h" |
12 | 12 | #include "ee/EeExecutor.h" |
| 13 | +#include "ee/VuExecutor.h" |
13 | 14 |
|
14 | 15 | #define LOG_NAME "GameConfig" |
15 | 16 |
|
16 | 17 | #define GAMECONFIG_FILENAME "GameConfig.xml" |
17 | 18 |
|
| 19 | +template <typename BlockKeyType> |
| 20 | +static std::optional<BlockKeyType> ParseBlockKey(const char* blockKeyString) |
| 21 | +{ |
| 22 | + BlockKeyType blockKey; |
| 23 | + int parseCount = sscanf(blockKeyString, "%08X%08X%08X%08X;%d", |
| 24 | + &blockKey.first.nV[3], &blockKey.first.nV[2], |
| 25 | + &blockKey.first.nV[1], &blockKey.first.nV[0], |
| 26 | + &blockKey.second); |
| 27 | + if(parseCount == 5) |
| 28 | + { |
| 29 | + return std::optional<BlockKeyType>(blockKey); |
| 30 | + } |
| 31 | + else |
| 32 | + { |
| 33 | + return std::optional<BlockKeyType>(); |
| 34 | + } |
| 35 | +} |
| 36 | + |
18 | 37 | void CGameConfig::ApplyGameConfig(CPS2VM& virtualMachine) |
19 | 38 | { |
20 | 39 | std::unique_ptr<Framework::Xml::CNode> document; |
@@ -44,9 +63,11 @@ void CGameConfig::ApplyGameConfig(CPS2VM& virtualMachine) |
44 | 63 | CEeExecutor::BlockFpRoundingModeMap blockFpRoundingModes; |
45 | 64 | CEeExecutor::BlockFpUseAccurateAddSubSet blockFpUseAccurateAddSub; |
46 | 65 | CEeExecutor::IdleLoopBlockMap idleLoopBlocks; |
| 66 | + CVuExecutor::BlockNoClampingSet blockNoClamping; |
47 | 67 |
|
48 | 68 | const char* executableName = virtualMachine.m_ee->m_os->GetExecutableName(); |
49 | 69 | auto eeExecutor = static_cast<CEeExecutor*>(virtualMachine.m_ee->m_EE.m_executor.get()); |
| 70 | + auto vu1Executor = static_cast<CVuExecutor*>(virtualMachine.m_ee->m_vpu1->GetContext().m_executor.get()); |
50 | 71 | auto eeRam = virtualMachine.m_ee->m_ram; |
51 | 72 |
|
52 | 73 | for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigsNode, "GameConfig"); |
@@ -149,25 +170,38 @@ void CGameConfig::ApplyGameConfig(CPS2VM& virtualMachine) |
149 | 170 | if(sscanf(addressString, "%x", &address) == 0) continue; |
150 | 171 | if(checkBlockKeyString) |
151 | 172 | { |
152 | | - CEeExecutor::CachedBlockKey blockKey; |
153 | | - int parseCount = sscanf(checkBlockKeyString, "%08X%08X%08X%08X;%d", |
154 | | - &blockKey.first.nV[3], &blockKey.first.nV[2], |
155 | | - &blockKey.first.nV[1], &blockKey.first.nV[0], |
156 | | - &blockKey.second); |
157 | | - if(parseCount != 5) |
| 173 | + auto blockKey = ParseBlockKey<CEeExecutor::CachedBlockKey>(checkBlockKeyString); |
| 174 | + if(!blockKey.has_value()) |
158 | 175 | { |
159 | 176 | continue; |
160 | 177 | } |
161 | | - checkBlockKey = blockKey; |
| 178 | + checkBlockKey = blockKey.value(); |
162 | 179 | } |
163 | 180 |
|
164 | 181 | idleLoopBlocks.insert(std::make_pair(address, checkBlockKey)); |
165 | 182 | } |
166 | 183 |
|
| 184 | + for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigNode, "Vu1BlockNoClamping"); |
| 185 | + !itNode.IsEnd(); itNode++) |
| 186 | + { |
| 187 | + auto node = (*itNode); |
| 188 | + |
| 189 | + const char* blockKeyString = node->GetAttribute("BlockKey"); |
| 190 | + if(!blockKeyString) continue; |
| 191 | + |
| 192 | + auto blockKey = ParseBlockKey<CVuExecutor::CachedBlockKey>(blockKeyString); |
| 193 | + if(blockKey.has_value()) |
| 194 | + { |
| 195 | + blockNoClamping.insert(blockKey.value()); |
| 196 | + } |
| 197 | + } |
| 198 | + |
167 | 199 | eeExecutor->SetBlockFpRoundingModes(std::move(blockFpRoundingModes)); |
168 | 200 | eeExecutor->SetBlockFpUseAccurateAddSub(std::move(blockFpUseAccurateAddSub)); |
169 | 201 | eeExecutor->SetIdleLoopBlocks(std::move(idleLoopBlocks)); |
170 | 202 |
|
| 203 | + vu1Executor->SetBlockNoClamping(std::move(blockNoClamping)); |
| 204 | + |
171 | 205 | break; |
172 | 206 | } |
173 | 207 | } |
0 commit comments