2013-04-17 21:09:55 -06:00
|
|
|
// Copyright 2013 Dolphin Emulator Project
|
|
|
|
// Licensed under GPLv2
|
|
|
|
// Refer to the license.txt file included.
|
2010-02-19 10:05:26 -07:00
|
|
|
|
2014-02-10 11:54:46 -07:00
|
|
|
#pragma once
|
2010-02-19 10:05:26 -07:00
|
|
|
|
2014-05-02 20:47:04 -06:00
|
|
|
#include <algorithm>
|
2014-02-19 20:11:52 -07:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
2010-02-19 10:05:26 -07:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2014-02-17 03:18:15 -07:00
|
|
|
#include "Common/Common.h"
|
|
|
|
|
2010-02-19 10:05:26 -07:00
|
|
|
// 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; }
|
2010-12-22 01:00:08 -07:00
|
|
|
bool GetArrayData(u8* dest, u16 destSize)
|
|
|
|
{
|
|
|
|
if (dest && destSize >= dataLength)
|
|
|
|
{
|
|
|
|
memcpy(dest, data, dataLength);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool SetArrayData(u8* buffer, u16 bufferSize)
|
|
|
|
{
|
2011-08-21 22:10:58 -06:00
|
|
|
if (buffer)
|
2010-12-22 01:00:08 -07:00
|
|
|
{
|
2014-05-02 20:47:04 -06:00
|
|
|
memcpy(data, buffer, std::min<u16>(bufferSize, dataLength));
|
2010-12-22 01:00:08 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2010-02-19 10:05:26 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
class SysConf
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SysConf();
|
|
|
|
~SysConf();
|
|
|
|
|
|
|
|
bool IsValid() { return m_IsValid; }
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
T GetData(const char* sectionName)
|
|
|
|
{
|
|
|
|
if (!m_IsValid)
|
|
|
|
{
|
2011-01-12 19:05:58 -07:00
|
|
|
PanicAlertT("Trying to read from invalid SYSCONF");
|
2010-02-19 10:05:26 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-03 15:47:48 -07:00
|
|
|
std::vector<SSysConfEntry>::iterator index = m_Entries.begin();
|
2014-02-12 08:00:34 -07:00
|
|
|
for (; index < m_Entries.end() - 1; ++index)
|
2010-02-19 10:05:26 -07:00
|
|
|
{
|
2011-03-03 15:47:48 -07:00
|
|
|
if (strcmp(index->name, sectionName) == 0)
|
2010-02-19 10:05:26 -07:00
|
|
|
break;
|
|
|
|
}
|
2011-03-03 15:47:48 -07:00
|
|
|
if (index == m_Entries.end() - 1)
|
2010-02-19 10:05:26 -07:00
|
|
|
{
|
2011-01-12 19:05:58 -07:00
|
|
|
PanicAlertT("Section %s not found in SYSCONF", sectionName);
|
2010-02-19 10:05:26 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-03 15:47:48 -07:00
|
|
|
return index->GetData<T>();
|
2010-02-19 10:05:26 -07:00
|
|
|
}
|
|
|
|
|
2010-12-22 01:00:08 -07:00
|
|
|
bool GetArrayData(const char* sectionName, u8* dest, u16 destSize)
|
|
|
|
{
|
|
|
|
if (!m_IsValid)
|
|
|
|
{
|
2011-01-12 19:05:58 -07:00
|
|
|
PanicAlertT("Trying to read from invalid SYSCONF");
|
2010-12-22 01:00:08 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-03 15:47:48 -07:00
|
|
|
std::vector<SSysConfEntry>::iterator index = m_Entries.begin();
|
2014-02-12 08:00:34 -07:00
|
|
|
for (; index < m_Entries.end() - 1; ++index)
|
2010-12-22 01:00:08 -07:00
|
|
|
{
|
2011-03-03 15:47:48 -07:00
|
|
|
if (strcmp(index->name, sectionName) == 0)
|
2010-12-22 01:00:08 -07:00
|
|
|
break;
|
|
|
|
}
|
2011-03-03 15:47:48 -07:00
|
|
|
if (index == m_Entries.end() - 1)
|
2010-12-22 01:00:08 -07:00
|
|
|
{
|
2011-01-12 19:05:58 -07:00
|
|
|
PanicAlertT("Section %s not found in SYSCONF", sectionName);
|
2010-12-22 01:00:08 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-03 15:47:48 -07:00
|
|
|
return index->GetArrayData(dest, destSize);
|
2010-12-22 01:00:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SetArrayData(const char* sectionName, u8* buffer, u16 bufferSize)
|
|
|
|
{
|
|
|
|
if (!m_IsValid)
|
|
|
|
return false;
|
|
|
|
|
2011-03-03 15:47:48 -07:00
|
|
|
std::vector<SSysConfEntry>::iterator index = m_Entries.begin();
|
2014-02-12 08:00:34 -07:00
|
|
|
for (; index < m_Entries.end() - 1; ++index)
|
2010-12-22 01:00:08 -07:00
|
|
|
{
|
2011-03-03 15:47:48 -07:00
|
|
|
if (strcmp(index->name, sectionName) == 0)
|
2010-12-22 01:00:08 -07:00
|
|
|
break;
|
|
|
|
}
|
2011-03-03 15:47:48 -07:00
|
|
|
if (index == m_Entries.end() - 1)
|
2010-12-22 01:00:08 -07:00
|
|
|
{
|
2011-01-12 19:05:58 -07:00
|
|
|
PanicAlertT("Section %s not found in SYSCONF", sectionName);
|
2010-12-22 01:00:08 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-03-03 15:47:48 -07:00
|
|
|
return index->SetArrayData(buffer, bufferSize);
|
2010-12-22 01:00:08 -07:00
|
|
|
}
|
|
|
|
|
2010-02-19 10:05:26 -07:00
|
|
|
template<class T>
|
|
|
|
bool SetData(const char* sectionName, T newValue)
|
|
|
|
{
|
|
|
|
if (!m_IsValid)
|
|
|
|
return false;
|
|
|
|
|
2011-03-03 15:47:48 -07:00
|
|
|
std::vector<SSysConfEntry>::iterator index = m_Entries.begin();
|
2014-02-12 08:00:34 -07:00
|
|
|
for (; index < m_Entries.end() - 1; ++index)
|
2010-02-19 10:05:26 -07:00
|
|
|
{
|
2011-03-03 15:47:48 -07:00
|
|
|
if (strcmp(index->name, sectionName) == 0)
|
2010-02-19 10:05:26 -07:00
|
|
|
break;
|
|
|
|
}
|
2011-03-03 15:47:48 -07:00
|
|
|
if (index == m_Entries.end() - 1)
|
2010-02-19 10:05:26 -07:00
|
|
|
{
|
2011-01-12 19:05:58 -07:00
|
|
|
PanicAlertT("Section %s not found in SYSCONF", sectionName);
|
2010-02-19 10:05:26 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-03-03 15:47:48 -07:00
|
|
|
*(T*)index->data = newValue;
|
2010-02-19 10:05:26 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Save();
|
2014-03-12 13:33:41 -06:00
|
|
|
bool SaveToFile(const std::string& filename);
|
|
|
|
bool LoadFromFile(const std::string& filename);
|
2011-03-02 17:07:33 -07:00
|
|
|
bool Reload();
|
2011-05-24 13:12:18 -06:00
|
|
|
// This function is used when the NAND root is changed
|
|
|
|
void UpdateLocation();
|
2011-03-02 17:07:33 -07:00
|
|
|
|
2010-02-19 10:05:26 -07:00
|
|
|
private:
|
2011-03-11 05:56:26 -07:00
|
|
|
bool LoadFromFileInternal(FILE *fh);
|
2011-03-06 09:57:58 -07:00
|
|
|
void GenerateSysConf();
|
2011-03-02 17:07:33 -07:00
|
|
|
void Clear();
|
|
|
|
|
|
|
|
std::string m_Filename;
|
|
|
|
std::string m_FilenameDefault;
|
|
|
|
std::vector<SSysConfEntry> m_Entries;
|
|
|
|
bool m_IsValid;
|
2010-02-19 10:05:26 -07:00
|
|
|
};
|