diff options
| author | Shawn Hoffman <godisgovernment@gmail.com> | 2009-09-14 06:26:49 +0000 |
|---|---|---|
| committer | Shawn Hoffman <godisgovernment@gmail.com> | 2009-09-14 06:26:49 +0000 |
| commit | aff34e678952e020091bde24360c970f7a0a5903 (patch) | |
| tree | 0fe3c74024a75a3f00c7e544b28d22b41d38de5e /Source/Core/Common | |
| parent | a08c801256b6b409fd46217d73ac120905004094 (diff) | |
revamp handling of wii sysconf. it's in Common lib so that plugins can (possibly) utilize it if they like
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4268 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/Common')
| -rw-r--r-- | Source/Core/Common/Common.vcproj | 10 | ||||
| -rw-r--r-- | Source/Core/Common/Src/SysConf.cpp | 156 | ||||
| -rw-r--r-- | Source/Core/Common/Src/SysConf.h | 122 |
3 files changed, 287 insertions, 1 deletions
diff --git a/Source/Core/Common/Common.vcproj b/Source/Core/Common/Common.vcproj index 93958f9d86..628ca6e250 100644 --- a/Source/Core/Common/Common.vcproj +++ b/Source/Core/Common/Common.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9,00"
+ Version="9.00"
Name="Common"
ProjectGUID="{C573CAF7-EE6A-458E-8049-16C0BF34C2E9}"
RootNamespace="Common"
@@ -813,6 +813,14 @@ >
</File>
<File
+ RelativePath=".\Src\SysConf.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Src\SysConf.h"
+ >
+ </File>
+ <File
RelativePath=".\Src\Thread.cpp"
>
</File>
diff --git a/Source/Core/Common/Src/SysConf.cpp b/Source/Core/Common/Src/SysConf.cpp new file mode 100644 index 0000000000..38c4f6f549 --- /dev/null +++ b/Source/Core/Common/Src/SysConf.cpp @@ -0,0 +1,156 @@ +// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "FileUtil.h"
+#include "SysConf.h"
+
+SysConf::SysConf()
+: m_IsValid(false)
+{
+ if (LoadFromFile(WII_SYSCONF_FILE))
+ m_IsValid = true;
+}
+
+SysConf::~SysConf()
+{
+ if (!m_IsValid)
+ return;
+
+ Save();
+
+ for (size_t i = 0; i < m_Entries.size() - 1; i++)
+ {
+ delete [] m_Entries.at(i).data;
+ m_Entries.at(i).data = NULL;
+ }
+}
+
+bool SysConf::LoadFromFile(const char *filename)
+{
+ FILE* f = fopen(filename, "rb");
+
+ if (f == NULL)
+ return false;
+
+ // Basic check
+ if (File::GetSize(filename) != SYSCONF_SIZE)
+ {
+ PanicAlert("Your SYSCONF file is the wrong size - should be 0x%04x", SYSCONF_SIZE);
+ return false;
+ }
+
+ // Fill in infos
+ if (fread(&m_Header.version, sizeof(m_Header.version), 1, f) != 1) return false;
+ if (fread(&m_Header.numEntries, sizeof(m_Header.numEntries), 1, f) != 1) return false;
+ m_Header.numEntries = Common::swap16(m_Header.numEntries) + 1;
+
+ for (u16 index = 0; index < m_Header.numEntries; index++)
+ {
+ SSysConfEntry tmpEntry;
+ if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false;
+ tmpEntry.offset = Common::swap16(tmpEntry.offset);
+ m_Entries.push_back(tmpEntry);
+ }
+
+ // Last offset is an invalid entry. We ignore it throughout this class
+ for (size_t i = 0; i < m_Entries.size() - 1; i++)
+ {
+ SSysConfEntry& curEntry = m_Entries.at(i);
+ if (fseek(f, curEntry.offset, SEEK_SET) != 0) return false;
+
+ u8 description = 0;
+ if (fread(&description, sizeof(description), 1, f) != 1) return false;
+ // Data type
+ curEntry.type = (SysconfType)((description & 0xe0) >> 5);
+ // Length of name in bytes - 1
+ curEntry.nameLength = (description & 0x1f) + 1;
+ // Name
+ if (fread(&curEntry.name, curEntry.nameLength, 1, f) != 1) return false;
+ curEntry.name[curEntry.nameLength] = '\0';
+ // Get length of data
+ curEntry.dataLength = 0;
+ switch (curEntry.type)
+ {
+ case Type_BigArray:
+ if (fread(&curEntry.dataLength, 2, 1, f) != 1) return false;
+ curEntry.dataLength = Common::swap16(curEntry.dataLength);
+ break;
+ case Type_SmallArray:
+ if (fread(&curEntry.dataLength, 1, 1, f) != 1) return false;
+ break;
+ case Type_Byte:
+ case Type_Bool:
+ curEntry.dataLength = 1;
+ break;
+ case Type_Short:
+ curEntry.dataLength = 2;
+ break;
+ case Type_Long:
+ curEntry.dataLength = 4;
+ break;
+ default:
+ PanicAlert("Unknown entry type %i in SYSCONF (%s@%x)!",
+ curEntry.type, curEntry.name, curEntry.offset);
+ return false;
+ }
+ // Fill in the actual data
+ if (curEntry.dataLength)
+ {
+ curEntry.data = new u8[curEntry.dataLength];
+ if (fread(curEntry.data, curEntry.dataLength, 1, f) != 1) return false;
+ }
+ }
+
+ // OK!, done!
+ m_Filename = filename;
+ fclose(f);
+ return true;
+}
+
+bool SysConf::SaveToFile(const char *filename)
+{
+ FILE *f = fopen(filename, "r+b");
+
+ if (f == NULL)
+ return false;
+
+ for (size_t i = 0; i < m_Entries.size() - 1; i++)
+ {
+ // Seek to after the name of this entry
+ if (fseek(f, m_Entries.at(i).offset + m_Entries.at(i).nameLength + 1, SEEK_SET) != 0) return false;
+ // We may have to write array length value...
+ if (m_Entries.at(i).type == Type_BigArray)
+ {
+ u16 tmpDataLength = Common::swap16(m_Entries.at(i).dataLength);
+ if (fwrite(&tmpDataLength, 2, 1, f) != 1) return false;
+ }
+ else if (m_Entries.at(i).type == Type_SmallArray)
+ {
+ if (fwrite(&m_Entries.at(i).dataLength, 1, 1, f) != 1) return false;
+ }
+ // Now write the actual data
+ if (fwrite(m_Entries.at(i).data, m_Entries.at(i).dataLength, 1, f) != 1) return false;
+ }
+
+ fclose(f);
+ return true;
+}
+
+bool SysConf::Save()
+{
+ return SaveToFile(m_Filename.c_str());
+}
diff --git a/Source/Core/Common/Src/SysConf.h b/Source/Core/Common/Src/SysConf.h new file mode 100644 index 0000000000..e58f2618d6 --- /dev/null +++ b/Source/Core/Common/Src/SysConf.h @@ -0,0 +1,122 @@ +// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef __SYSCONF_MANAGER_h__
+#define __SYSCONF_MANAGER_h__
+
+// This class is meant to edit the values in a given Wii SYSCONF file
+// It currently does not add/remove/rearrange sections,
+// instead only modifies exiting sections' data
+
+#define SYSCONF_SIZE 0x4000
+
+enum SysconfType
+{
+ Type_BigArray = 1,
+ Type_SmallArray,
+ Type_Byte,
+ Type_Short,
+ Type_Long,
+ Type_Unknown,
+ Type_Bool
+};
+
+struct SSysConfHeader
+{
+ char version[4];
+ u16 numEntries;
+};
+
+struct SSysConfEntry
+{
+ u16 offset;
+ SysconfType type;
+ u8 nameLength;
+ char name[32];
+ u16 dataLength;
+ u8* data;
+
+ template<class T>
+ T GetData() { return *(T*)data; }
+};
+
+class SysConf
+{
+private:
+ SSysConfHeader m_Header;
+ std::string m_Filename;
+ std::vector<SSysConfEntry> m_Entries;
+ bool m_IsValid;
+
+public:
+ SysConf();
+ ~SysConf();
+
+ bool IsValid() { return m_IsValid; }
+
+ template<class T>
+ T GetData(const char* sectionName)
+ {
+ if (!m_IsValid)
+ {
+ PanicAlert("Trying to read from invalid SYSCONF");
+ return 0;
+ }
+
+ size_t index = 0;
+ for (index; index < m_Entries.size() - 1; index++)
+ {
+ if (strcmp(m_Entries.at(index).name, sectionName) == 0)
+ break;
+ }
+ if (index == m_Entries.size() - 1)
+ {
+ PanicAlert("Section %s not found in SYSCONF", sectionName);
+ return 0;
+ }
+
+ return m_Entries.at(index).GetData<T>();
+ }
+
+ template<class T>
+ bool SetData(const char* sectionName, T newValue)
+ {
+ if (!m_IsValid)
+ return false;
+
+ size_t index = 0;
+ for (index; index < m_Entries.size() - 1; index++)
+ {
+ if (strcmp(m_Entries.at(index).name, sectionName) == 0)
+ break;
+ }
+ if (index == m_Entries.size() - 1)
+ {
+ PanicAlert("Section %s not found in SYSCONF", sectionName);
+ return false;
+ }
+
+ *(T*)m_Entries.at(index).data = newValue;
+ return true;
+ }
+
+ bool Save();
+ bool SaveToFile(const char* filename);
+ bool LoadFromFile(const char* filename);
+};
+
+#endif // __SYSCONF_MANAGER_h__
|
