Somewhat experimental. If the SYSCONF file is not found or is invalid then generate one. For now ask the user if this should be done. The generated SYSCONF file works for me with the games I have tested, but this needs further testing. Unfortunately, most users will never use this as they will have the SYSCONF file anyway. Eventually we could perhaps remove the distributed SYSCONF, and generate it the first time dolphin is run.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7311 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
99e6c47497
commit
a734b3f057
|
@ -46,13 +46,16 @@ bool SysConf::LoadFromFile(const char *filename)
|
||||||
{
|
{
|
||||||
// Basic check
|
// Basic check
|
||||||
u64 size = File::GetSize(filename);
|
u64 size = File::GetSize(filename);
|
||||||
if (size == 0)
|
|
||||||
return false; //most likely: file does not exist
|
|
||||||
if (size != SYSCONF_SIZE)
|
if (size != SYSCONF_SIZE)
|
||||||
{
|
{
|
||||||
PanicAlertT("Your SYSCONF file is the wrong size - should be 0x%04x (but is 0x%04llx)",
|
if (AskYesNoT("Your SYSCONF file is the wrong size.\nIt should be 0x%04x (but is 0x%04llx)\nDo you want to generate a new one?",
|
||||||
SYSCONF_SIZE, size);
|
SYSCONF_SIZE, size))
|
||||||
return false;
|
{
|
||||||
|
GenerateSysConf();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
FILE* f = fopen(filename, "rb");
|
FILE* f = fopen(filename, "rb");
|
||||||
|
|
||||||
|
@ -60,10 +63,7 @@ bool SysConf::LoadFromFile(const char *filename)
|
||||||
return false;
|
return false;
|
||||||
bool result = LoadFromFileInternal(f);
|
bool result = LoadFromFileInternal(f);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
|
||||||
// OK, done!
|
|
||||||
m_Filename = filename;
|
m_Filename = filename;
|
||||||
}
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -71,11 +71,12 @@ bool SysConf::LoadFromFile(const char *filename)
|
||||||
bool SysConf::LoadFromFileInternal(FILE *f)
|
bool SysConf::LoadFromFileInternal(FILE *f)
|
||||||
{
|
{
|
||||||
// Fill in infos
|
// Fill in infos
|
||||||
if (fread(&m_Header.version, sizeof(m_Header.version), 1, f) != 1) return false;
|
SSysConfHeader s_Header;
|
||||||
if (fread(&m_Header.numEntries, sizeof(m_Header.numEntries), 1, f) != 1) return false;
|
if (fread(&s_Header.version, sizeof(s_Header.version), 1, f) != 1) return false;
|
||||||
m_Header.numEntries = Common::swap16(m_Header.numEntries) + 1;
|
if (fread(&s_Header.numEntries, sizeof(s_Header.numEntries), 1, f) != 1) return false;
|
||||||
|
s_Header.numEntries = Common::swap16(s_Header.numEntries) + 1;
|
||||||
|
|
||||||
for (u16 index = 0; index < m_Header.numEntries; index++)
|
for (u16 index = 0; index < s_Header.numEntries; index++)
|
||||||
{
|
{
|
||||||
SSysConfEntry tmpEntry;
|
SSysConfEntry tmpEntry;
|
||||||
if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false;
|
if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false;
|
||||||
|
@ -136,6 +137,217 @@ bool SysConf::LoadFromFileInternal(FILE *f)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the size of the item in file
|
||||||
|
unsigned int create_item(SSysConfEntry &item, SysconfType type, const std::string &name,
|
||||||
|
const int data_length, unsigned int offset)
|
||||||
|
{
|
||||||
|
item.offset = offset;
|
||||||
|
item.type = type;
|
||||||
|
item.nameLength = name.length();
|
||||||
|
strncpy(item.name, name.c_str(), 32);
|
||||||
|
item.dataLength = data_length;
|
||||||
|
item.data = new u8[data_length];
|
||||||
|
memset(item.data, 0, data_length);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case Type_BigArray:
|
||||||
|
// size of description + name length + size of dataLength + data length + null
|
||||||
|
return 1 + item.nameLength + 2 + item.dataLength + 1;
|
||||||
|
case Type_SmallArray:
|
||||||
|
// size of description + name length + size of dataLength + data length + null
|
||||||
|
return 1 + item.nameLength + 1 + item.dataLength + 1;
|
||||||
|
case Type_Byte:
|
||||||
|
case Type_Bool:
|
||||||
|
case Type_Short:
|
||||||
|
case Type_Long:
|
||||||
|
// size of description + name length + data length
|
||||||
|
return 1 + item.nameLength + item.dataLength;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysConf::GenerateSysConf()
|
||||||
|
{
|
||||||
|
SSysConfHeader s_Header;
|
||||||
|
strncpy(s_Header.version, "SCv0", 4);
|
||||||
|
s_Header.numEntries = Common::swap16(28 - 1);
|
||||||
|
|
||||||
|
SSysConfEntry items[27];
|
||||||
|
memset(items, 0, sizeof(SSysConfEntry) * 27);
|
||||||
|
|
||||||
|
// version length + size of numEntries + 28 * size of offset
|
||||||
|
unsigned int current_offset = 4 + 2 + 28 * 2;
|
||||||
|
|
||||||
|
// BT.DINF
|
||||||
|
current_offset += create_item(items[0], Type_BigArray, "BT.DINF", 0x460, current_offset);
|
||||||
|
items[0].data[0] = 4;
|
||||||
|
for (unsigned int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
const u8 bt_addr[6] = {i, 0x00, 0x79, 0x19, 0x02, 0x11};
|
||||||
|
memcpy(&items[0].data[1 + 70 * i], bt_addr, sizeof(bt_addr));
|
||||||
|
memcpy(&items[0].data[7 + 70 * i], "Nintendo RVL-CNT-01", 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BT.SENS
|
||||||
|
current_offset += create_item(items[1], Type_Long, "BT.SENS", 4, current_offset);
|
||||||
|
items[1].data[3] = 0x03;
|
||||||
|
|
||||||
|
// IPL.NIK
|
||||||
|
current_offset += create_item(items[2], Type_SmallArray, "IPL.NIK", 0x15, current_offset);
|
||||||
|
const u8 console_nick[14] = {0, 'd', 0, 'o', 0, 'l', 0, 'p', 0, 'h', 0, 'i', 0, 'n'};
|
||||||
|
memcpy(items[2].data, console_nick, 14);
|
||||||
|
|
||||||
|
// IPL.AR
|
||||||
|
current_offset += create_item(items[3], Type_Byte, "IPL.AR", 1, current_offset);
|
||||||
|
items[3].data[0] = 0x01;
|
||||||
|
|
||||||
|
// BT.BAR
|
||||||
|
current_offset += create_item(items[4], Type_Byte, "BT.BAR", 1, current_offset);
|
||||||
|
items[4].data[0] = 0x01;
|
||||||
|
|
||||||
|
// IPL.SSV
|
||||||
|
current_offset += create_item(items[5], Type_Byte, "IPL.SSV", 1, current_offset);
|
||||||
|
|
||||||
|
// IPL.LNG
|
||||||
|
current_offset += create_item(items[6], Type_Byte, "IPL.LNG", 1, current_offset);
|
||||||
|
items[6].data[0] = 0x01;
|
||||||
|
|
||||||
|
// IPL.SADR
|
||||||
|
current_offset += create_item(items[7], Type_BigArray, "IPL.SADR", 0x1007, current_offset);
|
||||||
|
items[7].data[0] = 0x6c;
|
||||||
|
|
||||||
|
// IPL.CB
|
||||||
|
current_offset += create_item(items[8], Type_Long, "IPL.CB", 4, current_offset);
|
||||||
|
items[8].data[0] = 0x0f; items[8].data[1] = 0x11;
|
||||||
|
items[8].data[2] = 0x14; items[8].data[3] = 0xa6;
|
||||||
|
|
||||||
|
// BT.SPKV
|
||||||
|
current_offset += create_item(items[9], Type_Byte, "BT.SPKV", 1, current_offset);
|
||||||
|
items[9].data[0] = 0x58;
|
||||||
|
|
||||||
|
// IPL.PC
|
||||||
|
current_offset += create_item(items[10], Type_SmallArray, "IPL.PC", 0x49, current_offset);
|
||||||
|
items[10].data[1] = 0x04; items[10].data[2] = 0x14;
|
||||||
|
|
||||||
|
// NET.CTPC
|
||||||
|
current_offset += create_item(items[11], Type_Long, "NET.CTPC", 4, current_offset);
|
||||||
|
|
||||||
|
// WWW.RST
|
||||||
|
current_offset += create_item(items[12], Type_Bool, "WWW.RST", 1, current_offset);
|
||||||
|
|
||||||
|
// BT.CDIF
|
||||||
|
current_offset += create_item(items[13], Type_BigArray, "BT.CDIF", 0x204, current_offset);
|
||||||
|
|
||||||
|
// IPL.INC
|
||||||
|
current_offset += create_item(items[14], Type_Long, "IPL.INC", 4, current_offset);
|
||||||
|
items[14].data[3] = 0x08;
|
||||||
|
|
||||||
|
// IPL.FRC
|
||||||
|
current_offset += create_item(items[15], Type_Long, "IPL.FRC", 4, current_offset);
|
||||||
|
items[15].data[3] = 0x28;
|
||||||
|
|
||||||
|
// IPL.CD
|
||||||
|
current_offset += create_item(items[16], Type_Bool, "IPL.CD", 1, current_offset);
|
||||||
|
items[16].data[0] = 0x01;
|
||||||
|
|
||||||
|
// IPL.CD2
|
||||||
|
current_offset += create_item(items[17], Type_Bool, "IPL.CD2", 1, current_offset);
|
||||||
|
items[17].data[0] = 0x01;
|
||||||
|
|
||||||
|
// IPL.UPT
|
||||||
|
current_offset += create_item(items[18], Type_Byte, "IPL.UPT", 1, current_offset);
|
||||||
|
items[18].data[0] = 0x02;
|
||||||
|
|
||||||
|
// IPL.PGS
|
||||||
|
current_offset += create_item(items[19], Type_Byte, "IPL.PGS", 1, current_offset);
|
||||||
|
|
||||||
|
// IPL.E60
|
||||||
|
current_offset += create_item(items[20], Type_Byte, "IPL.E60", 1, current_offset);
|
||||||
|
items[20].data[0] = 0x01;
|
||||||
|
|
||||||
|
// IPL.DH
|
||||||
|
current_offset += create_item(items[21], Type_Byte, "IPL.DH", 1, current_offset);
|
||||||
|
|
||||||
|
// NET.WCFG
|
||||||
|
current_offset += create_item(items[22], Type_Long, "NET.WCFG", 4, current_offset);
|
||||||
|
items[22].data[3] = 0x01;
|
||||||
|
|
||||||
|
// IPL.IDL
|
||||||
|
current_offset += create_item(items[23], Type_SmallArray, "IPL.IDL", 1, current_offset);
|
||||||
|
items[23].data[0] = 0x01;
|
||||||
|
|
||||||
|
// IPL.EULA
|
||||||
|
current_offset += create_item(items[24], Type_Bool, "IPL.EULA", 1, current_offset);
|
||||||
|
items[24].data[0] = 0x01;
|
||||||
|
|
||||||
|
// BT.MOT
|
||||||
|
current_offset += create_item(items[25], Type_Byte, "BT.MOT", 1, current_offset);
|
||||||
|
items[25].data[0] = 0x01;
|
||||||
|
|
||||||
|
// MPLS.MOVIE
|
||||||
|
current_offset += create_item(items[26], Type_Bool, "MPLS.MOVIE", 1, current_offset);
|
||||||
|
items[26].data[0] = 0x01;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < 27; i++)
|
||||||
|
m_Entries.push_back(items[i]);
|
||||||
|
|
||||||
|
File::CreateFullPath(m_FilenameDefault);
|
||||||
|
FILE *g = fopen(m_FilenameDefault.c_str(), "wb");
|
||||||
|
|
||||||
|
// Write the header and item offsets
|
||||||
|
fwrite(&s_Header.version, sizeof(s_Header.version), 1, g);
|
||||||
|
fwrite(&s_Header.numEntries, sizeof(u16), 1, g);
|
||||||
|
for (int i = 0; i < 27; ++i)
|
||||||
|
{
|
||||||
|
u16 tmp_offset = Common::swap16(items[i].offset);
|
||||||
|
fwrite(&tmp_offset, 2, 1, g);
|
||||||
|
}
|
||||||
|
const u16 end_data_offset = Common::swap16(current_offset);
|
||||||
|
fwrite(&end_data_offset, 2, 1, g);
|
||||||
|
|
||||||
|
// Write the items
|
||||||
|
const u8 null_byte = 0;
|
||||||
|
for (int i = 0; i < 27; ++i)
|
||||||
|
{
|
||||||
|
u8 description = (items[i].type << 5) | (items[i].nameLength - 1);
|
||||||
|
fwrite(&description, sizeof(description), 1, g);
|
||||||
|
fwrite(&items[i].name, items[i].nameLength, 1, g);
|
||||||
|
switch (items[i].type)
|
||||||
|
{
|
||||||
|
case Type_BigArray:
|
||||||
|
{
|
||||||
|
u16 tmpDataLength = Common::swap16(items[i].dataLength);
|
||||||
|
fwrite(&tmpDataLength, 2, 1, g);
|
||||||
|
fwrite(items[i].data, items[i].dataLength, 1, g);
|
||||||
|
fwrite(&null_byte, 1, 1, g);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type_SmallArray:
|
||||||
|
fwrite(&items[i].dataLength, 1, 1, g);
|
||||||
|
fwrite(items[i].data, items[i].dataLength, 1, g);
|
||||||
|
fwrite(&null_byte, 1, 1, g);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fwrite(items[i].data, items[i].dataLength, 1, g);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pad file to the correct size
|
||||||
|
const u64 cur_size = File::GetSize(g);
|
||||||
|
for (unsigned int i = 0; i < 16380 - cur_size; ++i)
|
||||||
|
fwrite(&null_byte, 1, 1, g);
|
||||||
|
|
||||||
|
// Write the footer
|
||||||
|
const char footer[5] = "SCed";
|
||||||
|
fwrite(&footer, 4, 1, g);
|
||||||
|
|
||||||
|
fclose(g);
|
||||||
|
m_Filename = m_FilenameDefault;
|
||||||
|
}
|
||||||
|
|
||||||
bool SysConf::SaveToFile(const char *filename)
|
bool SysConf::SaveToFile(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "r+b");
|
FILE *f = fopen(filename, "r+b");
|
||||||
|
|
|
@ -180,9 +180,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool LoadFromFileInternal(FILE *f);
|
bool LoadFromFileInternal(FILE *f);
|
||||||
|
void GenerateSysConf();
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
SSysConfHeader m_Header;
|
|
||||||
std::string m_Filename;
|
std::string m_Filename;
|
||||||
std::string m_FilenameDefault;
|
std::string m_FilenameDefault;
|
||||||
std::vector<SSysConfEntry> m_Entries;
|
std::vector<SSysConfEntry> m_Entries;
|
||||||
|
|
Loading…
Reference in New Issue