mirror of
https://github.com/redstrate/Astra.git
synced 2025-04-20 11:47:46 +00:00
Add a fiin parser
Don't know what this file format is actually used for, but it was fun to reverse engineer, and I don't think anyone has done it for this format yet!
This commit is contained in:
parent
0b3f438819
commit
1c71d69a84
3 changed files with 90 additions and 1 deletions
|
@ -32,7 +32,9 @@ set(SRC
|
|||
src/launcherwindow.cpp
|
||||
include/launcherwindow.h
|
||||
src/gamescopesettingswindow.cpp
|
||||
include/gamescopesettingswindow.h)
|
||||
include/gamescopesettingswindow.h
|
||||
src/fiinparser.cpp
|
||||
include/fiinparser.h)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
|
|
40
include/fiinparser.h
Normal file
40
include/fiinparser.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
|
||||
// this is methods dedicated to parsing "fiin" files, commonly shown as "fileinfo.fiin"
|
||||
|
||||
// header is 1024 bytes
|
||||
// for some reason, they store unknown1 and unknown 2 in this weird format,
|
||||
// unknown1 is capped at 256 (in decimal) and will overflow into unknown 2
|
||||
// for example, 1 is equal to unknown1 = 96 and unknown2 = 0
|
||||
// 96 / 1 == 1
|
||||
// if you have say, 14 entries, then unknown1 = 64 and unknown2 = 5
|
||||
// 5 (unknown2) * 256 = 1280 + 64 (unknown1) = 1344
|
||||
// 1344 / 96 = 14
|
||||
// i could've made a mistake and this is actually really common but i don't know
|
||||
struct FileInfoHeader {
|
||||
char magic[9];
|
||||
uint8_t dummy1[16];
|
||||
uint8_t unknown; // version? always seems to be 4
|
||||
uint8_t dummy2[2];
|
||||
uint8_t unknown1;
|
||||
uint8_t unknown2;
|
||||
uint8_t dummy[994];
|
||||
};
|
||||
|
||||
// each entry is 96 bytes
|
||||
struct FileInfoEntry {
|
||||
uint8_t dummy[8]; // length of file name in some format
|
||||
char str[64]; // simple \0 encoded string
|
||||
uint8_t dummy2[24]; // sha1
|
||||
};
|
||||
|
||||
struct FileInfo {
|
||||
FileInfoHeader header;
|
||||
std::vector<FileInfoEntry> entries;
|
||||
};
|
||||
|
||||
FileInfo readFileInfo(const std::string_view path);
|
47
src/fiinparser.cpp
Normal file
47
src/fiinparser.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "fiinparser.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <QDebug>
|
||||
|
||||
FileInfo readFileInfo(const std::string_view path) {
|
||||
FILE* file = fopen(path.data(), "rb");
|
||||
if(!file) {
|
||||
qInfo() << "Failed to read file info " << path.data();
|
||||
return {};
|
||||
}
|
||||
|
||||
FileInfo info;
|
||||
fread(&info.header, sizeof info.header, 1, file);
|
||||
|
||||
char magic[9] = "FileInfo";
|
||||
if(strcmp(info.header.magic, magic) != 0)
|
||||
qInfo() << "Invalid magic for fileinfo.";
|
||||
else
|
||||
qInfo() << "Got matching magic:" << info.header.magic;
|
||||
|
||||
qInfo() << "unknown (version?) = " << info.header.unknown;
|
||||
qInfo() << "unknown1 = " << info.header.unknown1;
|
||||
qInfo() << "unknown2 = " << info.header.unknown2;
|
||||
|
||||
int overflow = info.header.unknown2;
|
||||
int extra = overflow * 256;
|
||||
int first = info.header.unknown1 / 96;
|
||||
int first2 = extra / 96;
|
||||
int actualEntries = first + first2 + 1; // is this 1 really needed? lol
|
||||
|
||||
qInfo() << "Guessed number of entries: " << actualEntries;
|
||||
|
||||
int numEntries = actualEntries;
|
||||
for(int i = 0; i < numEntries; i++) {
|
||||
FileInfoEntry entry;
|
||||
fread(&entry, sizeof entry, 1, file);
|
||||
|
||||
info.entries.push_back(entry);
|
||||
|
||||
qDebug() << entry.str;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return info;
|
||||
}
|
Loading…
Add table
Reference in a new issue