Skip to content

Commit 560781c

Browse files
committed
Move GameConfig logic out of PS2OS.
1 parent d356043 commit 560781c

6 files changed

Lines changed: 194 additions & 164 deletions

File tree

Source/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ set(COMMON_SRC_FILES
255255
ScreenPositionListener.h
256256
InputConfig.cpp
257257
InputConfig.h
258+
GameConfig.cpp
259+
GameConfig.h
258260
GenericMipsExecutor.h
259261
gs/GsCachedArea.cpp
260262
gs/GsCachedArea.h

Source/GameConfig.cpp

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#include "GameConfig.h"
2+
#include "xml/Node.h"
3+
#include "xml/Parser.h"
4+
#include "xml/FilteringNodeIterator.h"
5+
#include "PathUtils.h"
6+
#include "StdStreamUtils.h"
7+
#ifdef __ANDROID__
8+
#include "android/AssetStream.h"
9+
#endif
10+
#include "Log.h"
11+
#include "PS2VM.h"
12+
#include "ee/EeExecutor.h"
13+
14+
#define LOG_NAME "GameConfig"
15+
16+
#define GAMECONFIG_FILENAME "GameConfig.xml"
17+
18+
void CGameConfig::ApplyGameConfig(CPS2VM& virtualMachine)
19+
{
20+
std::unique_ptr<Framework::Xml::CNode> document;
21+
try
22+
{
23+
#ifdef __ANDROID__
24+
Framework::Android::CAssetStream inputStream(GAMECONFIG_FILENAME);
25+
#else
26+
auto gameConfigPath = Framework::PathUtils::GetAppResourcesPath() / GAMECONFIG_FILENAME;
27+
Framework::CStdStream inputStream(Framework::CreateInputStdStream(gameConfigPath.native()));
28+
#endif
29+
document = Framework::Xml::CParser::ParseDocument(inputStream);
30+
if(!document) return;
31+
}
32+
catch(const std::exception& exception)
33+
{
34+
CLog::GetInstance().Warn(LOG_NAME, "Failed to open game config file: %s.\r\n", exception.what());
35+
return;
36+
}
37+
38+
auto gameConfigsNode = document->Select("GameConfigs");
39+
if(!gameConfigsNode)
40+
{
41+
return;
42+
}
43+
44+
CEeExecutor::BlockFpRoundingModeMap blockFpRoundingModes;
45+
CEeExecutor::BlockFpUseAccurateAddSubSet blockFpUseAccurateAddSub;
46+
CEeExecutor::IdleLoopBlockMap idleLoopBlocks;
47+
48+
const char* executableName = virtualMachine.m_ee->m_os->GetExecutableName();
49+
auto eeExecutor = static_cast<CEeExecutor*>(virtualMachine.m_ee->m_EE.m_executor.get());
50+
auto eeRam = virtualMachine.m_ee->m_ram;
51+
52+
for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigsNode, "GameConfig");
53+
!itNode.IsEnd(); itNode++)
54+
{
55+
auto gameConfigNode = (*itNode);
56+
57+
const char* executable = gameConfigNode->GetAttribute("Executable");
58+
if(!executable) continue;
59+
60+
if(strcmp(executable, executableName)) continue;
61+
62+
//Found the right executable, apply config
63+
64+
for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigNode, "Patch");
65+
!itNode.IsEnd(); itNode++)
66+
{
67+
auto patch = (*itNode);
68+
69+
const char* addressString = patch->GetAttribute("Address");
70+
const char* valueString = patch->GetAttribute("Value");
71+
72+
if(!addressString) continue;
73+
if(!valueString) continue;
74+
75+
uint32 value = 0, address = 0;
76+
if(sscanf(addressString, "%x", &address) == 0) continue;
77+
if(sscanf(valueString, "%x", &value) == 0) continue;
78+
79+
*reinterpret_cast<uint32*>(eeRam + address) = value;
80+
}
81+
82+
for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigNode, "BlockFpRoundingMode");
83+
!itNode.IsEnd(); itNode++)
84+
{
85+
auto node = (*itNode);
86+
87+
const char* addressString = node->GetAttribute("Address");
88+
const char* modeString = node->GetAttribute("Mode");
89+
90+
if(!addressString) continue;
91+
if(!modeString) continue;
92+
93+
uint32 address = 0;
94+
auto roundingMode = Jitter::CJitter::ROUND_NEAREST;
95+
if(sscanf(addressString, "%x", &address) == 0) continue;
96+
97+
if(!strcmp(modeString, "NEAREST"))
98+
{
99+
roundingMode = Jitter::CJitter::ROUND_NEAREST;
100+
}
101+
else if(!strcmp(modeString, "PLUSINFINITY"))
102+
{
103+
roundingMode = Jitter::CJitter::ROUND_PLUSINFINITY;
104+
}
105+
else if(!strcmp(modeString, "MINUSINFINITY"))
106+
{
107+
roundingMode = Jitter::CJitter::ROUND_MINUSINFINITY;
108+
}
109+
else if(!strcmp(modeString, "TRUNCATE"))
110+
{
111+
roundingMode = Jitter::CJitter::ROUND_TRUNCATE;
112+
}
113+
else
114+
{
115+
assert(false);
116+
continue;
117+
}
118+
119+
blockFpRoundingModes.insert(std::make_pair(address, roundingMode));
120+
}
121+
122+
for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigNode, "BlockFpUseAccurateAddSub");
123+
!itNode.IsEnd(); itNode++)
124+
{
125+
auto node = (*itNode);
126+
127+
const char* addressString = node->GetAttribute("Address");
128+
if(!addressString) continue;
129+
130+
uint32 address = 0;
131+
if(sscanf(addressString, "%x", &address) == 0) continue;
132+
133+
blockFpUseAccurateAddSub.insert(address);
134+
}
135+
136+
for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigNode, "IdleLoopBlock");
137+
!itNode.IsEnd(); itNode++)
138+
{
139+
auto node = (*itNode);
140+
141+
const char* addressString = node->GetAttribute("Address");
142+
const char* checkBlockKeyString = node->GetAttribute("CheckBlockKey");
143+
144+
if(!addressString) continue;
145+
146+
uint32 address = 0;
147+
std::optional<CEeExecutor::CachedBlockKey> checkBlockKey;
148+
149+
if(sscanf(addressString, "%x", &address) == 0) continue;
150+
if(checkBlockKeyString)
151+
{
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)
158+
{
159+
continue;
160+
}
161+
checkBlockKey = blockKey;
162+
}
163+
164+
idleLoopBlocks.insert(std::make_pair(address, checkBlockKey));
165+
}
166+
167+
eeExecutor->SetBlockFpRoundingModes(std::move(blockFpRoundingModes));
168+
eeExecutor->SetBlockFpUseAccurateAddSub(std::move(blockFpUseAccurateAddSub));
169+
eeExecutor->SetIdleLoopBlocks(std::move(idleLoopBlocks));
170+
171+
break;
172+
}
173+
}

Source/GameConfig.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
class CPS2VM;
4+
5+
class CGameConfig
6+
{
7+
public:
8+
static void ApplyGameConfig(CPS2VM&);
9+
};

Source/PS2VM.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "iop/ioman/PreferenceDirectoryDevice.h"
3131
#include "Log.h"
3232
#include "DiskUtils.h"
33+
#include "GameConfig.h"
3334
#ifdef __ANDROID__
3435
#include "android/JavaVM.h"
3536
#endif
@@ -474,6 +475,7 @@ void CPS2VM::CreateVM()
474475

475476
m_ee = std::make_unique<Ee::CSubSystem>(m_iop->m_ram, *iopOs);
476477
m_OnRequestLoadExecutableConnection = m_ee->m_os->OnRequestLoadExecutable.Connect(std::bind(&CPS2VM::ReloadExecutable, this, std::placeholders::_1, std::placeholders::_2));
478+
m_OnExecutableChangeConnection = m_ee->m_os->OnExecutableChange.Connect(std::bind(&CPS2VM::OnExecutableChange, this));
477479
m_OnCrtModeChangeConnection = m_ee->m_os->OnCrtModeChange.Connect(std::bind(&CPS2VM::OnCrtModeChange, this));
478480

479481
ResetVM();
@@ -882,6 +884,11 @@ void CPS2VM::ReloadExecutable(const char* executablePath, const CPS2OS::Argument
882884
}
883885
}
884886

887+
void CPS2VM::OnExecutableChange()
888+
{
889+
CGameConfig::ApplyGameConfig(*this);
890+
}
891+
885892
void CPS2VM::OnCrtModeChange()
886893
{
887894
ReloadFrameRateLimit();

Source/PS2VM.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class CPS2VM : public CVirtualMachine
123123
void LoadVmTimingState(Framework::CZipArchiveReader&);
124124

125125
void ReloadExecutable(const char*, const CPS2OS::ArgumentList&);
126+
void OnExecutableChange();
126127
void OnCrtModeChange();
127128

128129
void PauseImpl();
@@ -203,5 +204,6 @@ class CPS2VM : public CVirtualMachine
203204
CProfiler::ZoneHandle m_otherProfilerZone = 0;
204205

205206
CPS2OS::RequestLoadExecutableEvent::Connection m_OnRequestLoadExecutableConnection;
207+
Framework::CSignal<void()>::Connection m_OnExecutableChangeConnection;
206208
Framework::CSignal<void()>::Connection m_OnCrtModeChangeConnection;
207209
};

0 commit comments

Comments
 (0)