Refectored f2_header and f2_struct

This commit is contained in:
korenkonder
2024-11-22 01:28:42 +03:00
parent 560ed0b678
commit dd1eba3cae
25 changed files with 626 additions and 363 deletions
+25 -25
View File
@@ -264,7 +264,7 @@ namespace Glitter {
}
void FileReader::ParseAnimation(f2_struct* st, Animation* anim) {
if (!st || !st->header.data_size
if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('ANIM'))
return;
@@ -273,7 +273,7 @@ namespace Glitter {
}
void FileReader::ParseCurve(f2_struct* st, Animation* anim) {
if (!st || !st->header.data_size
if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('CURV'))
return;
@@ -286,7 +286,7 @@ namespace Glitter {
uint32_t keys_count;
if (type == Glitter::X) {
if (st->header.version == 1) {
if (st->header.use_big_endian) {
if (st->header.attrib.get_big_endian()) {
c->type = (CurveType)load_reverse_endianness_uint32_t((void*)d);
c->repeat = load_reverse_endianness_uint32_t((void*)(d + 4)) != 0;
c->flags = (CurveFlag)load_reverse_endianness_uint32_t((void*)(d + 8));
@@ -306,7 +306,7 @@ namespace Glitter {
}
}
else {
if (st->header.use_big_endian) {
if (st->header.attrib.get_big_endian()) {
c->type = (CurveType)load_reverse_endianness_uint32_t((void*)d);
c->repeat = load_reverse_endianness_uint32_t((void*)(d + 4)) != 0;
c->flags = (CurveFlag)load_reverse_endianness_uint32_t((void*)(d + 8));
@@ -327,7 +327,7 @@ namespace Glitter {
}
}
else {
if (st->header.use_big_endian) {
if (st->header.attrib.get_big_endian()) {
c->type = (CurveType)load_reverse_endianness_uint32_t((void*)d);
c->repeat = load_reverse_endianness_uint32_t((void*)(d + 4)) != 0;
c->flags = (CurveFlag)load_reverse_endianness_uint32_t((void*)(d + 8));
@@ -357,16 +357,16 @@ namespace Glitter {
}
for (f2_struct& i : st->sub_structs)
if (i.header.data_size && i.header.signature == reverse_endianness_uint32_t('KEYS')) {
if (i.header.get_raw_data_size() && i.header.signature == reverse_endianness_uint32_t('KEYS')) {
UnpackCurve(i.data.data(), anim, c,
keys_count, i.header.version, i.header.use_big_endian);
keys_count, i.header.version, i.header.attrib.get_big_endian());
break;
}
anim->curves.push_back(c);
}
bool FileReader::ParseDivaEffect(GPM, f2_struct* st) {
if (!st || !st->header.data_size
if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('DVEF'))
return false;
@@ -416,7 +416,7 @@ namespace Glitter {
}
bool FileReader::ParseDivaList(f2_struct* st, EffectGroup* eff_group) {
if (!st || !st->header.data_size
if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('LIST'))
return false;
@@ -427,7 +427,7 @@ namespace Glitter {
}
bool FileReader::ParseDivaResource(GPM, f2_struct* st, EffectGroup* eff_group) {
if (!st || !st->header.data_size)
if (!st || !st->header.get_raw_data_size())
return false;
for (f2_struct& i : st->sub_structs)
@@ -437,13 +437,13 @@ namespace Glitter {
}
bool FileReader::ParseEffect(f2_struct* st, EffectGroup* eff_group) {
if (!st || !st->header.data_size
if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('EFCT'))
return false;
Effect* eff = new Effect(type);
if (!UnpackEffect(st->data.data(), eff,
st->header.version, st->header.use_big_endian)) {
st->header.version, st->header.attrib.get_big_endian())) {
delete eff;
return false;
}
@@ -457,12 +457,12 @@ namespace Glitter {
}
bool FileReader::ParseEffectGroup(f2_struct* st, std::vector<Effect*>* vec, EffectGroup* eff_group) {
if (!st || !st->header.data_size
if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('DVEF'))
return false;
for (f2_struct& i : st->sub_structs) {
if (!i.header.data_size)
if (!i.header.get_raw_data_size())
continue;
if (i.header.signature == reverse_endianness_uint32_t('EFCT')) {
@@ -477,12 +477,12 @@ namespace Glitter {
}
bool FileReader::ParseEmitter(f2_struct* st, Effect* eff, EffectGroup* eff_group) {
if (!st || !st->header.data_size || st->header.signature != reverse_endianness_uint32_t('EMIT'))
if (!st || !st->header.get_raw_data_size() || st->header.signature != reverse_endianness_uint32_t('EMIT'))
return false;
Emitter* emit = new Emitter(type);
if (!UnpackEmitter(st->data.data(), emit,
st->header.version, st->header.use_big_endian)) {
st->header.version, st->header.attrib.get_big_endian())) {
delete emit;
return false;
}
@@ -496,12 +496,12 @@ namespace Glitter {
}
bool FileReader::ParseParticle(f2_struct* st, Emitter* emit, Effect* eff, EffectGroup* eff_group) {
if (!st || !st->header.data_size || st->header.signature != reverse_endianness_uint32_t('PTCL'))
if (!st || !st->header.get_raw_data_size() || st->header.signature != reverse_endianness_uint32_t('PTCL'))
return false;
Particle* ptcl = new Particle(type);
if (!UnpackParticle(st->data.data(), ptcl,
st->header.version, eff, st->header.use_big_endian, eff_group)) {
st->header.version, eff, st->header.attrib.get_big_endian(), eff_group)) {
delete ptcl;
return false;
}
@@ -958,13 +958,13 @@ namespace Glitter {
}
bool FileReader::UnpackDivaList(f2_struct* st, EffectGroup* eff_group) {
if (!st || !st->header.data_size
if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('GEFF'))
return false;
size_t d = (size_t)st->data.data();
uint32_t length;
if (st->header.use_big_endian)
if (st->header.attrib.get_big_endian())
length = load_reverse_endianness_uint32_t((void*)d);
else
length = *(uint32_t*)d;
@@ -993,11 +993,11 @@ namespace Glitter {
}
bool FileReader::UnpackDivaResource(GPM, f2_struct* st, EffectGroup* eff_group) {
if (!st || !st->header.data_size
if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('TXPC'))
return false;
eff_group->resources_tex.unpack_file(st->data.data(), st->header.use_big_endian);
eff_group->resources_tex.unpack_file(st->data.data(), st->header.attrib.get_big_endian());
if (!eff_group->resources_count)
return false;
@@ -1051,7 +1051,7 @@ namespace Glitter {
bool FileReader::UnpackDivaResourceHashes(f2_struct* st, EffectGroup* eff_group) {
if (eff_group->resources_count && eff_group->resource_hashes.size() > 0)
return true;
else if (!st || !st->header.data_size
else if (!st || !st->header.get_raw_data_size()
|| st->header.signature != reverse_endianness_uint32_t('DVRS'))
return false;
@@ -1060,7 +1060,7 @@ namespace Glitter {
return false;
uint32_t count;
if (st->header.use_big_endian)
if (st->header.attrib.get_big_endian())
count = load_reverse_endianness_uint32_t((void*)d);
else
count = *(int32_t*)d;
@@ -1073,7 +1073,7 @@ namespace Glitter {
if (!resource_hashes)
return false;
if (st->header.use_big_endian)
if (st->header.attrib.get_big_endian())
for (size_t i = count; i; i--, resource_hashes++, d += sizeof(uint64_t))
*resource_hashes = load_reverse_endianness_uint64_t((void*)d);
else
+35 -66
View File
@@ -86,10 +86,7 @@ namespace Glitter {
void FileWriter::PackCurve(f2_struct* st, Curve* c, bool big_endian) {
if (!c->keys.size()) {
st->header.signature = reverse_endianness_uint32_t('KEYS');
st->header.length = 0x20;
st->header.use_big_endian = false;
st->header.use_section_size = true;
new (&st->header) f2_header('KEYS');
st->header.version = c->keys_version;
return;
}
@@ -449,10 +446,8 @@ namespace Glitter {
st->enrs = e;
st->header.signature = reverse_endianness_uint32_t('KEYS');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('KEYS');
st->header.attrib.set_big_endian(big_endian);
st->header.version = c->keys_version;
}
@@ -491,10 +486,8 @@ namespace Glitter {
st->enrs = e;
st->header.signature = reverse_endianness_uint32_t('GEFF');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('GEFF');
st->header.attrib.set_big_endian(big_endian);
return true;
}
@@ -507,10 +500,7 @@ namespace Glitter {
eff_group->resources_tex.pack_file(st->data, false);
st->header.signature = reverse_endianness_uint32_t('TXPC');
st->header.length = 0x20;
st->header.use_big_endian = false;
st->header.use_section_size = true;
new (&st->header) f2_header('TXPC');
return true;
}
@@ -554,10 +544,8 @@ namespace Glitter {
st->enrs = e;
st->header.signature = reverse_endianness_uint32_t('DVRS');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('DVRS');
st->header.attrib.set_big_endian(big_endian);
return true;
}
@@ -956,10 +944,8 @@ namespace Glitter {
st->enrs = e;
st->header.signature = reverse_endianness_uint32_t('EFCT');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('EFCT');
st->header.attrib.set_big_endian(big_endian);
st->header.version = eff->version;
return true;
}
@@ -1302,10 +1288,8 @@ namespace Glitter {
st->enrs = e;
st->header.signature = reverse_endianness_uint32_t('EMIT');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('EMIT');
st->header.attrib.set_big_endian(big_endian);
st->header.version = emit->version;
return true;
}
@@ -1817,10 +1801,8 @@ namespace Glitter {
st->enrs = e;
st->header.signature = reverse_endianness_uint32_t('PTCL');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('PTCL');
st->header.attrib.set_big_endian(big_endian);
st->header.version = ptcl->version;
return true;
}
@@ -1882,10 +1864,8 @@ namespace Glitter {
if (st->sub_structs.size() < 1)
return false;
st->header.signature = reverse_endianness_uint32_t('ANIM');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('ANIM');
st->header.attrib.set_big_endian(big_endian);
return true;
}
@@ -1924,7 +1904,7 @@ namespace Glitter {
st->data.resize(l);
d = (size_t)st->data.data();
if (st->header.use_big_endian) {
if (big_endian) {
store_reverse_endianness_uint32_t((void*)d, c->type);
store_reverse_endianness_uint32_t((void*)(d + 4), c->repeat ? 1 : 0);
store_reverse_endianness_uint32_t((void*)(d + 8), c->flags);
@@ -1954,7 +1934,7 @@ namespace Glitter {
st->data.resize(l);
d = (size_t)st->data.data();
if (st->header.use_big_endian) {
if (big_endian) {
store_reverse_endianness_uint32_t((void*)d, c->type);
store_reverse_endianness_uint32_t((void*)(d + 4), c->repeat ? 1 : 0);
store_reverse_endianness_uint32_t((void*)(d + 8), c->flags);
@@ -2026,10 +2006,8 @@ namespace Glitter {
st->enrs = e;
st->header.signature = reverse_endianness_uint32_t('CURV');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('CURV');
st->header.attrib.set_big_endian(big_endian);
st->header.version = c->version;
f2_struct s;
@@ -2044,10 +2022,7 @@ namespace Glitter {
bool FileWriter::UnparseDivaEffect(EffectGroup* eff_group, f2_struct* st, bool big_endian) {
UnparseEffectGroup(eff_group, st, big_endian);
st->header.signature = reverse_endianness_uint32_t('DVEF');
st->header.length = 0x20;
st->header.use_big_endian = false;
st->header.use_section_size = true;
new (&st->header) f2_header('DVEF');
st->header.version = eff_group->version;
return true;
}
@@ -2059,10 +2034,8 @@ namespace Glitter {
st->sub_structs.push_back(s);
st->header.signature = reverse_endianness_uint32_t('LIST');
st->header.length = 0x20;
st->header.use_big_endian = big_endian;
st->header.use_section_size = true;
new (&st->header) f2_header('LIST');
st->header.attrib.set_big_endian(big_endian);
return true;
}
@@ -2073,10 +2046,7 @@ namespace Glitter {
st->sub_structs.push_back(s);
st->header.signature = reverse_endianness_uint32_t('DVRS');
st->header.length = 0x20;
st->header.use_big_endian = false;
st->header.use_section_size = true;
new (&st->header) f2_header('DVRS');
st->header.version = 1;
return true;
}
@@ -2177,6 +2147,17 @@ namespace Glitter {
memcpy(temp, file, file_len);
temp[file_len] = 0;
{
f2_struct drs_st;
if (fr.UnparseDivaResource(eff_group, &drs_st)) {
memcpy(&temp[file_len], ".drs", 4);
temp[file_len + 4] = 0;
farc_file* ff_drs = f.add_file(temp);
drs_st.write(&ff_drs->data, &ff_drs->size);
ff_drs->compressed = compress;
ff_drs->encrypted = encrypt;
}
}
{
f2_struct dve_st;
@@ -2194,18 +2175,6 @@ namespace Glitter {
}
}
{
f2_struct drs_st;
if (fr.UnparseDivaResource(eff_group, &drs_st)) {
memcpy(&temp[file_len], ".drs", 4);
temp[file_len + 4] = 0;
farc_file* ff_drs = f.add_file(temp);
drs_st.write(&ff_drs->data, &ff_drs->size);
ff_drs->compressed = compress;
ff_drs->encrypted = encrypt;
}
}
if (fr.type == Glitter::FT || save_lst) {
f2_struct lst_st;
if (fr.UnparseDivaList(eff_group, &lst_st, big_endian)) {
+1 -4
View File
@@ -547,10 +547,7 @@ static void a3da_write_inner(a3da* a, stream& s) {
s_a3da.copy(st.data);
s_a3da.close();
st.header.signature = reverse_endianness_uint32_t('A3DA');
st.header.length = 0x40;
st.header.use_big_endian = false;
st.header.use_section_size = true;
new (&st.header) f2_header('A3DA');
st.header.inner_signature = a->format == A3DA_FORMAT_XHD ? 0x00131010 : 0x01131010;
st.write(s, true, a->format == A3DA_FORMAT_X || a->format == A3DA_FORMAT_XHD);
+4 -6
View File
@@ -904,8 +904,8 @@ static void aet_set_modern_read_inner(aet_set* as, prj::shared_ptr<prj::stack_al
if (st.header.signature != reverse_endianness_uint32_t('AETC') || !st.data.size())
return;
uint32_t header_length = st.header.length;
bool big_endian = st.header.use_big_endian;
uint32_t header_length = st.header.get_length();
bool big_endian = st.header.attrib.get_big_endian();
bool is_x = st.pof.shift_x;
memory_stream s_aetc;
@@ -978,10 +978,8 @@ static void aet_set_modern_write_inner(aet_set* as, stream& s) {
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('AETC');
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('AETC');
st.header.attrib.set_big_endian(big_endian);
st.write(s, true, is_x);
}
+8 -10
View File
@@ -96,8 +96,8 @@ void aet_database_file::read(const char* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('AEDB')) {
memory_stream s_aedb;
s_aedb.open(st.data);
s_aedb.big_endian = st.header.use_big_endian;
aet_database_file_modern_read_inner(this, s_aedb, st.header.length);
s_aedb.big_endian = st.header.attrib.get_big_endian();
aet_database_file_modern_read_inner(this, s_aedb, st.header.get_length());
}
}
free_def(path_aei);
@@ -132,8 +132,8 @@ void aet_database_file::read(const wchar_t* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('AEDB')) {
memory_stream s_aedb;
s_aedb.open(st.data);
s_aedb.big_endian = st.header.use_big_endian;
aet_database_file_modern_read_inner(this, s_aedb, st.header.length);
s_aedb.big_endian = st.header.attrib.get_big_endian();
aet_database_file_modern_read_inner(this, s_aedb, st.header.get_length());
}
}
free_def(path_aei);
@@ -155,8 +155,8 @@ void aet_database_file::read(const void* data, size_t size, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('AEDB')) {
memory_stream s_aedb;
s_aedb.open(st.data);
s_aedb.big_endian = st.header.use_big_endian;
aet_database_file_modern_read_inner(this, s_aedb, st.header.length);
s_aedb.big_endian = st.header.attrib.get_big_endian();
aet_database_file_modern_read_inner(this, s_aedb, st.header.get_length());
}
}
}
@@ -869,10 +869,8 @@ static void aet_database_file_modern_write_inner(aet_database_file* aet_db, stre
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('AEDB');
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('AEDB');
st.header.attrib.set_big_endian(big_endian);
st.write(s, true, aet_db->is_x);
}
+9 -10
View File
@@ -82,8 +82,8 @@ void bone_database::read(const char* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('BONE')) {
memory_stream s_bone;
s_bone.open(st.data);
s_bone.big_endian = st.header.use_big_endian;
bone_database_modern_read_inner(this, s_bone, st.header.length);
s_bone.big_endian = st.header.attrib.get_big_endian();
bone_database_modern_read_inner(this, s_bone, st.header.get_length());
}
}
free_def(path_bon);
@@ -118,8 +118,8 @@ void bone_database::read(const wchar_t* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('BONE')) {
memory_stream s_bone;
s_bone.open(st.data);
s_bone.big_endian = st.header.use_big_endian;
bone_database_modern_read_inner(this, s_bone, st.header.length);
s_bone.big_endian = st.header.attrib.get_big_endian();
bone_database_modern_read_inner(this, s_bone, st.header.get_length());
}
}
free_def(path_bon);
@@ -141,8 +141,8 @@ void bone_database::read(const void* data, size_t size, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('BONE')) {
memory_stream s_bone;
s_bone.open(st.data);
s_bone.big_endian = st.header.use_big_endian;
bone_database_modern_read_inner(this, s_bone, st.header.length);
s_bone.big_endian = st.header.attrib.get_big_endian();
bone_database_modern_read_inner(this, s_bone, st.header.get_length());
}
}
}
@@ -1418,10 +1418,9 @@ static void bone_database_modern_write_inner(bone_database* bone_data, stream& s
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('BONE');
st.header.length = is_x ? 0x20 : 0x40;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('BONE');
st.header.set_length(is_x ? F2_HEADER_DEFAULT_LENGTH : F2_HEADER_EXTENDED_LENGTH);
st.header.attrib.set_big_endian(big_endian);
st.write(s, true, is_x);
}
+8 -10
View File
@@ -89,8 +89,8 @@ void object_database_file::read(const char* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('MOSI')) {
memory_stream s_mosi;
s_mosi.open(st.data);
s_mosi.big_endian = st.header.use_big_endian;
object_database_file_modern_read_inner(this, s_mosi, st.header.length);
s_mosi.big_endian = st.header.attrib.get_big_endian();
object_database_file_modern_read_inner(this, s_mosi, st.header.get_length());
}
}
free_def(path_osi);
@@ -125,8 +125,8 @@ void object_database_file::read(const wchar_t* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('MOSI')) {
memory_stream s_mosi;
s_mosi.open(st.data);
s_mosi.big_endian = st.header.use_big_endian;
object_database_file_modern_read_inner(this, s_mosi, st.header.length);
s_mosi.big_endian = st.header.attrib.get_big_endian();
object_database_file_modern_read_inner(this, s_mosi, st.header.get_length());
}
}
free_def(path_osi);
@@ -148,8 +148,8 @@ void object_database_file::read(const void* data, size_t size, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('MOSI')) {
memory_stream s_mosi;
s_mosi.open(st.data);
s_mosi.big_endian = st.header.use_big_endian;
object_database_file_modern_read_inner(this, s_mosi, st.header.length);
s_mosi.big_endian = st.header.attrib.get_big_endian();
object_database_file_modern_read_inner(this, s_mosi, st.header.get_length());
}
}
}
@@ -933,10 +933,8 @@ static void object_database_file_modern_write_inner(object_database_file* obj_db
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('MOSI');
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('MOSI');
st.header.attrib.set_big_endian(big_endian);
st.write(s, true, is_x);
}
+8 -10
View File
@@ -93,8 +93,8 @@ void sprite_database_file::read(const char* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('SPDB')) {
memory_stream s_spdb;
s_spdb.open(st.data);
s_spdb.big_endian = st.header.use_big_endian;
sprite_database_file_modern_read_inner(this, s_spdb, st.header.length);
s_spdb.big_endian = st.header.attrib.get_big_endian();
sprite_database_file_modern_read_inner(this, s_spdb, st.header.get_length());
}
}
free_def(path_spi);
@@ -129,8 +129,8 @@ void sprite_database_file::read(const wchar_t* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('SPDB')) {
memory_stream s_spdb;
s_spdb.open(st.data);
s_spdb.big_endian = st.header.use_big_endian;
sprite_database_file_modern_read_inner(this, s_spdb, st.header.length);
s_spdb.big_endian = st.header.attrib.get_big_endian();
sprite_database_file_modern_read_inner(this, s_spdb, st.header.get_length());
}
}
free_def(path_spi);
@@ -152,8 +152,8 @@ void sprite_database_file::read(const void* data, size_t size, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('SPDB')) {
memory_stream s_spdb;
s_spdb.open(st.data);
s_spdb.big_endian = st.header.use_big_endian;
sprite_database_file_modern_read_inner(this, s_spdb, st.header.length);
s_spdb.big_endian = st.header.attrib.get_big_endian();
sprite_database_file_modern_read_inner(this, s_spdb, st.header.get_length());
}
}
}
@@ -931,10 +931,8 @@ static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('SPDB');
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('SPDB');
st.header.attrib.set_big_endian(big_endian);
st.write(s, true, spr_db->is_x);
}
+6 -6
View File
@@ -118,8 +118,8 @@ void stage_database_file::read(const char* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('STGC')) {
memory_stream s_stgc;
s_stgc.open(st.data);
s_stgc.big_endian = st.header.use_big_endian;
stage_database_file_modern_read_inner(this, s_stgc, st.header.length);
s_stgc.big_endian = st.header.attrib.get_big_endian();
stage_database_file_modern_read_inner(this, s_stgc, st.header.get_length());
}
}
free_def(path_stg);
@@ -154,8 +154,8 @@ void stage_database_file::read(const wchar_t* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('STGC')) {
memory_stream s_stgc;
s_stgc.open(st.data);
s_stgc.big_endian = st.header.use_big_endian;
stage_database_file_modern_read_inner(this, s_stgc, st.header.length);
s_stgc.big_endian = st.header.attrib.get_big_endian();
stage_database_file_modern_read_inner(this, s_stgc, st.header.get_length());
}
}
free_def(path_stg);
@@ -177,8 +177,8 @@ void stage_database_file::read(const void* data, size_t size, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('STGC')) {
memory_stream s_stgc;
s_stgc.open(st.data);
s_stgc.big_endian = st.header.use_big_endian;
stage_database_file_modern_read_inner(this, s_stgc, st.header.length);
s_stgc.big_endian = st.header.attrib.get_big_endian();
stage_database_file_modern_read_inner(this, s_stgc, st.header.get_length());
}
}
}
+8 -10
View File
@@ -73,8 +73,8 @@ void texture_database_file::read(const char* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('MTXI')) {
memory_stream s_mtxi;
s_mtxi.open(st.data);
s_mtxi.big_endian = st.header.use_big_endian;
texture_database_file_modern_read_inner(this, s_mtxi, st.header.length);
s_mtxi.big_endian = st.header.attrib.get_big_endian();
texture_database_file_modern_read_inner(this, s_mtxi, st.header.get_length());
}
}
free_def(path_txi);
@@ -109,8 +109,8 @@ void texture_database_file::read(const wchar_t* path, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('MTXI')) {
memory_stream s_mtxi;
s_mtxi.open(st.data);
s_mtxi.big_endian = st.header.use_big_endian;
texture_database_file_modern_read_inner(this, s_mtxi, st.header.length);
s_mtxi.big_endian = st.header.attrib.get_big_endian();
texture_database_file_modern_read_inner(this, s_mtxi, st.header.get_length());
}
}
free_def(path_txi);
@@ -132,8 +132,8 @@ void texture_database_file::read(const void* data, size_t size, bool modern) {
if (st.header.signature == reverse_endianness_uint32_t('MTXI')) {
memory_stream s_mtxi;
s_mtxi.open(st.data);
s_mtxi.big_endian = st.header.use_big_endian;
texture_database_file_modern_read_inner(this, s_mtxi, st.header.length);
s_mtxi.big_endian = st.header.attrib.get_big_endian();
texture_database_file_modern_read_inner(this, s_mtxi, st.header.get_length());
}
}
}
@@ -488,10 +488,8 @@ static void texture_database_file_modern_write_inner(texture_database_file* tex_
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('MTXI');
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('MTXI');
st.header.attrib.set_big_endian(big_endian);
st.write(s, true, tex_db->is_x);
}
+3 -4
View File
@@ -3042,7 +3042,7 @@ bool dsc::parse(const void* data, size_t size, dsc_type type) {
case DSC_VRFL:
st.read(data, size);
data_dsc = (int32_t*)st.data.data();
if (st.header.use_big_endian)
if (st.header.attrib.get_big_endian())
for (size_t i = size / 4; i; i--, data_dsc++)
*data_dsc = load_reverse_endianness_uint32_t(data_dsc);
@@ -3248,9 +3248,8 @@ void dsc::unparse(void** data, size_t* size) {
st.enrs = e;
st.header.signature = reverse_endianness_uint32_t('PVSC');
st.header.length = 0x40;
st.header.use_section_size = true;
new (&st.header) f2_header('PVSC');
st.header.set_length(F2_HEADER_EXTENDED_LENGTH);
st.header.inner_signature = 0x13120420;
st.write(data, size, true, false);
}
+198 -17
View File
@@ -5,33 +5,214 @@
#include "header.hpp"
void f2_header_read(stream& s, f2_header* h) {
memset(h, 0, sizeof(f2_header));
static uint8_t calc_crc8(uint8_t* data, uint32_t size, uint8_t seed = 0xFF);
static uint16_t calc_crc16_ccitt(uint8_t* data, uint32_t size, uint16_t seed = 0xFFFF);
f2_header::f2_header() : signature(), data_size(), length(), attrib(), depth(), crc8(), crc16(),
section_size(), version(), custom(), murmurhash(), unknown1(), inner_signature(), unknown2() {
signature = ' ';
set_length(F2_HEADER_DEFAULT_LENGTH);
attrib.set_type(0x01);
}
f2_header::f2_header(uint32_t signature, uint32_t size, uint32_t depth, bool align) : f2_header() {
this->signature = reverse_endianness_uint32_t(signature);
set_length(F2_HEADER_DEFAULT_LENGTH);
set_section_size(size, align);
set_data_size(size, align);
attrib.m.unk0 = 0x00;
attrib.set_align(align);
attrib.set_big_endian(false);
this->depth = (uint8_t)depth;
version &= 0xFFF0FFFF;
}
void f2_header::apply_xor() {
if (attrib.get_xor_data() > 0x01)
return;
if (attrib.get_xor_data()) {
remove_xor();
apply_xor();
return;
}
uint8_t* data = get_section_data();
uint8_t* data_end = data + get_section_size();
uint8_t* iv_begin = (uint8_t*)this;
uint8_t* iv = iv_begin;
uint8_t xor_val = 0xA5;
while (iv != iv_begin + 0x08)
xor_val ^= *iv++;
if (!xor_val || xor_val == 0xFF)
xor_val = 0x01;
while (data != data_end) {
xor_val ^= *data;
*data++ = xor_val;
}
attrib.set_xor_data(0x02);
}
void f2_header::calc_crc() {
attrib.set_crc(true);
uint8_t crc8 = calc_crc8((uint8_t*)&section_size, 0x0C, calc_crc8((uint8_t*)this, 0x11));
if (attrib.get_type())
this->crc8 = crc8;
else
abort();
uint16_t crc16 = calc_crc16();
if (attrib.get_type())
this->crc16 = crc16;
else
abort();
}
uint16_t f2_header::calc_crc16() const {
uint16_t hash = calc_crc16_ccitt((uint8_t*)this + F2_HEADER_DEFAULT_LENGTH,
get_length() - F2_HEADER_DEFAULT_LENGTH);
return calc_crc16_ccitt(get_section_data(), get_section_size(), hash);
}
void f2_header::read(stream& s) {
*this = {};
if (s.check_null())
return;
s.read(h, 0x20);
if (h->length == 0x40)
s.read((uint8_t*)h + 0x20, 0x20);
s.read(this, F2_HEADER_DEFAULT_LENGTH);
if (get_length() > F2_HEADER_DEFAULT_LENGTH)
s.read((uint8_t*)this + F2_HEADER_DEFAULT_LENGTH,
min_def(get_length(), F2_HEADER_EXTENDED_LENGTH) - F2_HEADER_DEFAULT_LENGTH);
}
void f2_header_write(stream& s, f2_header* h, bool extended) {
void f2_header::remove_xor() {
if (attrib.get_xor_data() > 0x01) {
if (attrib.get_xor_data() != 0x03) {
uint8_t* data = get_section_data();
uint8_t* data_end = data + get_section_size();
uint8_t* iv_begin = (uint8_t*)this;
uint8_t* iv = iv_begin;
uint8_t xor_val = 0xA5;
while (iv != iv_begin + 0x08)
xor_val ^= *iv++;
if (!xor_val || xor_val == 0xFF)
xor_val = 0x01;
while (data != data_end) {
uint8_t temp = *data;
*data++ ^= xor_val;
xor_val = temp;
}
attrib.set_xor_data(0x00);
}
}
else {
if (attrib.get_xor_data() != 0x00) {
uint8_t* data = get_section_data();
uint8_t* data_end = data + min_def(0x200U, get_section_size());
uint8_t* iv_begin = (uint8_t*)this;
uint8_t* iv = iv_begin;
uint8_t xor_val = 0xA5;
while (iv != iv_begin + 0x08)
xor_val ^= *iv++;
if (!xor_val || xor_val == 0xFF)
xor_val = 0x01;
while (data != data_end) {
uint8_t temp = *data;
*data++ ^= xor_val;
xor_val = temp;
}
attrib.set_xor_data(0x00);
}
}
}
bool f2_header::validate_crc(int32_t not_ignore_crc) {
if (!not_ignore_crc && !attrib.get_crc())
return true;
uint8_t crc8;
if (attrib.get_type())
crc8 = this->crc8;
else {
abort();
crc8 = 0xDE;
}
if (crc8 == calc_crc8((uint8_t*)&this->section_size, 0x0C, calc_crc8((uint8_t*)this, 0x11))) {
uint16_t crc16;
if (attrib.get_type())
crc16 = this->crc16;
else {
abort();
crc16 = 0xDEAD;
}
if (crc16 == calc_crc16())
return true;
}
return false;
}
void f2_header::write(stream& s) {
if (s.check_null())
return;
h->length = extended ? 0x40 : 0x20;
s.write(h, h->length);
s.write(this, get_length());
}
void f2_header_write_end_of_container(stream& s, uint32_t depth) {
if (s.check_null())
return;
// CRC8 Polynomial 0x8D
// 0x813495E0 in PCSB01007
static uint8_t calc_crc8(uint8_t* data, uint32_t size, uint8_t seed) {
static const uint8_t crc8_table_small[] = {
0x00, 0x8D, 0x97, 0x1A, 0xA3, 0x2E, 0x34, 0xB9,
0xCB, 0x46, 0x5C, 0xD1, 0x68, 0xE5, 0xFF, 0x72,
};
f2_header h = {};
h.signature = reverse_endianness_uint32_t('EOFC');
h.length = 0x20;
h.depth = depth;
h.use_section_size = true;
f2_header_write(s, &h, false);
uint8_t crc = seed;
uint8_t* data_end = data + size;
while (data != data_end) {
crc ^= *data++;
crc = crc8_table_small[crc >> 0x04] ^ (crc << 0x04);
crc = crc8_table_small[crc >> 0x04] ^ (crc << 0x04);
}
return crc;
}
// CRC16-CCITT
// 0x81349476 in PCSB01007
static uint16_t calc_crc16_ccitt(uint8_t* data, uint32_t size, uint16_t seed) {
static const uint16_t crc16_ccitt_table_small[] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
};
uint16_t crc = seed;
uint8_t* data_end = data + size;
while (data != data_end) {
crc ^= (uint16_t)*data++ << 0x08;
crc = crc16_ccitt_table_small[crc >> 0x0C] ^ (crc << 0x04);
crc = crc16_ccitt_table_small[crc >> 0x0C] ^ (crc << 0x04);
}
return crc;
}
+162 -15
View File
@@ -8,32 +8,179 @@
#include "../default.hpp"
#include "../io/stream.hpp"
#define F2_HEADER_BASE_ALIGNMENT (0x10U)
#define F2_HEADER_DEFAULT_LENGTH (0x20U)
#define F2_HEADER_EXTENDED_LENGTH (0x40U)
struct f2_header_attrib_member {
friend struct f2_header;
friend union f2_header_attrib;
private:
uint32_t unk0 : 3;
uint32_t align : 1;
uint32_t unk1 : 5;
uint32_t aes : 1;
uint32_t gzip : 1;
uint32_t unk2 : 6;
uint32_t xor_data : 2;
uint32_t crc : 1;
uint32_t unk3 : 7;
uint32_t big_endian : 1;
uint32_t type : 4;
};
union f2_header_attrib {
f2_header_attrib_member m;
uint32_t w;
inline bool get_aes() const {
return !!m.aes;
}
inline bool get_align() const {
return !!m.align;
}
inline bool get_big_endian() const {
return !!m.big_endian;
}
inline bool get_crc() const {
return !!m.crc;
}
inline bool get_gzip() const {
return !!m.gzip;
}
inline uint32_t get_type() const {
return m.type;
}
inline uint32_t get_xor_data() const {
return m.xor_data;
}
inline void set_aes(bool value) {
m.aes = value ? 0x01 : 0x00;
}
inline void set_align(bool value) {
m.align = value ? 0x01 : 0x00;
}
inline void set_big_endian(bool value) {
m.big_endian = value ? 0x01 : 0x00;
}
inline void set_crc(bool value) {
m.crc = value ? 0x01 : 0x00;
}
inline void set_gzip(bool value) {
m.gzip = value ? 0x01 : 0x00;
}
inline void set_type(uint32_t value) {
m.type = value;
}
inline void set_xor_data(uint32_t value) {
m.xor_data = value;
}
};
struct f2_header {
union {
char signature_char[0x04]; // 0x00
uint32_t signature; // 0x00
};
private:
uint32_t data_size; // 0x04
uint32_t length; // 0x08
union { // 0x0C
struct {
uint32_t flags0 : 27;
uint32_t use_big_endian : 1;
uint32_t use_section_size : 1;
uint32_t flags1 : 3;
};
uint32_t flags;
};
uint32_t depth; // 0x10
public:
f2_header_attrib attrib; // 0x0C
uint8_t depth; // 0x10
uint8_t crc8; // 0x11
uint16_t crc16; // 0x12
private:
uint32_t section_size; // 0x14
public:
uint32_t version; // 0x18
uint32_t unknown0; // 0x1C
uint32_t custom; // 0x1C
uint32_t murmurhash; // 0x20
uint32_t unknown1[3]; // 0x24
uint32_t inner_signature; // 0x30
uint32_t unknown2[3]; // 0x34
};
extern void f2_header_read(stream& s, f2_header* h);
extern void f2_header_write(stream& s, f2_header* h, bool extended);
extern void f2_header_write_end_of_container(stream& s, uint32_t depth);
f2_header();
f2_header(uint32_t signature, uint32_t size = 0, uint32_t depth = 0, bool align = false);
void apply_xor();
void calc_crc();
uint16_t calc_crc16() const;
void read(stream& s);
void remove_xor();
bool validate_crc(int32_t not_ignore_crc = 0);
void write(stream& s);
inline uint32_t get_data_size() const {
if (attrib.get_type() < 0x02)
return data_size;
else
return F2_HEADER_BASE_ALIGNMENT * data_size;
}
inline uint32_t get_length() const {
if (attrib.get_type() < 0x02)
return length;
else
return F2_HEADER_BASE_ALIGNMENT * length;
}
inline uint32_t get_raw_data_size() const {
return data_size;
}
inline uint8_t* get_section_data() const {
if (get_section_size())
return (uint8_t*)this + get_length();
return 0;
}
inline uint32_t get_section_size() const {
if (!attrib.get_type())
return data_size;
else if (attrib.get_type() == 0x01)
return section_size;
else
return F2_HEADER_BASE_ALIGNMENT * section_size;
}
inline void set_data_size(uint32_t value, bool align = false) {
if (attrib.get_type() < 0x02)
data_size = value;
else if (!(value & 0x0F) || !align)
data_size = value / F2_HEADER_BASE_ALIGNMENT;
else
abort();
}
inline void set_length(uint32_t value) {
if (attrib.get_type() < 0x02)
length = value;
else
length = value / F2_HEADER_BASE_ALIGNMENT;
}
inline void set_section_size(uint32_t value, bool align = false) {
if (attrib.get_type()) {
if (attrib.get_type() < 0x02)
section_size = value;
else if (!(section_size & 0x0F) || !align)
section_size = value / F2_HEADER_BASE_ALIGNMENT;
else
abort();
}
}
};
+39 -52
View File
@@ -15,7 +15,7 @@ static void f2_struct_get_length(f2_struct* s, bool shift_x);
static void f2_struct_write_pof(stream& s, pof* pof, uint32_t depth, bool shift_x);
static void f2_struct_write_enrs(stream& s, enrs* enrs, uint32_t depth);
f2_struct::f2_struct() : header() {
f2_struct::f2_struct() {
}
@@ -34,7 +34,7 @@ void f2_struct::read(const char* path) {
divafile::decrypt(s, ms);
f2_header h;
f2_header_read(ms, &h);
h.read(ms);
f2_struct_read_data(ms, this, &h);
}
}
@@ -50,7 +50,7 @@ void f2_struct::read(const wchar_t* path) {
divafile::decrypt(s, ms);
f2_header h;
f2_header_read(ms, &h);
h.read(ms);
f2_struct_read_data(ms, this, &h);
}
}
@@ -66,7 +66,7 @@ void f2_struct::read(const void* data, size_t size) {
divafile::decrypt(s, ms);
f2_header h;
f2_header_read(ms, &h);
h.read(ms);
f2_struct_read_data(ms, this, &h);
}
}
@@ -79,7 +79,7 @@ void f2_struct::read(stream& s) {
divafile::decrypt(s, ms);
f2_header h;
f2_header_read(ms, &h);
h.read(ms);
f2_struct_read_data(ms, this, &h);
}
@@ -113,7 +113,7 @@ void f2_struct::write(void** data, size_t* size, bool use_depth, bool shift_x) {
f2_struct_get_length(this, shift_x);
memory_stream s;
s.open(0, header.data_size + 0x40ULL);
s.open(0, header.get_data_size() + (size_t)F2_HEADER_EXTENDED_LENGTH);
f2_struct_write_inner(s, this, 0, use_depth, shift_x);
s.copy(data, size);
@@ -125,43 +125,41 @@ void f2_struct::write(stream& s, bool use_depth, bool shift_x) {
f2_struct_get_length(this, shift_x);
f2_struct_write_inner(s, this, 0, use_depth, shift_x);
}
static void f2_struct_get_length(f2_struct* s, bool shift_x) {
bool has_pof = s->pof.vec.size() > 0 ? true : false;
bool has_enrs = s->enrs.vec.size() > 0 ? true : false;
bool has_sub_structs = s->sub_structs.size() > 0 ? true : false;
bool has_pof = !!s->pof.vec.size();
bool has_enrs = !!s->enrs.vec.size();
bool has_sub_structs = !!s->sub_structs.size();
s->header.section_size = (uint32_t)s->data.size();
if (!s->header.attrib.get_type() && (has_pof || has_enrs || has_sub_structs))
s->header.attrib.set_type(0x01);
uint32_t l = s->header.section_size;
if (has_enrs) {
uint32_t len = s->enrs.length();
l += 0x20 + align_val(len, 0x10);
}
s->header.set_section_size((uint32_t)s->data.size());
uint32_t l = s->header.get_section_size();
if (has_enrs)
l += F2_HEADER_DEFAULT_LENGTH + align_val(s->enrs.length(), 0x10);
if (has_pof) {
s->pof.shift_x = shift_x;
uint32_t len = s->pof.length();
l += 0x20 + align_val(len, 0x10);
l += F2_HEADER_DEFAULT_LENGTH + align_val(s->pof.length(), 0x10);
}
if (has_sub_structs) {
for (f2_struct& i : s->sub_structs) {
f2_struct_get_length(&i, shift_x);
l += i.header.data_size;
l += i.header.length;
l += i.header.get_data_size();
l += i.header.get_length();
}
l += 0x20;
l += F2_HEADER_DEFAULT_LENGTH;
}
s->header.data_size = l;
s->header.set_data_size(l);
}
static void f2_struct_read_data(stream& s, f2_struct* st, f2_header* h) {
uint32_t l = h->use_section_size ? h->section_size : h->data_size;
uint32_t depth = h->depth;
uint32_t l = h->get_section_size();
st->header = *h;
if (l) {
st->data.resize(l);
@@ -169,13 +167,13 @@ static void f2_struct_read_data(stream& s, f2_struct* st, f2_header* h) {
}
uint32_t sig;
size_t length = (size_t)h->data_size - l;
size_t length = (size_t)h->get_data_size() - l;
size_t position = 0;
while (length > position) {
f2_header_read(s, h);
h->read(s);
sig = reverse_endianness_uint32_t(h->signature);
l = h->use_section_size ? h->section_size : h->data_size;
position += (size_t)h->length + l;
l = h->get_section_size();
position += (size_t)h->get_length() + l;
if (sig == 'EOFC')
break;
else if (sig == 'ENRS') {
@@ -197,12 +195,12 @@ static void f2_struct_read_data(stream& s, f2_struct* st, f2_header* h) {
}
static void f2_struct_write_inner(stream& s, f2_struct* st, uint32_t depth, bool use_depth, bool shift_x) {
bool has_pof = st->pof.vec.size() > 0 ? true : false;
bool has_enrs = st->enrs.vec.size() > 0 ? true : false;
bool has_sub_structs = st->sub_structs.size() > 0 ? true : false;
bool has_pof = !!st->pof.vec.size();
bool has_enrs = !!st->enrs.vec.size();
bool has_sub_structs = !!st->sub_structs.size();
st->header.depth = use_depth ? depth : 0;
f2_header_write(s, &st->header, st->header.length == 0x40);
st->header.depth = use_depth ? (uint8_t)depth : 0;
st->header.write(s);
if (st->data.size())
s.write(st->data.data(), st->data.size());
if (has_enrs)
@@ -212,33 +210,22 @@ static void f2_struct_write_inner(stream& s, f2_struct* st, uint32_t depth, bool
if (has_sub_structs) {
for (f2_struct& i : st->sub_structs)
f2_struct_write_inner(s, &i, depth + 1, use_depth, shift_x);
f2_header_write_end_of_container(s, use_depth ? depth + 1 : 0);
f2_header('EOFC', 0, use_depth ? depth + 1 : 0).write(s);
}
if (!depth) {
f2_header('EOFC', 0).write(s);
}
if (!depth)
f2_header_write_end_of_container(s, 0);
}
static void f2_struct_write_pof(stream& s, pof* pof, uint32_t depth, bool shift_x) {
pof->shift_x = shift_x;
size_t len = pof->length();
f2_header h = {};
h.signature = shift_x ? reverse_endianness_uint32_t('POF1') : reverse_endianness_uint32_t('POF0');
h.length = 0x20;
h.depth = depth;
h.use_section_size = true;
h.data_size = h.section_size = (uint32_t)align_val(len, 0x10);
f2_header_write(s, &h, false);
f2_header(shift_x ? 'POF1' : 'POF0', (uint32_t)align_val(pof->length(), 0x10), depth).write(s);
pof->write(s);
}
static void f2_struct_write_enrs(stream& s, enrs* enrs, uint32_t depth) {
size_t len = enrs->length();
f2_header h = {};
h.signature = reverse_endianness_uint32_t('ENRS');
h.length = 0x20;
h.depth = depth;
h.use_section_size = true;
h.data_size = h.section_size = (uint32_t)align_val(len, 0x10);
f2_header_write(s, &h, false);
f2_header('ENRS', (uint32_t)align_val(enrs->length(), 0x10), depth).write(s);
enrs->write(s);
}
+1 -1
View File
@@ -52,7 +52,7 @@ const uint32_t hash_murmurhash_empty = 0x0CAD3078;
// "NULL" string
const uint32_t hash_murmurhash_null = 0x5A009B23;
// Empty string
const uint32_t hash_crc16_ccitt_empty = 0xFFFF;
const uint16_t hash_crc16_ccitt_empty = 0xFFFF;
// FNV 1a 64-bit Modified
// 0x1403B04D0 in SBZV_7.10
+2 -2
View File
@@ -15,7 +15,7 @@ extern const uint32_t hash_murmurhash_empty;
// "NULL" string
extern const uint32_t hash_murmurhash_null;
// Empty string
extern const uint32_t hash_crc16_ccitt_empty;
extern const uint16_t hash_crc16_ccitt_empty;
extern uint64_t hash_fnv1a64m(const void* data, size_t size, bool make_upper = false);
extern uint32_t hash_murmurhash(const void* data, size_t size,
@@ -60,7 +60,7 @@ inline uint16_t hash_utf8_crc16_ccitt(const char* data, bool make_upper = false)
inline uint16_t hash_utf16_crc16_ccitt(const wchar_t* data, bool make_upper = false) {
char* temp = utf16_to_utf8(data);
uint32_t hash = hash_crc16_ccitt(temp, utf8_length(temp), make_upper);
uint16_t hash = hash_crc16_ccitt(temp, utf8_length(temp), make_upper);
free_def(temp);
return hash;
}
+5 -6
View File
@@ -580,8 +580,8 @@ static void mot_modern_read_inner(mot_set* ms, prj::shared_ptr<prj::stack_alloca
return;
}
uint32_t header_length = st.header.length;
bool big_endian = st.header.use_big_endian;
uint32_t header_length = st.header.get_length();
bool big_endian = st.header.attrib.get_big_endian();
bool is_x = st.pof.shift_x;
memory_stream s_motc;
@@ -997,10 +997,9 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) {
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('MOTC');
st.header.length = 0x40;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('MOTC');
st.header.set_length(F2_HEADER_EXTENDED_LENGTH);
st.header.attrib.set_big_endian(big_endian);
st.header.murmurhash = murmurhash;
st.header.inner_signature = 0xFF010008;
+18 -28
View File
@@ -3898,8 +3898,8 @@ static void obj_set_modern_read_inner(obj_set* set, prj::shared_ptr<prj::stack_a
if (st.header.signature != reverse_endianness_uint32_t('MOSD') || !st.data.size())
return;
uint32_t header_length = st.header.length;
bool big_endian = st.header.use_big_endian;
uint32_t header_length = st.header.get_length();
bool big_endian = st.header.attrib.get_big_endian();
bool is_x = st.pof.shift_x;
memory_stream s_mosd;
@@ -4038,33 +4038,33 @@ static void obj_set_modern_read_inner(obj_set* set, prj::shared_ptr<prj::stack_a
stream* s_ovtx_ptr = 0;
if (oskn) {
s_oskn.open(oskn->data);
s_oskn.big_endian = oskn->header.use_big_endian;
s_oskn.big_endian = oskn->header.attrib.get_big_endian();
s_oskn_ptr = &s_oskn;
}
if (oidx) {
s_oidx.open(oidx->data);
s_oidx.big_endian = oidx->header.use_big_endian;
s_oidx.big_endian = oidx->header.attrib.get_big_endian();
s_oidx_ptr = &s_oidx;
}
if (ovtx) {
s_ovtx.open(ovtx->data);
s_ovtx.big_endian = ovtx->header.use_big_endian;
s_ovtx.big_endian = ovtx->header.attrib.get_big_endian();
s_ovtx_ptr = &s_ovtx;
}
obj* obj = set->obj_data[omdl_index];
memory_stream s_omdl;
s_omdl.open(i.data);
s_omdl.big_endian = i.header.use_big_endian;
s_omdl.big_endian = i.header.attrib.get_big_endian();
obj_modern_read_model(obj, alloc,
s_omdl, 0, i.header.length, is_x, s_oidx_ptr, s_ovtx_ptr);
s_omdl, 0, i.header.get_length(), is_x, s_oidx_ptr, s_ovtx_ptr);
s_omdl.close();
if (s_oskn_ptr)
obj->skin = obj_modern_read_skin(alloc,
*s_oskn_ptr, 0, oskn->header.length, is_x);
*s_oskn_ptr, 0, oskn->header.get_length(), is_x);
omdl_index++;
}
@@ -4284,10 +4284,8 @@ static void obj_set_modern_write_inner(obj_set* set, stream& s) {
s_oskn.copy(oskn->data);
s_oskn.close();
oskn->header.signature = reverse_endianness_uint32_t('OSKN');
oskn->header.length = 0x20;
oskn->header.use_big_endian = big_endian;
oskn->header.use_section_size = true;
new (&oskn->header) f2_header('OSKN');
oskn->header.attrib.set_big_endian(big_endian);
}
obj_modern_write_model(obj, s_omdl, 0, is_x, omdl);
@@ -4296,10 +4294,8 @@ static void obj_set_modern_write_inner(obj_set* set, stream& s) {
s_omdl.copy(omdl->data);
s_omdl.close();
omdl->header.signature = reverse_endianness_uint32_t('OMDL');
omdl->header.length = 0x20;
omdl->header.use_big_endian = big_endian;
omdl->header.use_section_size = true;
new (&omdl->header) f2_header('OMDL');
omdl->header.attrib.set_big_endian(big_endian);
}
s_mosd.align_write(0x10);
@@ -4309,10 +4305,8 @@ static void obj_set_modern_write_inner(obj_set* set, stream& s) {
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('MOSD');
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('MOSD');
st.header.attrib.set_big_endian(big_endian);
st.write(s, true, set->is_x);
}
@@ -4943,19 +4937,15 @@ static void obj_modern_write_model(obj* obj, stream& s,
s_oidx.copy(oidx->data);
s_oidx.close();
oidx->header.signature = reverse_endianness_uint32_t('OIDX');
oidx->header.length = 0x20;
oidx->header.use_big_endian = big_endian;
oidx->header.use_section_size = true;
new (&oidx->header) f2_header('OIDX');
oidx->header.attrib.set_big_endian(big_endian);
s_ovtx.align_write(0x10);
s_ovtx.copy(ovtx->data);
s_ovtx.close();
ovtx->header.signature = reverse_endianness_uint32_t('OVTX');
ovtx->header.length = 0x20;
ovtx->header.use_big_endian = big_endian;
ovtx->header.use_section_size = true;
new (&ovtx->header) f2_header('OVTX');
ovtx->header.attrib.set_big_endian(big_endian);
}
static void obj_modern_read_model_mesh(obj_mesh* mesh,
+9 -10
View File
@@ -33,8 +33,8 @@ void dof::read(const char* path) {
if (st.header.signature == reverse_endianness_uint32_t('DOFT')) {
memory_stream s_doft;
s_doft.open(st.data);
s_doft.big_endian = st.header.use_big_endian;
dof_read_inner(this, s_doft, st.header.length);
s_doft.big_endian = st.header.attrib.get_big_endian();
dof_read_inner(this, s_doft, st.header.get_length());
}
}
free_def(path_dft);
@@ -51,8 +51,8 @@ void dof::read(const wchar_t* path) {
if (st.header.signature == reverse_endianness_uint32_t('DOFT')) {
memory_stream s_doft;
s_doft.open(st.data);
s_doft.big_endian = st.header.use_big_endian;
dof_read_inner(this, s_doft, st.header.length);
s_doft.big_endian = st.header.attrib.get_big_endian();
dof_read_inner(this, s_doft, st.header.get_length());
}
}
free_def(path_dex);
@@ -67,8 +67,8 @@ void dof::read(const void* data, size_t size) {
if (st.header.signature == reverse_endianness_uint32_t('DOFT')) {
memory_stream s_doft;
s_doft.open(st.data);
s_doft.big_endian = st.header.use_big_endian;
dof_read_inner(this, s_doft, st.header.length);
s_doft.big_endian = st.header.attrib.get_big_endian();
dof_read_inner(this, s_doft, st.header.get_length());
}
}
@@ -253,10 +253,9 @@ static void dof_write_inner(dof* d, stream& s) {
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('DOFT');
st.header.length = 0x40;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('DOFT');
st.header.set_length(F2_HEADER_EXTENDED_LENGTH);
st.header.attrib.set_big_endian(big_endian);
st.header.murmurhash = murmurhash;
st.header.inner_signature = 0x03;
+4 -6
View File
@@ -115,8 +115,8 @@ void pv_exp::unpack_file(prj::shared_ptr<prj::stack_allocator> alloc, const void
if (st.header.signature == reverse_endianness_uint32_t('EXPC')) {
memory_stream s_expc;
s_expc.open(st.data);
s_expc.big_endian = st.header.use_big_endian;
pv_exp_modern_read_inner(this, alloc, s_expc, st.header.length);
s_expc.big_endian = st.header.attrib.get_big_endian();
pv_exp_modern_read_inner(this, alloc, s_expc, st.header.get_length());
}
}
}
@@ -530,10 +530,8 @@ static void pv_exp_modern_write_inner(pv_exp* exp, stream& s) {
s_expc.copy(st.data);
s_expc.close();
st.header.signature = reverse_endianness_uint32_t('EXPC');
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('EXPC');
st.header.attrib.set_big_endian(big_endian);
st.write(s, true, exp->is_x);
}
+1 -1
View File
@@ -324,7 +324,7 @@ static void pvpp_read_inner(pvpp* pp, stream& s) {
return;
}
bool big_endian = st.header.use_big_endian;
bool big_endian = st.header.attrib.get_big_endian();
memory_stream s_pvpp;
s_pvpp.open(st.data);
+1 -1
View File
@@ -205,7 +205,7 @@ static void pvsr_read_inner(pvsr* sr, stream& s) {
return;
}
bool big_endian = st.header.use_big_endian;
bool big_endian = st.header.attrib.get_big_endian();
memory_stream s_pvsr;
s_pvsr.open(st.data);
+5 -7
View File
@@ -272,8 +272,8 @@ static void spr_set_modern_read_inner(spr_set* ss,
if (st.header.signature != reverse_endianness_uint32_t('SPRC') || !st.data.size())
return;
uint32_t header_length = st.header.length;
bool big_endian = st.header.use_big_endian;
uint32_t header_length = st.header.get_length();
bool big_endian = st.header.attrib.get_big_endian();
bool is_x = st.pof.shift_x;
memory_stream s_sprc;
@@ -342,7 +342,7 @@ static void spr_set_modern_read_inner(spr_set* ss,
}
s_sprc.close();
texofs = st.header.data_size + 0x20;
texofs = st.header.get_data_size() + F2_HEADER_DEFAULT_LENGTH;
ss->txp = new txp_set;
ss->txp->unpack_file_modern((const void*)((size_t)data + texofs), size - texofs, 'TXPC');
@@ -376,10 +376,8 @@ static void spr_set_modern_write_inner(spr_set* ss, void** data, size_t* size) {
st.enrs = e;
st.pof = pof;
st.header.signature = reverse_endianness_uint32_t('SPRC');
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header('SPRC');
st.header.attrib.set_big_endian(big_endian);
st.write(data, size, true, is_x);
}
+3 -5
View File
@@ -259,10 +259,8 @@ bool txp_set::pack_file_modern(void** data, size_t* size, bool big_endian, uint3
produce_enrs(&st.enrs);
st.header.signature = reverse_endianness_uint32_t(signature);
st.header.length = 0x20;
st.header.use_big_endian = big_endian;
st.header.use_section_size = true;
new (&st.header) f2_header(signature);
st.header.attrib.set_big_endian(big_endian);
st.write(data, size, true, false);
return true;
}
@@ -424,7 +422,7 @@ bool txp_set::unpack_file_modern(const void* data, size_t size, uint32_t signatu
f2_struct st;
st.read(data, size);
if (st.header.signature == reverse_endianness_uint32_t(signature))
ret = unpack_file(st.data.data(), st.header.use_big_endian);
ret = unpack_file(st.data.data(), st.header.attrib.get_big_endian());
return ret;
}
+63 -51
View File
@@ -771,15 +771,14 @@ void compile_all_shaders(bool debug) {
}
}
/*
void decrypt_x_save_data() {
uint8_t key[] = {
/*bool decrypt_x_save_data() {
static const uint8_t savedata_key[] = {
0xA4, 0xB7, 0x31, 0xD0, 0x33, 0xFB, 0x4A, 0x63, 0x9D, 0xD2, 0x46, 0xA5, 0x05, 0xCD, 0x4B, 0xE5,
0xF2, 0x10, 0xEE, 0x05, 0xC3, 0x56, 0x45, 0x3A, 0xAF, 0x22, 0x5C, 0x88, 0xA0, 0x9F, 0xB6, 0x8A,
};
aes256_ctx aes;
aes256_init_ctx(&aes, key);
aes256_init_ctx(&aes, savedata_key);
file_stream ifs;
ifs.open("SECURE.BIN", "rb");
@@ -790,60 +789,73 @@ void decrypt_x_save_data() {
ifs.read(data.data(), data.size());
ifs.close();
struct savedata_header {
uint32_t signature;
uint32_t data_size;
uint32_t length;
uint32_t flags;
uint8_t unk10;
uint8_t crc8;
uint16_t crc16;
uint32_t section_size;
uint32_t unk18;
uint32_t unk1C;
uint8_t data[];
};
f2_header* head = (f2_header*)data.data();
savedata_header* head = (savedata_header*)data.data();
uint8_t* a1 = data.data();
uint8_t* v5 = a1 + head->length;
uint8_t* v8 = a1;
uint8_t* v9 = v5 + head->section_size;
uint8_t v10 = 0xA5;
while (v8 != a1 + 8)
v10 ^= *v8++;
if (!v10 || v10 == 0xFF)
v10 = 1;
while (v5 != v9) {
uint8_t v12 = *v5;
*v5 ^= v10;
v10 = v12;
v5++;
}
aes256_ecb_decrypt_buffer(&aes, data.data() + head->length, data.size() - head->length);
file_stream ofs;
ofs.open("SECURE.BIN_DEC", "wb");
ofs.write(data.data(), data.size());
ofs.close();
bool reset_flags = head->attrib.get_gzip() || head->attrib.get_xor_data();
void* dst = 0;
size_t dst_len = head->unk1C;
deflate::decompress(data.data() + head->length, data.size() - head->length,
&dst, &dst_len, deflate::MODE_GZIP);
size_t dst_len = 0;
file_stream ufs;
ufs.open("SECURE.BIN_DEC_DEFLATE", "wb");
ufs.write(dst, dst_len);
ufs.close();
if (head->attrib.get_crc()) {
if (!head->validate_crc())
return false;
if (reset_flags) {
head->attrib.set_crc(false);
head->crc8 = 0x00;
head->crc16 = 0x00;
}
}
if (head->attrib.get_xor_data())
head->remove_xor();
if (head->attrib.get_aes()) {
uint8_t* section_data = head->get_section_data();
uint32_t section_size = head->get_section_size();
if (section_data && section_size == align_val(section_size, 0x20)) {
aes256_ecb_decrypt_buffer(&aes, section_data, section_size);
head->attrib.set_aes(false);
}
}
if (head->attrib.get_gzip()) {
uint8_t* section_data = head->get_section_data();
uint32_t section_size = head->get_section_size();
if (!head->custom || !section_data || !section_size)
return false;
dst = 0;
dst_len = head->custom;
if (deflate::decompress(section_data, section_size, &dst, &dst_len, deflate::MODE_GZIP) < 0
|| !dst_len || dst_len < head->custom) {
if (dst)
free(dst);
return false;
}
if (reset_flags)
head->attrib.set_gzip(false);
}
else {
dst = malloc(head->custom);
if (dst) {
dst_len = head->custom;
memset(dst, 0, head->custom);
memcpy(dst, head->get_section_data(), min_def(head->custom, head->get_section_size()));
}
}
if (dst && dst_len) {
file_stream ofs;
ofs.open("SECURE.BIN_DEC", "wb");
ofs.write(dst, dst_len);
ofs.close();
}
if (dst)
free(dst);
return true;
}*/
/*void process_edit_dsc(const char* path, const char* file,