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
|
||||
u64 size = File::GetSize(filename);
|
||||
if (size == 0)
|
||||
return false; //most likely: file does not exist
|
||||
if (size != SYSCONF_SIZE)
|
||||
{
|
||||
PanicAlertT("Your SYSCONF file is the wrong size - should be 0x%04x (but is 0x%04llx)",
|
||||
SYSCONF_SIZE, size);
|
||||
return false;
|
||||
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))
|
||||
{
|
||||
GenerateSysConf();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
FILE* f = fopen(filename, "rb");
|
||||
|
||||
|
@ -60,10 +63,7 @@ bool SysConf::LoadFromFile(const char *filename)
|
|||
return false;
|
||||
bool result = LoadFromFileInternal(f);
|
||||
if (result)
|
||||
{
|
||||
// OK, done!
|
||||
m_Filename = filename;
|
||||
}
|
||||
fclose(f);
|
||||
return result;
|
||||
}
|
||||
|
@ -71,11 +71,12 @@ bool SysConf::LoadFromFile(const char *filename)
|
|||
bool SysConf::LoadFromFileInternal(FILE *f)
|
||||
{
|
||||
// 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;
|
||||
SSysConfHeader s_Header;
|
||||
if (fread(&s_Header.version, sizeof(s_Header.version), 1, f) != 1) return false;
|
||||
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;
|
||||
if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false;
|
||||
|
@ -136,6 +137,217 @@ bool SysConf::LoadFromFileInternal(FILE *f)
|
|||
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)
|
||||
{
|
||||
FILE *f = fopen(filename, "r+b");
|
||||
|
|
|
@ -180,9 +180,9 @@ public:
|
|||
|
||||
private:
|
||||
bool LoadFromFileInternal(FILE *f);
|
||||
void GenerateSysConf();
|
||||
void Clear();
|
||||
|
||||
SSysConfHeader m_Header;
|
||||
std::string m_Filename;
|
||||
std::string m_FilenameDefault;
|
||||
std::vector<SSysConfEntry> m_Entries;
|
||||
|
|
Loading…
Reference in New Issue