Fix Action Replay properly (i hope :P).. some misc code cleanup

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@851 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-10-13 19:21:25 +00:00
parent 744efe72e5
commit e13ca7e384
7 changed files with 160 additions and 259 deletions

View File

@ -86,7 +86,7 @@ bool IniFile::DeleteSection(const char* sectionName)
if (!s) if (!s)
{ {
return(false); return false;
} }
for (std::vector<Section>::iterator iter = sections.begin(); iter != sections.end(); ++iter) for (std::vector<Section>::iterator iter = sections.begin(); iter != sections.end(); ++iter)
@ -94,11 +94,11 @@ bool IniFile::DeleteSection(const char* sectionName)
if (&(*iter) == s) if (&(*iter) == s)
{ {
sections.erase(iter); sections.erase(iter);
return(true); return true;
} }
} }
return(false); return false;
} }
@ -150,11 +150,11 @@ std::string* IniFile::GetLine(Section* section, const char* key, std::string* va
if (!stricmp(lineKey.c_str(), key)) if (!stricmp(lineKey.c_str(), key))
{ {
return(&line); return &line;
} }
} }
return(0); return 0;
} }
@ -206,7 +206,7 @@ bool IniFile::Get(const char* sectionName, const char* key, std::string* value,
*value = defaultValue; *value = defaultValue;
} }
return(false); return false;
} }
std::string* line = GetLine(section, key, value, 0); std::string* line = GetLine(section, key, value, 0);
@ -218,10 +218,10 @@ bool IniFile::Get(const char* sectionName, const char* key, std::string* value,
*value = defaultValue; *value = defaultValue;
} }
return(false); return false;
} }
return(true); return true;
} }
@ -232,11 +232,11 @@ bool IniFile::Get(const char* sectionName, const char* key, int* value, int defa
if (retval && TryParseInt(temp.c_str(), value)) if (retval && TryParseInt(temp.c_str(), value))
{ {
return(true); return true;
} }
*value = defaultValue; *value = defaultValue;
return(false); return false;
} }
@ -247,11 +247,11 @@ bool IniFile::Get(const char* sectionName, const char* key, u32* value, u32 defa
if (retval && TryParseUInt(temp.c_str(), value)) if (retval && TryParseUInt(temp.c_str(), value))
{ {
return(true); return true;
} }
*value = defaultValue; *value = defaultValue;
return(false); return false;
} }
@ -262,11 +262,11 @@ bool IniFile::Get(const char* sectionName, const char* key, bool* value, bool de
if (retval && TryParseBool(temp.c_str(), value)) if (retval && TryParseBool(temp.c_str(), value))
{ {
return(true); return true;
} }
*value = defaultValue; *value = defaultValue;
return(false); return false;
} }
@ -276,7 +276,7 @@ bool IniFile::DeleteKey(const char* sectionName, const char* key)
if (!section) if (!section)
{ {
return(false); return false;
} }
std::string* line = GetLine(section, key, 0, 0); std::string* line = GetLine(section, key, 0, 0);
@ -286,11 +286,11 @@ bool IniFile::DeleteKey(const char* sectionName, const char* key)
if (line == &(*liter)) if (line == &(*liter))
{ {
section->lines.erase(liter); section->lines.erase(liter);
return(true); return true;
} }
} }
return(false); //shouldn't happen return false; //shouldn't happen
} }
@ -305,7 +305,7 @@ bool IniFile::Load(const char* filename)
if (in.fail()) if (in.fail())
{ {
return(false); return false;
} }
while (!in.eof()) while (!in.eof())
@ -345,7 +345,7 @@ bool IniFile::Load(const char* filename)
} }
in.close(); in.close();
return(true); return true;
} }
@ -356,7 +356,7 @@ bool IniFile::Save(const char* filename)
if (out.fail()) if (out.fail())
{ {
return(false); return false;
} }
for (std::vector<Section>::const_iterator iter = sections.begin(); iter != sections.end(); ++iter) for (std::vector<Section>::const_iterator iter = sections.begin(); iter != sections.end(); ++iter)
@ -376,7 +376,7 @@ bool IniFile::Save(const char* filename)
} }
out.close(); out.close();
return(true); return true;
} }
@ -386,7 +386,7 @@ bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys)
if (!section) if (!section)
{ {
return(false); return false;
} }
keys.clear(); keys.clear();
@ -398,26 +398,21 @@ bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys)
keys.push_back(key); keys.push_back(key);
} }
return(true); return true;
} }
bool IniFile::GetLines(const char* sectionName, std::vector<std::string>& lines) bool IniFile::GetLines(const char* sectionName, std::vector<std::string>& lines)
{ {
Section* section = GetSection(sectionName); Section* section = GetSection(sectionName);
if (!section) if (!section)
{ return false;
return(false);
}
lines.clear(); lines.clear();
for (std::vector<std::string>::const_iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter) for (std::vector<std::string>::const_iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter)
{ {
std::string line = StripSpaces(*iter); std::string line = StripSpaces(*iter);
int commentPos = (int)line.find('#'); int commentPos = (int)line.find('#');
if (commentPos == 0) if (commentPos == 0)
{ {
continue; continue;
@ -431,8 +426,7 @@ bool IniFile::GetLines(const char* sectionName, std::vector<std::string>& lines)
lines.push_back(line); lines.push_back(line);
} }
lines = section->lines; return true;
return(true);
} }

View File

@ -25,69 +25,61 @@
class Section class Section
{ {
public: public:
Section();
Section(const std::string& _name);
Section(const Section& other);
std::vector<std::string>lines;
std::string name;
std::string comment;
Section(); bool operator<(const Section& other) const
Section(const std::string& _name); {
Section(const Section& other); return(name < other.name);
std::vector<std::string>lines; }
std::string name;
std::string comment;
bool operator<(const Section& other) const
{
return(name < other.name);
}
}; };
class IniFile class IniFile
{ {
public: public:
IniFile();
~IniFile();
IniFile(); bool Load(const char* filename);
~IniFile(); bool Save(const char* filename);
bool Load(const char* filename); void Set(const char* sectionName, const char* key, const char* newValue);
bool Save(const char* filename); void Set(const char* sectionName, const char* key, int newValue);
void Set(const char* sectionName, const char* key, u32 newValue);
void Set(const char* sectionName, const char* key, bool newValue);
void Set(const char* sectionName, const char* key, const std::string& newValue) {Set(sectionName, key, newValue.c_str());}
void Set(const char* sectionName, const char* key, const std::vector<std::string>& newValues);
void Set(const char* sectionName, const char* key, const char* newValue); // getter should be const
void Set(const char* sectionName, const char* key, int newValue); bool Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue = "");
void Set(const char* sectionName, const char* key, u32 newValue); bool Get(const char* sectionName, const char* key, int* value, int defaultValue = 0);
void Set(const char* sectionName, const char* key, bool newValue); bool Get(const char* sectionName, const char* key, u32* value, u32 defaultValue = 0);
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);
void Set(const char* sectionName, const char* key, const std::string& newValue) {Set(sectionName, key, newValue.c_str());} bool DeleteKey(const char* sectionName, const char* key);
bool DeleteSection(const char* sectionName);
void SortSections();
void Set(const char* sectionName, const char* key, const std::vector<std::string>& newValues); void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut);
std::string* GetLine(Section* section, const char* key, std::string* valueOut, std::string* commentOut);
// getter should be const private:
bool Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue = ""); std::vector<Section>sections;
bool Get(const char* sectionName, const char* key, int* value, int defaultValue = 0);
bool Get(const char* sectionName, const char* key, u32* value, u32 defaultValue = 0);
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); Section* GetSection(const char* section);
bool GetLines(const char* sectionName, std::vector<std::string>& lines); Section* GetOrCreateSection(const char* section);
std::string* GetLine(const char* section, const char* key);
bool DeleteKey(const char* sectionName, const char* key); void CreateSection(const char* section);
bool DeleteSection(const char* sectionName);
void SortSections();
void ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut);
std::string* GetLine(Section* section, const char* key, std::string* valueOut, std::string* commentOut);
private:
std::vector<Section>sections;
Section* GetSection(const char* section);
Section* GetOrCreateSection(const char* section);
std::string* GetLine(const char* section, const char* key);
void CreateSection(const char* section);
}; };
#endif #endif

View File

@ -31,25 +31,21 @@
class MemArena class MemArena
{ {
public: public:
void GrabLowMemSpace(size_t size);
void ReleaseSpace();
void* CreateView(s64 offset, size_t size, bool ensure_low_mem = false);
void* CreateViewAt(s64 offset, size_t size, void* base);
void ReleaseView(void* view, size_t size);
void GrabLowMemSpace(size_t size); // This only finds 1 GB in 32-bit
void ReleaseSpace(); static u8* Find4GBBase();
void* CreateView(s64 offset, size_t size, bool ensure_low_mem = false); private:
void* CreateViewAt(s64 offset, size_t size, void* base);
void ReleaseView(void* view, size_t size);
// This only finds 1 GB in 32-bit
static u8* Find4GBBase();
private:
#ifdef _WIN32 #ifdef _WIN32
HANDLE hMemoryMapping; HANDLE hMemoryMapping;
#else #else
int fd; int fd;
#endif #endif
}; };

View File

@ -28,103 +28,35 @@ bool AsciiToHex(const char* _szValue, u32& result)
size_t finish = strlen(_szValue); size_t finish = strlen(_szValue);
if (finish > 8) if (finish > 8)
{ finish = 8; // Max 32-bit values are supported.
finish = 8;
}
for (size_t count = 0; count < finish; count++) for (size_t count = 0; count < finish; count++)
{ {
value <<= 4; value <<= 4;
switch (_szValue[count]) switch (_szValue[count])
{ {
case '0': case '0': break;
break; case '1': value += 1; break;
case '2': value += 2; break;
case '1': case '3': value += 3; break;
value += 1; case '4': value += 4; break;
break; case '5': value += 5; break;
case '6': value += 6; break;
case '2': case '7': value += 7; break;
value += 2; case '8': value += 8; break;
break; case '9': value += 9; break;
case '3':
value += 3;
break;
case '4':
value += 4;
break;
case '5':
value += 5;
break;
case '6':
value += 6;
break;
case '7':
value += 7;
break;
case '8':
value += 8;
break;
case '9':
value += 9;
break;
case 'A': case 'A':
value += 10; case 'a': value += 10; break;
break;
case 'a':
value += 10;
break;
case 'B': case 'B':
value += 11; case 'b': value += 11; break;
break;
case 'b':
value += 11;
break;
case 'C': case 'C':
value += 12; case 'c': value += 12; break;
break;
case 'c':
value += 12;
break;
case 'D': case 'D':
value += 13; case 'd': value += 13; break;
break;
case 'd':
value += 13;
break;
case 'E': case 'E':
value += 14; case 'e': value += 14; break;
break;
case 'e':
value += 14;
break;
case 'F': case 'F':
value += 15; case 'f': value += 15; break;
break;
case 'f':
value += 15;
break;
default: default:
return false; return false;
break; break;
@ -201,10 +133,10 @@ void ToStringFromFormat(std::string* out, const char* format, ...)
// Turns " hej " into "hej". Also handles tabs. // Turns " hej " into "hej". Also handles tabs.
std::string StripSpaces(std::string s) std::string StripSpaces(const std::string &str)
{ {
std::string s = str;
int i; int i;
for (i = 0; i < (int)s.size(); i++) for (i = 0; i < (int)s.size(); i++)
{ {
if ((s[i] != ' ') && (s[i] != 9)) if ((s[i] != ' ') && (s[i] != 9))
@ -223,7 +155,7 @@ std::string StripSpaces(std::string s)
} }
} }
return(s.substr(0, i + 1)); return s.substr(0, i + 1);
} }
@ -233,15 +165,23 @@ std::string StripSpaces(std::string s)
std::string StripQuotes(const std::string& s) std::string StripQuotes(const std::string& s)
{ {
if ((s[0] == '\"') && (s[s.size() - 1] == '\"')) if ((s[0] == '\"') && (s[s.size() - 1] == '\"'))
{ return s.substr(1, s.size() - 2);
return(s.substr(1, s.size() - 2));
}
else else
{ return s;
return(s);
}
} }
// "\"hello\"" is turned to "hello"
// This one assumes that the string has already been space stripped in both
// ends, as done by StripSpaces above, for example.
std::string StripNewline(const std::string& s)
{
if (!s.size())
return s;
else if (s[s.size() - 1] == '\n')
return s.substr(0, s.size() - 1);
else
return s;
}
bool TryParseInt(const char* str, int* outVal) bool TryParseInt(const char* str, int* outVal)
{ {
@ -261,7 +201,7 @@ bool TryParseInt(const char* str, int* outVal)
if ((c < '0') || (c > '9')) if ((c < '0') || (c > '9'))
{ {
return(false); return false;
} }
value = value * 10 + (c - '0'); value = value * 10 + (c - '0');
@ -270,7 +210,7 @@ bool TryParseInt(const char* str, int* outVal)
value = -value; value = -value;
*outVal = value; *outVal = value;
return(true); return true;
} }
@ -279,32 +219,28 @@ bool TryParseBool(const char* str, bool* output)
if ((str[0] == '1') || !strcmp(str, "true") || !strcmp(str, "True") || !strcmp(str, "TRUE")) if ((str[0] == '1') || !strcmp(str, "true") || !strcmp(str, "True") || !strcmp(str, "TRUE"))
{ {
*output = true; *output = true;
return(true); return true;
} }
else if (str[0] == '0' || !strcmp(str, "false") || !strcmp(str, "False") || !strcmp(str, "FALSE")) else if (str[0] == '0' || !strcmp(str, "false") || !strcmp(str, "False") || !strcmp(str, "FALSE"))
{ {
*output = false; *output = false;
return(true); return true;
} }
return false;
return(false);
} }
std::string StringFromInt(int value) std::string StringFromInt(int value)
{ {
char temp[16]; char temp[16];
sprintf(temp, "%i", value); sprintf(temp, "%i", value);
return(std::string(temp)); return std::string(temp);
} }
std::string StringFromBool(bool value) std::string StringFromBool(bool value)
{ {
return(value ? "True" : "False"); return value ? "True" : "False";
} }
#ifdef _WIN32 #ifdef _WIN32
bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension) bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension)
{ {
@ -330,10 +266,10 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
*_pExtension = ext; *_pExtension = ext;
} }
return(true); return true;
} }
return(false); return false;
} }
@ -344,14 +280,14 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
if (last_slash == std::string::npos) if (last_slash == std::string::npos)
{ {
return(false); return false;
} }
size_t last_dot = full_path.rfind('.'); size_t last_dot = full_path.rfind('.');
if ((last_dot == std::string::npos) || (last_dot < last_slash)) if ((last_dot == std::string::npos) || (last_dot < last_slash))
{ {
return(false); return false;
} }
if (_pPath) if (_pPath)
@ -374,7 +310,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
*_pFilename += full_path.substr(last_dot); *_pFilename += full_path.substr(last_dot);
} }
return(true); return true;
} }
@ -418,49 +354,20 @@ void SplitString(const std::string& str, const std::string& delim, std::vector<s
bool TryParseUInt(const std::string& str, u32* output) bool TryParseUInt(const std::string& str, u32* output)
{ {
if (!strcmp(str.substr(0, 2).c_str(), "0x") || !strcmp(str.substr(0, 2).c_str(), "0X")) if (!strcmp(str.substr(0, 2).c_str(), "0x") || !strcmp(str.substr(0, 2).c_str(), "0X"))
{ return sscanf(str.c_str() + 2, "%x", output) > 0;
return(sscanf(str.c_str() + 2, "%x", output) > 0);
}
else else
{ return sscanf(str.c_str(), "%d", output) > 0;
return(sscanf(str.c_str(), "%d", output) > 0);
}
} }
int ChooseStringFrom(const char* str, const char* * items) int ChooseStringFrom(const char* str, const char* * items)
{ {
int i = 0; int i = 0;
while (items[i] != 0) while (items[i] != 0)
{ {
if (!strcmp(str, items[i])) if (!strcmp(str, items[i]))
{ return i;
return(i);
}
i++; i++;
} }
return -1;
return(-1);
}
// Hmm, sometimes this test doesn't get run :P
TEST(splitStringTest)
{
/*
std::string orig = "abc:def";
std::vector<std::string> split;
SplitString(orig, std::string(":"), split);
CHECK(split.size() == 2);
CHECK(!strcmp(split[0].c_str(), "abc"));
CHECK(!strcmp(split[1].c_str(), "def"));
orig = "abc";
SplitString(orig, std::string(":"), split);
CHECK(split.size() == 1);
orig = ":";
SplitString(orig, std::string(":"), split);
CHECK(split.size() == 2);*/
} }

View File

@ -47,8 +47,9 @@ inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...)
} }
std::string StripSpaces(std::string s); std::string StripSpaces(const std::string &s);
std::string StripQuotes(const std::string& s); std::string StripQuotes(const std::string &s);
std::string StripNewline(const std::string &s);
std::string StringFromInt(int value); std::string StringFromInt(int value);

View File

@ -448,7 +448,6 @@ bool Init()
#ifdef _M_X64 #ifdef _M_X64
//Then, in x64 mode where we have space, grab a 4GB virtual address space //Then, in x64 mode where we have space, grab a 4GB virtual address space
//TODO: grab 8GB and align, for easier debugging
base = MemArena::Find4GBBase(); base = MemArena::Find4GBBase();
//OK, we know where to find free space. Now grab it! //OK, we know where to find free space. Now grab it!

View File

@ -173,47 +173,59 @@ void LoadActionReplayCodes(IniFile &ini)
if (!ini.GetLines("ActionReplay", lines)) if (!ini.GetLines("ActionReplay", lines))
return; return;
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
std::string line = StripSpaces(*iter); {
std::string line = *iter;
std::vector<std::string> pieces; std::vector<std::string> pieces;
SplitString(line, " ", pieces); SplitString(line, " ", pieces);
if (pieces.size() == 2 && pieces[0].size() == 8 && pieces[1].size() == 8) { if (pieces.size() == 2 && pieces[0].size() == 8 && pieces[1].size() == 8)
{
// Smells like a decrypted Action Replay code, great! Decode! // Smells like a decrypted Action Replay code, great! Decode!
AREntry op; AREntry op;
bool success = TryParseUInt(std::string("0x") + pieces[0], &op.cmd_addr); bool success = TryParseUInt(std::string("0x") + pieces[0], &op.cmd_addr);
success |= TryParseUInt(std::string("0x") + pieces[1], &op.value); success |= TryParseUInt(std::string("0x") + pieces[1], &op.value);
if (!success) { if (!success)
PanicAlert("Invalid AR code line: %s", line.c_str()); PanicAlert("Invalid AR code line: %s", line.c_str());
} else { else
currentCode.ops.push_back(op); currentCode.ops.push_back(op);
} }
} else { else
{
SplitString(line, "-", pieces); SplitString(line, "-", pieces);
if (pieces.size() == 3 && pieces[0].size() == 4 && pieces[1].size() == 4 && pieces[2].size() == 4) if (pieces.size() == 3 && pieces[0].size() == 4 && pieces[1].size() == 4 && pieces[2].size() == 4)
{ {
// Encrypted AR code // Encrypted AR code
PanicAlert("Dolphin does not yet support encrypted AR codes."); PanicAlert("Dolphin does not yet support encrypted AR codes.");
} }
else if (line.size()) { else if (line.size() > 1)
if (line[0] == '+') { {
// Active code // OK, name line. This is the start of a new code. Push the old one, prepare the new one.
if (currentCode.ops.size())
arCodes.push_back(currentCode);
currentCode.name = "(invalid)";
currentCode.ops.clear();
if (line[0] == '+')
{
// Active code - name line.
line = StripSpaces(line.substr(1)); line = StripSpaces(line.substr(1));
currentCode.name = line; currentCode.name = line;
currentCode.active = true; currentCode.active = true;
} }
else if (line[0] != '+') { else
{
// Inactive code.
currentCode.name = line; currentCode.name = line;
currentCode.active = false; currentCode.active = false;
} }
} else {
// Empty line - end of code. Push it.
arCodes.push_back(currentCode);
currentCode.name = "(invalid)";
currentCode.ops.clear();
} }
} }
arCodes.push_back(currentCode);
} }
// Handle the last code correctly.
if (currentCode.ops.size())
arCodes.push_back(currentCode);
} }
// The mechanism is slightly different than what the real AR uses, so there may be compatibility problems. // The mechanism is slightly different than what the real AR uses, so there may be compatibility problems.