summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorhrydgard <hrydgard@gmail.com>2008-11-23 12:59:10 +0000
committerhrydgard <hrydgard@gmail.com>2008-11-23 12:59:10 +0000
commitf87c709aa920e9dd2d4dcce4ab53beb3835e0b31 (patch)
treed721390ba009ca7fb5396ef352a1221ab99494ae /Source
parente2345ba34045be672bdbf2e468857b5ad3f652d7 (diff)
Added speed hack engine (way to make block take more cycles). Added example speed hack for Metroid Prime 2 PAL. (Speedhacking is only useful on games with really stupid idle loops, like the Metroids).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1271 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Common/Src/IniFile.cpp27
-rw-r--r--Source/Core/Common/Src/IniFile.h7
-rw-r--r--Source/Core/Core/Src/PatchEngine.cpp57
-rw-r--r--Source/Core/Core/Src/PatchEngine.h2
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp4
5 files changed, 69 insertions, 28 deletions
diff --git a/Source/Core/Common/Src/IniFile.cpp b/Source/Core/Common/Src/IniFile.cpp
index dc3f8095dd..27114e6d3c 100644
--- a/Source/Core/Common/Src/IniFile.cpp
+++ b/Source/Core/Common/Src/IniFile.cpp
@@ -51,21 +51,22 @@ Section::Section(const Section& other)
lines = other.lines;
}
+const Section* IniFile::GetSection(const char* sectionName) const
+{
+ for (std::vector<Section>::const_iterator iter = sections.begin(); iter != sections.end(); ++iter)
+ if (!strcmp(iter->name.c_str(), sectionName))
+ return (&(*iter));
+ return 0;
+}
Section* IniFile::GetSection(const char* sectionName)
{
for (std::vector<Section>::iterator iter = sections.begin(); iter != sections.end(); ++iter)
- {
if (!strcmp(iter->name.c_str(), sectionName))
- {
- return(&(*iter));
- }
- }
-
- return(0);
+ return (&(*iter));
+ return 0;
}
-
Section* IniFile::GetOrCreateSection(const char* sectionName)
{
Section* section = GetSection(sectionName);
@@ -102,7 +103,7 @@ bool IniFile::DeleteSection(const char* sectionName)
}
-void IniFile::ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut)
+void IniFile::ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) const
{
// allow many types of commenting
// These MUST be signed! Do not change to size_t
@@ -390,9 +391,9 @@ bool IniFile::Save(const char* filename)
}
-bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys)
+bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys) const
{
- Section* section = GetSection(sectionName);
+ const Section* section = GetSection(sectionName);
if (!section)
{
@@ -412,9 +413,9 @@ bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys)
}
-bool IniFile::GetLines(const char* sectionName, std::vector<std::string>& lines)
+bool IniFile::GetLines(const char* sectionName, std::vector<std::string>& lines) const
{
- Section* section = GetSection(sectionName);
+ const Section* section = GetSection(sectionName);
if (!section)
return false;
diff --git a/Source/Core/Common/Src/IniFile.h b/Source/Core/Common/Src/IniFile.h
index de4c5836d0..9614bf8b46 100644
--- a/Source/Core/Common/Src/IniFile.h
+++ b/Source/Core/Common/Src/IniFile.h
@@ -64,20 +64,21 @@ public:
bool Get(const char* sectionName, const char* key, bool* value, bool defaultValue = false);
bool Get(const char* sectionName, const char* key, std::vector<std::string>& values);
- bool GetKeys(const char* sectionName, std::vector<std::string>& keys);
- bool GetLines(const char* sectionName, std::vector<std::string>& lines);
+ bool GetKeys(const char* sectionName, std::vector<std::string>& keys) const;
+ bool GetLines(const char* sectionName, std::vector<std::string>& lines) const;
bool DeleteKey(const char* sectionName, const char* key);
bool DeleteSection(const char* sectionName);
void SortSections();
- void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut);
+ void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) const;
std::string* GetLine(Section* section, const char* key, std::string* valueOut, std::string* commentOut);
private:
std::vector<Section>sections;
+ const Section* GetSection(const char* section) const;
Section* GetSection(const char* section);
Section* GetOrCreateSection(const char* section);
std::string* GetLine(const char* section, const char* key);
diff --git a/Source/Core/Core/Src/PatchEngine.cpp b/Source/Core/Core/Src/PatchEngine.cpp
index 88ef81feca..f54f1963de 100644
--- a/Source/Core/Core/Src/PatchEngine.cpp
+++ b/Source/Core/Core/Src/PatchEngine.cpp
@@ -28,6 +28,7 @@
#include <string>
#include <vector>
+#include <map>
#include "StringUtil.h"
#include "PatchEngine.h"
#include "IniFile.h"
@@ -41,10 +42,9 @@ namespace
std::vector<Patch> onLoad;
std::vector<Patch> onFrame;
+std::map<u32, int> speedHacks;
-} // namespace
-
-void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile &ini)
+static void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile &ini)
{
std::vector<std::string> keys;
ini.GetKeys(section, keys);
@@ -59,18 +59,54 @@ void LoadPatchSection(const char *section, std::vector<Patch> &patches, IniFile
std::string val(value);
std::vector<std::string> items;
SplitString(val, ":", items);
- Patch p;
+ if (items.size() >= 2) {
+ Patch p;
+ bool success = true;
+ success = success && TryParseUInt(std::string(key.c_str()), &p.address);
+ success = success && TryParseUInt(items[1], &p.value);
+ p.type = (PatchType)ChooseStringFrom(items[0].c_str(), PatchTypeStrings);
+ success = success && (p.type != (PatchType)-1);
+ if (success)
+ patches.push_back(p);
+ }
+ }
+ }
+}
+
+static void LoadSpeedhacks(const char *section, std::map<u32, int> &hacks, IniFile &ini) {
+ std::vector<std::string> keys;
+ ini.GetKeys(section, keys);
+ for (std::vector<std::string>::const_iterator iter = keys.begin(); iter != keys.end(); ++iter)
+ {
+ std::string key = *iter;
+ std::string value;
+ ini.Get(section, key.c_str(), &value, "BOGUS");
+ if (value != "BOGUS")
+ {
+ u32 address;
+ u32 cycles;
bool success = true;
- success = success && TryParseUInt(std::string(key.c_str()), &p.address);
- success = success && TryParseUInt(items[1], &p.value);
- p.type = (PatchType)ChooseStringFrom(items[0].c_str(), PatchTypeStrings);
- success = success && (p.type != (PatchType)-1);
- if (success)
- patches.push_back(p);
+ success = success && TryParseUInt(std::string(key.c_str()), &address);
+ success = success && TryParseUInt(value, &cycles);
+ if (success) {
+ speedHacks[address] = (int)cycles;
+ }
}
}
}
+} // namespace
+
+
+int PatchEngine_GetSpeedhackCycles(u32 addr)
+{
+ std::map<u32, int>::const_iterator iter = speedHacks.find(addr);
+ if (iter == speedHacks.end())
+ return 0;
+ else
+ return iter->second;
+}
+
void PatchEngine_LoadPatches(const char *gameID)
{
IniFile ini;
@@ -79,6 +115,7 @@ void PatchEngine_LoadPatches(const char *gameID)
LoadPatchSection("OnLoad", onLoad, ini);
LoadPatchSection("OnFrame", onFrame, ini);
LoadActionReplayCodes(ini, false);
+ LoadSpeedhacks("Speedhacks", speedHacks, ini);
}
}
diff --git a/Source/Core/Core/Src/PatchEngine.h b/Source/Core/Core/Src/PatchEngine.h
index be475405bf..4f843cb194 100644
--- a/Source/Core/Core/Src/PatchEngine.h
+++ b/Source/Core/Core/Src/PatchEngine.h
@@ -46,4 +46,6 @@ void PatchEngine_LoadPatches(const char *gameID);
void PatchEngine_ApplyLoadPatches();
void PatchEngine_ApplyFramePatches();
void PatchEngine_ApplyARPatches();
+int PatchEngine_GetSpeedhackCycles(u32 addr);
+
#endif //_PATCHENGINE_H
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
index a708973b88..d992392524 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
@@ -23,6 +23,7 @@
#include "Thunk.h"
#include "../../HLE/HLE.h"
#include "../../Core.h"
+#include "../../PatchEngine.h"
#include "../../CoreTiming.h"
#include "../PowerPC.h"
#include "../Profiler.h"
@@ -371,7 +372,7 @@ namespace Jit64
gpr.Start(js.gpa);
fpr.Start(js.fpa);
- js.downcountAmount = js.st.numCycles;
+ js.downcountAmount = js.st.numCycles + PatchEngine_GetSpeedhackCycles(emaddress);
js.blockSize = size;
// Translate instructions
for (int i = 0; i < (int)size; i++)
@@ -396,7 +397,6 @@ namespace Jit64
}
// const GekkoOpInfo *info = GetOpInfo();
-
if (jo.interpretFPU && PPCTables::UsesFPU(ops[i].inst))
Default(ops[i].inst);
else