mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-09 15:09:50 +03:00
Refectored f2_header and f2_struct
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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*)§ion_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user