mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-31 13:25:58 -05:00
Compare commits
20 Commits
ImHex-v1.3
...
ImHex-v1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10bf1c76cf | ||
|
|
5b7c212029 | ||
|
|
1c2e948940 | ||
|
|
7ea34e410a | ||
|
|
56950e44d8 | ||
|
|
ed42452fc1 | ||
|
|
a68ecb8888 | ||
|
|
8d4cf59497 | ||
|
|
3c2fed22e4 | ||
|
|
ff550bd105 | ||
|
|
0ad6e3abde | ||
|
|
891968db53 | ||
|
|
5799d1d7ea | ||
|
|
9c6bfeb50f | ||
|
|
9f7cdded6a | ||
|
|
03298b0b0c | ||
|
|
5f2738872e | ||
|
|
63585e6de7 | ||
|
|
cb6caafa64 | ||
|
|
236fadee47 |
@@ -5,6 +5,7 @@
|
||||
## Checklist
|
||||
- [ ] A pattern for this format doesn't exist yet (or this PR improves the existing one)
|
||||
- [ ] The new pattern has been added to the relevant table in the Readme
|
||||
- [ ] The new pattern has a description pragma (`#pragma description My pattern Description here`)
|
||||
- [ ] The pattern was associated with all relevant MIME types (using `#pragma MIME mime-type` in the source code)
|
||||
- Make sure to never use `application/octet-stream` here as that means "Unidentifiable binary data"
|
||||
- [ ] A test file for this pattern has been added to [/tests/patterns/test_data](/tests/patterns/test_data)
|
||||
|
||||
25
.github/workflows/tests.yml
vendored
25
.github/workflows/tests.yml
vendored
@@ -28,6 +28,7 @@ jobs:
|
||||
sudo apt update
|
||||
sudo apt install -y \
|
||||
build-essential \
|
||||
ccache \
|
||||
gcc-12 \
|
||||
g++-12 \
|
||||
lld \
|
||||
@@ -41,12 +42,21 @@ jobs:
|
||||
|
||||
sudo pip install jsonschema
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${{ runner.os }}-ccache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-ccache
|
||||
max-size: 1G
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
cd tests
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
|
||||
-DLIBPL_ENABLE_TESTS=OFF \
|
||||
@@ -57,20 +67,7 @@ jobs:
|
||||
- name: 🧪 Perform Unit Tests
|
||||
run: |
|
||||
cd tests/build
|
||||
ctest --output-on-failure
|
||||
|
||||
#- name: ⚗️ Generate Coverage Report
|
||||
# run: |
|
||||
# cd tests/build
|
||||
# lcov -d ./_deps/pattern_language-build/lib --gcov-tool /usr/bin/gcov-12 -c -o coverage.info
|
||||
|
||||
#- name: ⬆️ Upload Coverage Report
|
||||
# uses: coverallsapp/github-action@master
|
||||
# env:
|
||||
# NODE_OPTIONS: --max-old-space-size=8000
|
||||
# with:
|
||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# path-to-lcov: tests/build/coverage.info
|
||||
ctest --output-on-failure -j 4
|
||||
|
||||
- name: 📎 Validate JSON Files
|
||||
run: |
|
||||
|
||||
18
README.md
18
README.md
@@ -1,6 +1,7 @@
|
||||
# ImHex Database
|
||||
|
||||
This repository serves as a database for files to use with the [ImHex Hex Editor](https://github.com/WerWolv/ImHex). It currently contains
|
||||
|
||||
- [Patterns](/patterns) - Binary Format definitions for the Pattern Language
|
||||
- [Pattern Libraries](/includes) - Libraries that make using the Pattern Language easier
|
||||
- [Magic Files](/magic) - Custom magic file definitions for the use with libmagic
|
||||
@@ -25,6 +26,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| 3DS | | [`patterns/3ds.hexpat`](patterns/3ds.hexpat) | Autodesk 3DS Max Model file |
|
||||
| 7Z | | [`patterns/7z.hexpat`](patterns/7z.hexpat) | 7z File Format |
|
||||
| AFE2 | | [`patterns/afe2.hexpat`](patterns/afe2.hexpat) | Nintendo Switch Atmosphère CFW Fatal Error log |
|
||||
| ANI | `application/x-navi-animation` | [`patterns/ani.hexpat`](patterns/ani.hexpat) | Windows Animated Cursor file |
|
||||
| AR | `application/x-archive` | [`patterns/ar.hexpat`](patterns/ar.hexpat) | Static library archive files |
|
||||
| ARIA2 | | [`patterns/aria2.hexpat`](patterns/aria2.hexpat) | ARIA2 Download Manager Control files |
|
||||
| ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout |
|
||||
@@ -48,6 +50,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| DMG | | [`patterns/dmg.hexpat`](patterns/dmg.hexpat) | Apple Disk Image Trailer (DMG) |
|
||||
| DS_Store | | [`patterns/dsstore.hexpat`](patterns/dsstore.hexpat) | .DS_Store file format |
|
||||
| DTA | | [`patterns/max_v104.hexpat`](patterns/max_v104.hexpat) | Mechanized Assault and Exploration v1.04 (strategy game) save file format |
|
||||
| DTED | | [`patterns/dted.hexpat`](patterns/dted.hexpat) | Digital Terrain Elevation Data (DTED) |
|
||||
| ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries |
|
||||
| EVTX | | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log |
|
||||
| FAS | | [`patterns/fas_oskasoftware.hexpat`](patterns/fas_oskasoftware.hexpat) [`patterns/fas_oskasoftware_old.hexpat`](patterns/fas_oskasoftware_old.hexpat) (Old versions of Oska DeskMate) | Oska Software DeskMates FAS (Frames and Sequences) file |
|
||||
@@ -56,6 +59,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| File System | | [`patterns/fs.hexpat`](patterns/fs.hexpat) | Drive File System |
|
||||
| FLAC | `audio/flac` | [`patterns/flac.hexpat`](patterns/flac.hexpat) | Free Lossless Audio Codec, FLAC Audio Format |
|
||||
| GB | `application/x-gameboy-rom` | [`patterns/gb.hexpat`](patterns/gb.hexpat) | Gameboy ROM |
|
||||
| GGUF | | [`patterns/gguf.hexpat`](patterns/gguf.hexpat) | GGML Inference Models |
|
||||
| GIF | `image/gif` | [`patterns/gif.hexpat`](patterns/gif.hexpat) | GIF image files |
|
||||
| GZIP | `application/gzip` | [`patterns/gzip.hexpat`](patterns/gzip.hexpat) | GZip compressed data format |
|
||||
| Halo Bitmap || [`patterns/hinf_bitmap.hexpat`](patterns/hinf_bitmap.hexpat) | Halo Infinite Bitmap tag files |
|
||||
@@ -82,16 +86,17 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files |
|
||||
| NTAG | | [`patterns/ntag.hexpat`](patterns/ntag.hexpat) | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC |
|
||||
| OGG | `audio/ogg` | [`patterns/ogg.hexpat`](patterns/ogg.hexpat) | OGG Audio format |
|
||||
| PAK | | [`patterns/xgspak.hexpat`](patterns/xgspak.hexpat) | Exient XGS Engine Pak files |
|
||||
| PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets |
|
||||
| PCX | `application/x-pcx` | [`patterns/pcx.hexpat`](patterns/pcx.hexpat) | PCX Image format |
|
||||
| PE | `application/x-dosexec` `application/x-msdownload` | [`patterns/pe.hexpat`](patterns/pe.hexpat) | PE header, COFF header, Standard COFF fields and Windows Specific fields |
|
||||
| PP | | [`patterns/selinuxpp.hexpat`](patterns/selinuxpp.pat) | SE Linux package |
|
||||
| PFS0 | | [`patterns/pfs0.hexpat`](patterns/pfs0.hexpat) | Nintendo Switch PFS0 archive (NSP files) |
|
||||
| PIF | `image/pif` | [`patterns/pif.hexpat`](patterns/pif.hexpat) | PIF Image Format |
|
||||
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
|
||||
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
|
||||
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
|
||||
| PyInstaller | | [`patterns/pyinstaller.hexpat`](patterns/pyinstaller.hexpat) | PyInstaller binray files |
|
||||
| PNG | `image/png` | [`patterns/png.hexpat`](patterns/png.hexpat) | PNG image files |
|
||||
| PRODINFO | | [`patterns/prodinfo.hexpat`](patterns/prodinfo.hexpat) | Nintendo Switch PRODINFO |
|
||||
| Protobuf | | [`patterns/protobuf.hexpat`](patterns/protobuf.hexpat) | Google Protobuf encoding |
|
||||
| PyInstaller | | [`patterns/pyinstaller.hexpat`](patterns/pyinstaller.hexpat) | PyInstaller binray files |
|
||||
| PYC | | [`patterns/pyc.hexpat`](patterns/pyc.hexpat) | Python bytecode files |
|
||||
| QBCL | | [`patterns/qbcl.hexpat`](patterns/qbcl.hexpat) | Qubicle voxel scene project file |
|
||||
| QOI | `image/qoi` | [`patterns/qoi.hexpat`](patterns/qoi.hexpat) | QOI image files |
|
||||
@@ -117,7 +122,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
| WAS | | [`patterns\was_oskasoftware.hexpat`](patterns\was_oskasoftware.hexpat) | Oska Software DeskMates WAS/WA3 (WAVE/MP3 Set) file
|
||||
| WAD | | [`patterns/wad.hexpat`](patterns/wad.hexpat) | DOOM WAD Archive |
|
||||
| XBEH | `audio/x-xbox-executable` | [`patterns/xbeh.hexpat`](patterns/xbeh.hexpat) | Xbox executable |
|
||||
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cardridge ROM |
|
||||
| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cartridge ROM |
|
||||
| XGT | | [`patterns/xgt.hexpat`](patterns/xgstexture.hexpat) | Exient XGS Engine Texture |
|
||||
| Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams |
|
||||
| Xilinx Bootgen | | [`patterns/xilinx_bootgen.hexpat`](patterns/xilinx_bootgen.hexpat) | Xilinx ZynqMP Boot Images |
|
||||
| ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers |
|
||||
@@ -203,12 +209,14 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
|
||||
> import custom encoding from File -> Import... -> Custome Encoding File
|
||||
|
||||
### Data Processor Nodes
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Caesar Cipher | [`nodes/caesar.hexnode`](nodes/caesar.hexnode) | Simple adjustable per-byte Caecar Cipher (ROT) |
|
||||
| XOR Cipher | [`nodes/xor.hexnode`](nodes/xor.hexnode) | XORs a input with a repeating XOR pad |
|
||||
|
||||
### Themes
|
||||
|
||||
| Name | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Visual Studio Dark | [`themes/vs_dark.json`](themes/vs_dark.json) | Theme similar to Visual Studio's Dark theme |
|
||||
|
||||
@@ -37,4 +37,14 @@ namespace auto hex::core {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
Add a file to the Virtual Filesystem
|
||||
@param path The name of the file
|
||||
@param pattern The pattern associated with the file
|
||||
*/
|
||||
fn add_virtual_file(str path, auto pattern)
|
||||
{
|
||||
builtin::hex::core::add_virtual_file(path, pattern);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace auto std::file {
|
||||
@param handle The handle of the file to flush
|
||||
*/
|
||||
fn flush(Handle handle) {
|
||||
builtin::std::file::remove(handle);
|
||||
builtin::std::file::flush(handle);
|
||||
};
|
||||
|
||||
|
||||
@@ -109,4 +109,12 @@ namespace auto std::file {
|
||||
builtin::std::file::remove(handle);
|
||||
};
|
||||
|
||||
/**
|
||||
Create all directories for the provided path
|
||||
@param path The path for which all directories should be created
|
||||
*/
|
||||
fn create_directories(str path) {
|
||||
builtin::std::file::create_directories(path);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma description 7z File Format
|
||||
#pragma MIME application/x-7z-compressed
|
||||
|
||||
import std.io;
|
||||
import std.mem;
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
#pragma author AdventureT
|
||||
#pragma description Crash Bandicoot - Back in Time (fan game) User created level format
|
||||
// Supports all versions till 0.94c, newer versions might be compatible!
|
||||
#pragma history
|
||||
#pragma 0.3 2024-05-15 Added support for version 0.95
|
||||
#pragma 0.2 2023-10-29 Added support for version 0.94c
|
||||
#pragma 0.1 2023-04-25 Initial support
|
||||
// Supports all versions till 0.95, newer versions might be compatible!
|
||||
|
||||
import type.magic;
|
||||
import std.string;
|
||||
import std.array;
|
||||
|
||||
|
||||
struct Header {
|
||||
type::Magic<"CRASHLVL"> magic;
|
||||
u8 version;
|
||||
@@ -17,8 +20,6 @@ struct Header {
|
||||
std::string::SizedString<u8> author;
|
||||
};
|
||||
|
||||
Header header @ 0x0;
|
||||
|
||||
// Background Music
|
||||
enum BGM : u32 {
|
||||
None,
|
||||
@@ -37,6 +38,56 @@ enum BGM : u32 {
|
||||
};
|
||||
|
||||
enum BGMV2 : u32 {
|
||||
None,
|
||||
N_TropyBGM,
|
||||
CrashCreatorBGM,
|
||||
MainMenuBGM,
|
||||
WarpRoomBGM,
|
||||
Jungle01BGM,
|
||||
SnowBGM,
|
||||
RiverBGM,
|
||||
FutureBGM,
|
||||
LabBGM,
|
||||
SewerBGM,
|
||||
EgyptBGM,
|
||||
NBrioBGM,
|
||||
AdventureBGM,
|
||||
SpyBGM,
|
||||
ChaseBGM,
|
||||
TrialsBGM,
|
||||
SpaceBGM,
|
||||
Jungle02BGM,
|
||||
RipperBGM,
|
||||
TheGreatWallBGM,
|
||||
RoadToSomewhereBGM,
|
||||
LavaKoalaBGM,
|
||||
CortexBGM,
|
||||
CyberCortexBGM,
|
||||
ArabicBGM,
|
||||
N_Tropy2BGM,
|
||||
JazzBGM,
|
||||
Space2BGM,
|
||||
TawnaBonusBGM,
|
||||
CortexPowerBGM,
|
||||
ArabicBonusBGM,
|
||||
EgyptBonusBGM,
|
||||
FutureBonusBGM,
|
||||
LostCityBGM,
|
||||
PolarBGM,
|
||||
RiverBonusBGM,
|
||||
RuinsBonusBGM,
|
||||
SewerBonusBGM,
|
||||
SnowBonusBGM,
|
||||
RoadToRuinBGM,
|
||||
NGinBGM,
|
||||
Arabia01BGM,
|
||||
Arabia02BGM,
|
||||
BashBGM,
|
||||
Cortex02BGM
|
||||
};
|
||||
|
||||
// v0.95
|
||||
enum BGMV3 : BGMV2 {
|
||||
None,
|
||||
N_TropyBGM,
|
||||
CrashCreatorBGM,
|
||||
@@ -83,12 +134,19 @@ enum BGMV2 : u32 {
|
||||
Arabia02BGM,
|
||||
BashBGM,
|
||||
Cortex02BGM,
|
||||
MedievalBGM,
|
||||
PreHistoricBGM,
|
||||
UnderWaterBGM,
|
||||
BrioRevisitedBGM,
|
||||
EgyptChaseBGM,
|
||||
RuinsLoopBGM,
|
||||
DingoSynthBGM
|
||||
};
|
||||
|
||||
enum Type : u32 {
|
||||
Unset,
|
||||
Flashback,
|
||||
Trial,
|
||||
Trial
|
||||
};
|
||||
|
||||
enum TypeV2 : u32 {
|
||||
@@ -118,13 +176,31 @@ enum SkyboxV2 : u32 {
|
||||
Black
|
||||
};
|
||||
|
||||
// 0.95
|
||||
enum SkyboxV3 : u32 {
|
||||
Default = 1,
|
||||
Briolab,
|
||||
Fort,
|
||||
Moon,
|
||||
Toxic,
|
||||
AboutRight,
|
||||
Crash1Island,
|
||||
Arabia,
|
||||
RoadToRuin,
|
||||
MotorcycleDay,
|
||||
MotorcycleNoon,
|
||||
MotorcycleMoon,
|
||||
MotorcycleNight,
|
||||
Black
|
||||
};
|
||||
|
||||
enum Scenery : u32 {
|
||||
None,
|
||||
FutureTense,
|
||||
Forest,
|
||||
Waterfall,
|
||||
Snow,
|
||||
Fortress,
|
||||
Fortress
|
||||
};
|
||||
|
||||
enum SceneryV2 : u32 {
|
||||
@@ -165,44 +241,102 @@ enum SceneryV4 : u32 {
|
||||
Pipes
|
||||
};
|
||||
|
||||
// 0.95
|
||||
enum SceneryV5 : u32 {
|
||||
None,
|
||||
FutureTense,
|
||||
Forest,
|
||||
Waterfall,
|
||||
Snow,
|
||||
Fortress,
|
||||
None2,
|
||||
Lava,
|
||||
TheGreatGate,
|
||||
Mountain,
|
||||
KoalaKong,
|
||||
SunsetVista,
|
||||
HangemHigh,
|
||||
Sphynxinator,
|
||||
Tunnel,
|
||||
Pipes,
|
||||
Medieval,
|
||||
FutureCity,
|
||||
TinyArena,
|
||||
HeavyMachinery,
|
||||
CrystalCave,
|
||||
MedievalWithHouses,
|
||||
CortexBonusChamber
|
||||
};
|
||||
|
||||
enum Weather : u32 {
|
||||
Default,
|
||||
Snow,
|
||||
Rain
|
||||
};
|
||||
|
||||
// 0.95
|
||||
enum WeatherV2 : u32 {
|
||||
Default,
|
||||
Snow,
|
||||
Rain,
|
||||
Night,
|
||||
UnderWater
|
||||
};
|
||||
|
||||
|
||||
struct Options {
|
||||
|
||||
if (header.version > 1)
|
||||
// Type
|
||||
if (header.version > 1) {
|
||||
TypeV2 type;
|
||||
else
|
||||
Type type;
|
||||
|
||||
if (header.version > 1)
|
||||
SkyboxV2 skybox;
|
||||
else
|
||||
Skybox skybox;
|
||||
|
||||
if (header.version == 1)
|
||||
Scenery scenery;
|
||||
else if (header.version > 1 && header.version < 4)
|
||||
SceneryV2 scenery;
|
||||
else
|
||||
SceneryV4 scenery;
|
||||
|
||||
if (header.version > 2)
|
||||
{
|
||||
Weather weather;
|
||||
}
|
||||
|
||||
if (header.version > 1)
|
||||
else {
|
||||
Type type;
|
||||
}
|
||||
// Skybox
|
||||
if (header.version > 1) {
|
||||
if (header.gameVersion == "0.95") {
|
||||
SkyboxV3 skybox;
|
||||
}
|
||||
else {
|
||||
SkyboxV2 skybox;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Skybox skybox;
|
||||
}
|
||||
// Scenery
|
||||
if (header.version == 1) {
|
||||
Scenery scenery;
|
||||
}
|
||||
else if (header.version > 1 && header.version < 4) {
|
||||
SceneryV2 scenery;
|
||||
}
|
||||
else {
|
||||
if (header.gameVersion == "0.95") {
|
||||
SceneryV5 skybox;
|
||||
}
|
||||
else {
|
||||
SceneryV4 skybox;
|
||||
}
|
||||
}
|
||||
// Weather
|
||||
if (header.version > 2) {
|
||||
if (header.gameVersion == "0.95") {
|
||||
WeatherV2 weather;
|
||||
}
|
||||
else {
|
||||
Weather weather;
|
||||
}
|
||||
}
|
||||
// Background music
|
||||
if (header.version > 1) {
|
||||
BGMV2 bgm;
|
||||
else
|
||||
}
|
||||
else {
|
||||
BGM bgm;
|
||||
|
||||
|
||||
if (type == Type::Trial)
|
||||
{
|
||||
}
|
||||
// Time Trial
|
||||
if (type == Type::Trial) {
|
||||
u32 timeTrialTicksBronze;
|
||||
u32 timeTrialTicksSilver;
|
||||
u32 timeTrialTicksGold;
|
||||
@@ -210,22 +344,17 @@ struct Options {
|
||||
};
|
||||
|
||||
struct Object {
|
||||
|
||||
std::string::SizedString<u8> objName;
|
||||
|
||||
if (header.version > 1)
|
||||
{
|
||||
if (header.version > 1) {
|
||||
u16 x;
|
||||
u16 y;
|
||||
bool hasMetafields;
|
||||
if (hasMetafields)
|
||||
{
|
||||
if (hasMetafields) {
|
||||
u16 numOfMetafields;
|
||||
u8 metafields[numOfMetafields];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else {
|
||||
u32 x;
|
||||
u32 y;
|
||||
}
|
||||
@@ -236,9 +365,6 @@ struct Objects{
|
||||
std::Array<Object, objCount> objArray;
|
||||
};
|
||||
|
||||
|
||||
Header header @ $;
|
||||
Options options @ $;
|
||||
Objects objects @ $;
|
||||
|
||||
|
||||
|
||||
Objects objects @ $;
|
||||
66
patterns/ani.hexpat
Normal file
66
patterns/ani.hexpat
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma description Windows animated cursor
|
||||
#pragma MIME application/x-navi-animation
|
||||
#pragma endian little
|
||||
|
||||
import std.io;
|
||||
import std.mem;
|
||||
|
||||
bitfield HeaderFlags {
|
||||
icon : 1;
|
||||
sequence : 1;
|
||||
padding: 30;
|
||||
};
|
||||
|
||||
struct anih {
|
||||
u32 struct_size;
|
||||
u32 stored_frames;
|
||||
u32 animation_steps;
|
||||
u32 w;
|
||||
u32 h;
|
||||
u32 bits;
|
||||
u32 planes;
|
||||
u32 default_jiffies;
|
||||
HeaderFlags flags;
|
||||
};
|
||||
|
||||
struct rate {
|
||||
u32 jiffies[parent.size / 4];
|
||||
};
|
||||
|
||||
struct seq {
|
||||
u32 index[parent.size / 4];
|
||||
};
|
||||
|
||||
struct RiffChunk {
|
||||
char signature[4];
|
||||
u32 size;
|
||||
if (signature == "RIFF" || signature == "LIST") {
|
||||
char type[4];
|
||||
RiffChunk chunks[while($ - addressof(type) < size)];
|
||||
} else if (signature[0] == 'I' && parent.type == "INFO") {
|
||||
char info[size];
|
||||
} else if (signature == "anih") {
|
||||
anih anih [[inline]];
|
||||
} else if (signature == "rate") {
|
||||
rate rate [[inline]];
|
||||
} else if (signature == "seq ") {
|
||||
seq seq [[inline]];
|
||||
} else {
|
||||
std::mem::Bytes<size> data;
|
||||
}
|
||||
padding[size % 2];
|
||||
} [[format_read("read_chunk")]];
|
||||
|
||||
fn read_chunk(RiffChunk chunk) {
|
||||
if (chunk.signature == "RIFF" || chunk.signature == "LIST") {
|
||||
return std::format("{}<{}> ({})", chunk.signature, chunk.type, chunk.size);
|
||||
} else {
|
||||
str ret = std::format("{} ({})", chunk.signature, chunk.size);
|
||||
try {
|
||||
ret += std::format(" \"{}\"", chunk.info);
|
||||
} catch {}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
RiffChunk riff @ 0;
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma description TODO
|
||||
|
||||
import std.math;
|
||||
import std.core;
|
||||
import type.magic;
|
||||
|
||||
117
patterns/dted.hexpat
Normal file
117
patterns/dted.hexpat
Normal file
@@ -0,0 +1,117 @@
|
||||
#pragma description Digital Terrain Elevation Data
|
||||
#pragma endian big
|
||||
|
||||
import std.core;
|
||||
import std.io;
|
||||
import std.mem;
|
||||
import std.string;
|
||||
|
||||
|
||||
enum Magic:u24 {
|
||||
UHL = 0x55484C,
|
||||
DSI = 0x445349,
|
||||
ACC = 0x414343,
|
||||
};
|
||||
|
||||
struct UHL {
|
||||
Magic magic;
|
||||
char one;
|
||||
char lon[8];
|
||||
char lat[8];
|
||||
char lon_data_interval[4];
|
||||
char lat_data_interval[4];
|
||||
char accuracy[4];
|
||||
char security_code[3];
|
||||
char uniq_ref[12];
|
||||
char lon_lines[4];
|
||||
char lat_points[4];
|
||||
char multi_accuracy;
|
||||
char reserved[24];
|
||||
};
|
||||
|
||||
struct DSI {
|
||||
Magic magic;
|
||||
char classification;
|
||||
char stuff1[29];
|
||||
char stuff2[26];
|
||||
char product_level[5];
|
||||
char uniq_ref[15];
|
||||
char reserved[8];
|
||||
char data_edition[2];
|
||||
char match_version;
|
||||
char maint_date[4];
|
||||
char match_date[4];
|
||||
char main_desc_code[4];
|
||||
char producer_code[8];
|
||||
char reserved2[16];
|
||||
char product_spec[9];
|
||||
char numbers[2];
|
||||
char product_spec_date[4];
|
||||
char vertical_datum[3];
|
||||
char horizontal_datum[5];
|
||||
char digitizing_system[10];
|
||||
char compilation_date[4];
|
||||
char reserved3[22];
|
||||
char lat_origin[9];
|
||||
char lon_origin[10];
|
||||
char lat_sw_corner[7];
|
||||
char lon_sw_corner[8];
|
||||
char lat_nw_corner[7];
|
||||
char lon_nw_corner[8];
|
||||
char lat_ne_corner[7];
|
||||
char lon_ne_corner[8];
|
||||
char lat_se_corner[7];
|
||||
char lon_se_corner[8];
|
||||
char clockwise_orientation[9];
|
||||
char lat_interval[4];
|
||||
char lon_interval[4];
|
||||
char lat_lines[4];
|
||||
char lon_lines[4];
|
||||
char partial_cell[2];
|
||||
char reserved4[101];
|
||||
char reserved5[100];
|
||||
char reserved6[156];
|
||||
};
|
||||
|
||||
struct ACCSub {
|
||||
char abs_vertical_accuracy[4];
|
||||
char abs_horizontal_accuracy[4];
|
||||
char rel_vertical_accuracy[4];
|
||||
char rel_horizontal_accuracy[4];
|
||||
char num_coords[2];
|
||||
char pairs[19*14];
|
||||
};
|
||||
|
||||
struct ACC {
|
||||
Magic magic;
|
||||
char abs_horizontal_accuracy[4];
|
||||
char abs_vertical_accuracy[4];
|
||||
char rel_horizontal_accuracy[4];
|
||||
char rel_vertical_accuracy[4];
|
||||
char reserved1[4];
|
||||
char reserved2[1];
|
||||
char reserved3[31];
|
||||
char multi_accuracy_outline[2]; // determines sub regions
|
||||
ACCSub subs[9];
|
||||
char reserved4[18];
|
||||
char reserved5[69];
|
||||
|
||||
};
|
||||
|
||||
struct DataRecords {
|
||||
char magic;
|
||||
s24 data_block_count;
|
||||
s16 lon_count;
|
||||
s16 lat_count;
|
||||
s16 elevation[std::string::parse_int(parent.dsi.lat_lines, 10)];
|
||||
u32 checksum;
|
||||
};
|
||||
|
||||
struct DTED {
|
||||
UHL uhl;
|
||||
DSI dsi;
|
||||
ACC acc;
|
||||
DataRecords records[std::string::parse_int(this.dsi.lon_lines, 10)];
|
||||
};
|
||||
|
||||
DTED dted @ 0x00;
|
||||
Submodule patterns/ffx updated: ad18b0259f...199879e24a
215
patterns/gguf.hexpat
Normal file
215
patterns/gguf.hexpat
Normal file
@@ -0,0 +1,215 @@
|
||||
// https://github.com/ggerganov/ggml/blob/master/docs/gguf.md
|
||||
// https://github.com/openxla/iree/blob/main/runtime/src/iree/io/formats/gguf/gguf_parser.c
|
||||
|
||||
#pragma description GGUF v3 File Format Patter
|
||||
#pragma authors @leonjza, jessie @ imhex discord
|
||||
|
||||
#pragma pattern_limit 300000
|
||||
|
||||
enum ggml_type: u32 {
|
||||
GGML_TYPE_F32 = 0,
|
||||
GGML_TYPE_F16 = 1,
|
||||
GGML_TYPE_Q4_0 = 2,
|
||||
GGML_TYPE_Q4_1 = 3,
|
||||
// GGML_TYPE_Q4_2 = 4, support has been removed
|
||||
// GGML_TYPE_Q4_3 = 5, support has been removed
|
||||
GGML_TYPE_Q5_0 = 6,
|
||||
GGML_TYPE_Q5_1 = 7,
|
||||
GGML_TYPE_Q8_0 = 8,
|
||||
GGML_TYPE_Q8_1 = 9,
|
||||
GGML_TYPE_Q2_K = 10,
|
||||
GGML_TYPE_Q3_K = 11,
|
||||
GGML_TYPE_Q4_K = 12,
|
||||
GGML_TYPE_Q5_K = 13,
|
||||
GGML_TYPE_Q6_K = 14,
|
||||
GGML_TYPE_Q8_K = 15,
|
||||
GGML_TYPE_IQ2_XXS = 16,
|
||||
GGML_TYPE_IQ2_XS = 17,
|
||||
GGML_TYPE_IQ3_XXS = 18,
|
||||
GGML_TYPE_IQ1_S = 19,
|
||||
GGML_TYPE_IQ4_NL = 20,
|
||||
GGML_TYPE_IQ3_S = 21,
|
||||
GGML_TYPE_IQ2_S = 22,
|
||||
GGML_TYPE_IQ4_XS = 23,
|
||||
GGML_TYPE_I8 = 24,
|
||||
GGML_TYPE_I16 = 25,
|
||||
GGML_TYPE_I32 = 26,
|
||||
GGML_TYPE_I64 = 27,
|
||||
GGML_TYPE_F64 = 28,
|
||||
GGML_TYPE_IQ1_M = 29,
|
||||
GGML_TYPE_COUNT,
|
||||
};
|
||||
|
||||
enum gguf_metadata_value_type: u32 {
|
||||
// The value is a 8-bit unsigned integer.
|
||||
GGUF_METADATA_VALUE_TYPE_UINT8 = 0,
|
||||
// The value is a 8-bit signed integer.
|
||||
GGUF_METADATA_VALUE_TYPE_INT8 = 1,
|
||||
// The value is a 16-bit unsigned little-endian integer.
|
||||
GGUF_METADATA_VALUE_TYPE_UINT16 = 2,
|
||||
// The value is a 16-bit signed little-endian integer.
|
||||
GGUF_METADATA_VALUE_TYPE_INT16 = 3,
|
||||
// The value is a 32-bit unsigned little-endian integer.
|
||||
GGUF_METADATA_VALUE_TYPE_UINT32 = 4,
|
||||
// The value is a 32-bit signed little-endian integer.
|
||||
GGUF_METADATA_VALUE_TYPE_INT32 = 5,
|
||||
// The value is a 32-bit IEEE754 floating point number.
|
||||
GGUF_METADATA_VALUE_TYPE_FLOAT32 = 6,
|
||||
// The value is a boolean.
|
||||
// 1-byte value where 0 is false and 1 is true.
|
||||
// Anything else is invalid, and should be treated as either the model being invalid or the reader being buggy.
|
||||
GGUF_METADATA_VALUE_TYPE_BOOL = 7,
|
||||
// The value is a UTF-8 non-null-terminated string, with length prepended.
|
||||
GGUF_METADATA_VALUE_TYPE_STRING = 8,
|
||||
// The value is an array of other values, with the length and type prepended.
|
||||
///
|
||||
// Arrays can be nested, and the length of the array is the number of elements in the array, not the number of bytes.
|
||||
GGUF_METADATA_VALUE_TYPE_ARRAY = 9,
|
||||
// The value is a 64-bit unsigned little-endian integer.
|
||||
GGUF_METADATA_VALUE_TYPE_UINT64 = 10,
|
||||
// The value is a 64-bit signed little-endian integer.
|
||||
GGUF_METADATA_VALUE_TYPE_INT64 = 11,
|
||||
// The value is a 64-bit IEEE754 floating point number.
|
||||
GGUF_METADATA_VALUE_TYPE_FLOAT64 = 12,
|
||||
};
|
||||
|
||||
// A string in GGUF.
|
||||
struct gguf_string_t {
|
||||
// The length of the string, in bytes.
|
||||
u64 len;
|
||||
// The string as a UTF-8 non-null-terminated string.
|
||||
char string[len];
|
||||
};
|
||||
|
||||
|
||||
struct gguf_metadata_value_t {
|
||||
gguf_metadata_value_type type;
|
||||
u64 length;
|
||||
|
||||
match(type) {
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT8): u8 value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT8): s8 value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT16): u16 value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT16): s16 value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT32): u32 value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT32): s32 value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_FLOAT32): float value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_BOOL): bool value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_STRING): gguf_string_t value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT64): u64 value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_FLOAT64): double value[length];
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_ARRAY): double value[length];
|
||||
}
|
||||
};
|
||||
|
||||
struct gguf_metadata_value {
|
||||
gguf_metadata_value_type type;
|
||||
|
||||
match(type) {
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT8): u8 value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT8): s8 value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT16): u16 value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT16): s16 value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT32): u32 value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_INT32): s32 value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_FLOAT32): float value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_BOOL): bool value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_STRING): gguf_string_t value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_UINT64): u64 value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_FLOAT64): double value;
|
||||
(gguf_metadata_value_type::GGUF_METADATA_VALUE_TYPE_ARRAY): gguf_metadata_value_t value;
|
||||
}
|
||||
};
|
||||
|
||||
struct gguf_metadata_kv_t {
|
||||
// The key of the metadata. It is a standard GGUF string, with the following caveats:
|
||||
// - It must be a valid ASCII string.
|
||||
// - It must be a hierarchical key, where each segment is `lower_snake_case` and separated by a `.`.
|
||||
// - It must be at most 2^16-1/65535 bytes long.
|
||||
// Any keys that do not follow these rules are invalid.
|
||||
gguf_string_t key;
|
||||
|
||||
// The type of the value.
|
||||
// Must be one of the `gguf_metadata_value_type` values.
|
||||
// gguf_metadata_value_type value_type;
|
||||
|
||||
// The value.
|
||||
gguf_metadata_value value;
|
||||
};
|
||||
|
||||
struct gguf_header_t {
|
||||
// Magic number to announce that this is a GGUF file.
|
||||
// Must be `GGUF` at the byte level: `0x47` `0x47` `0x55` `0x46`.
|
||||
// Your executor might do little-endian byte order, so it might be
|
||||
// check for 0x46554747 and letting the endianness cancel out.
|
||||
// Consider being *very* explicit about the byte order here.
|
||||
u32 magic;
|
||||
// The version of the format implemented.
|
||||
// Must be `3` for version described in this spec, which introduces big-endian support.
|
||||
//
|
||||
// This version should only be increased for structural changes to the format.
|
||||
// Changes that do not affect the structure of the file should instead update the metadata
|
||||
// to signify the change.
|
||||
u32 version;
|
||||
// The number of tensors in the file.
|
||||
// This is explicit, instead of being included in the metadata, to ensure it is always present
|
||||
// for loading the tensors.
|
||||
u64 tensor_count;
|
||||
// The number of metadata key-value pairs.
|
||||
u64 metadata_kv_count;
|
||||
// The metadata key-value pairs.
|
||||
gguf_metadata_kv_t metadata_kv[metadata_kv_count];
|
||||
};
|
||||
|
||||
struct gguf_tensor_info_t {
|
||||
// The name of the tensor. It is a standard GGUF string, with the caveat that
|
||||
// it must be at most 64 bytes long.
|
||||
gguf_string_t name;
|
||||
// The number of dimensions in the tensor.
|
||||
// Currently at most 4, but this may change in the future.
|
||||
u32 n_dimensions;
|
||||
// The dimensions of the tensor.
|
||||
u64 dimensions[n_dimensions];
|
||||
// The type of the tensor.
|
||||
ggml_type type;
|
||||
// The offset of the tensor's data in this file in bytes.
|
||||
//
|
||||
// This offset is relative to `tensor_data`, not to the start
|
||||
// of the file, to make it easier for writers to write the file.
|
||||
// Readers should consider exposing this offset relative to the
|
||||
// file to make it easier to read the data.
|
||||
//
|
||||
// Must be a multiple of `ALIGNMENT`. That is, `align_offset(offset) == offset`.
|
||||
u64 offset;
|
||||
};
|
||||
|
||||
struct gguf_file_t {
|
||||
// The header of the file.
|
||||
gguf_header_t header;
|
||||
|
||||
// Tensor infos, which can be used to locate the tensor data.
|
||||
gguf_tensor_info_t tensor_infos[header.tensor_count];
|
||||
|
||||
// Padding to the nearest multiple of `ALIGNMENT`.
|
||||
//
|
||||
// That is, if `sizeof(header) + sizeof(tensor_infos)` is not a multiple of `ALIGNMENT`,
|
||||
// this padding is added to make it so.
|
||||
//
|
||||
// This can be calculated as `align_offset(position) - position`, where `position` is
|
||||
// the position of the end of `tensor_infos` (i.e. `sizeof(header) + sizeof(tensor_infos)`).
|
||||
u8 _padding[];
|
||||
|
||||
// Tensor data.
|
||||
//
|
||||
// This is arbitrary binary data corresponding to the weights of the model. This data should be close
|
||||
// or identical to the data in the original model file, but may be different due to quantization or
|
||||
// other optimizations for inference. Any such deviations should be recorded in the metadata or as
|
||||
// part of the architecture definition.
|
||||
//
|
||||
// Each tensor's data must be stored within this array, and located through its `tensor_infos` entry.
|
||||
// The offset of each tensor's data must be a multiple of `ALIGNMENT`, and the space between tensors
|
||||
// should be padded to `ALIGNMENT` bytes.
|
||||
u8 tensor_data[];
|
||||
};
|
||||
|
||||
gguf_file_t GGUF @ 0x00;
|
||||
@@ -22,6 +22,8 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma description TODO
|
||||
|
||||
import std.mem;
|
||||
import std.io;
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma description TODO
|
||||
|
||||
import std.mem;
|
||||
import std.io;
|
||||
import std.string;
|
||||
|
||||
@@ -18,15 +18,23 @@ fn format_string(auto string) {
|
||||
return string.value;
|
||||
};
|
||||
|
||||
fn format_fixed32(auto fp32) {
|
||||
return fp32.integer + fp32.fraction / 65536.0;
|
||||
};
|
||||
|
||||
fn format_fixed16(auto fp16) {
|
||||
return fp16.integer + fp16.fraction / 256.0;
|
||||
};
|
||||
|
||||
struct FixedPoint16 {
|
||||
u8 integer;
|
||||
u8 fraction;
|
||||
};
|
||||
} [[format("format_fixed16")]];
|
||||
|
||||
struct FixedPoint32 {
|
||||
u16 integer;
|
||||
u16 fraction;
|
||||
};
|
||||
} [[format("format_fixed32")]];
|
||||
|
||||
struct string {
|
||||
char value[std::mem::find_sequence_in_range(0, $, std::mem::size(), 0x00) - $];
|
||||
@@ -122,8 +130,8 @@ struct TrackHeaderBox : FullBox {
|
||||
s16 volume;
|
||||
u16 reserved_3;
|
||||
s32 matrix[9];
|
||||
u32 width;
|
||||
u32 height;
|
||||
FixedPoint32 width;
|
||||
FixedPoint32 height;
|
||||
};
|
||||
|
||||
struct DataEntryBox : FullBox {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma author Fl3ch4
|
||||
|
||||
#pragma description TODO
|
||||
#pragma MIME image/webp
|
||||
#pragma endian big
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma author 5h4rrK
|
||||
#pragma description ReFS-File-System
|
||||
#pragma author 5h4rrK // https://www.github.com/5h4rrK
|
||||
#pragma organization temabi0s // (https://bi0s.in)
|
||||
#pragma description ReFS-File-System
|
||||
|
||||
#pragma array_limit 10000
|
||||
|
||||
import type.types.win32;
|
||||
import type.guid;
|
||||
@@ -25,19 +28,46 @@ enum BLOCK : u32 {
|
||||
MSBPlus = 0x2b42534d
|
||||
};
|
||||
|
||||
struct SELF_DESCRIPTOR{
|
||||
u32 start = $;
|
||||
u64 LCN1[[name("FirstLCN")]];
|
||||
u64 LCN2[[name("SecondLCN")]];
|
||||
u64 LCN3[[name("ThirdLCN")]];
|
||||
u64 LCN4[[name("FourthLCN")]];
|
||||
$ = $+2;
|
||||
u8 checksumtype[[name("ChecksumType")]];
|
||||
u8 checksumoffset[[name("ChecksumOffset")]];
|
||||
u16 checksumlen[[name("CheckSumLength")]];
|
||||
$ = $+2;
|
||||
if(checksumtype == 2){
|
||||
u64 chksum[[comment("Crc64"),name("CRC64-CheckSum") ]];}
|
||||
else if(checksumtype == 1){
|
||||
u32 chksum[[comment("Crc32"),name("CRC32-CheckSum") ]];
|
||||
}
|
||||
u32 rem = this.parent.lenselfdescriptor - ($ - start);
|
||||
BYTE buff[rem];
|
||||
};
|
||||
|
||||
struct META_HEADERS {
|
||||
BLOCK Signature[[comment("Block Signature"), name("BlockSignature")]];
|
||||
u32 unk[[comment("Fixed Value 0x02"), name("Unknown")]];
|
||||
$ = $ + (0x8 + 0x10);
|
||||
u32 zero[[name("AlwaysZero")]];
|
||||
u32 volsig[[name("VolumeSignature")]];
|
||||
u128 blockNo[[comment("Most Recent Block"), name("PageRecency")]];
|
||||
u64 LCN1[[comment("MetaPage 1st LogicalClusterNumber"), name("FirstLCN")]];
|
||||
u64 LCN2[[comment("MetaPage 2nd LogicalClusterNumber"), name("SecondLCN")]];
|
||||
u64 LCN3[[comment("MetaPage 3rd LogicalClusterNumber"), name("ThirdLCN")]];
|
||||
u64 LCN4[[comment("MetaPage 4th LogicalClusterNumber"), name("FourthLCN")]];
|
||||
u64 _Objid;
|
||||
u64 ObjId;
|
||||
u64 tableidlo[[name("TableIdentifierHigh")]];
|
||||
u64 tableidhi[[name("TableIdentifierLow")]];
|
||||
|
||||
};
|
||||
|
||||
struct OFFSET_ENTRIES{
|
||||
u16 offset[[name("Offset")]];
|
||||
u16 unk[[name("Ignore")]];
|
||||
};
|
||||
|
||||
struct ATTRIBUTE {
|
||||
u64 LCN1[[name("FirstLCN")]];
|
||||
u64 LCN2[[name("SecondLCN")]];
|
||||
@@ -49,52 +79,129 @@ struct ATTRIBUTE {
|
||||
BYTE ZeroPadding[56][[name("Padding")]];
|
||||
};
|
||||
|
||||
enum NodeType : BYTE {
|
||||
InnerNode = 0x01,
|
||||
RootNode = 0x02,
|
||||
StreamNode = 0x03,
|
||||
};
|
||||
|
||||
struct INDEX_HEADER {
|
||||
u32 size[[name("DataStartOffset")]];
|
||||
u32 dataendoff[[name("DataAreaEndOffset")]];
|
||||
u32 freebuff[[name("FreeBuff")]];
|
||||
BYTE height[[name("Height")]];
|
||||
NodeType ntype[[name("NodeType")]];
|
||||
u16 unused1[[name("UnUsed")]];
|
||||
u32 keyindxoff[[name("KeyIndexOffset")]];
|
||||
u32 keycount[[name("KeysCount")]];
|
||||
u64 unused2[[name("UnUsed")]];
|
||||
u32 end[[name("KeyIndexEnd")]];
|
||||
u32 align[[name("Alignment")]];
|
||||
$ = this.parent.start_pos + 0x50 + this.parent.rootsize + keyindxoff;
|
||||
OFFSET_ENTRIES entries[keycount][[name("KeyEntries")]];
|
||||
|
||||
};
|
||||
|
||||
enum Flags : u16 {
|
||||
RightMost = 0x02,
|
||||
DeletedEntry = 0x04,
|
||||
StreamIndexEntry = 0x40,
|
||||
};
|
||||
|
||||
struct INDEX_ENTRY_STRUCTURE {
|
||||
u32 start_pos = $;
|
||||
u32 indxentlen[[name("IndxEntryLen")]];
|
||||
u16 keyoff[[name("KeyOffset")]];
|
||||
u16 keylen[[name("KeyLen")]];
|
||||
Flags flag[[name("Flags")]];
|
||||
u16 valoff[[name("ValOffset")]];
|
||||
u16 vallen[[name("ValLen")]];
|
||||
$ = start_pos + keyoff;
|
||||
char key[keylen][[name("Key")]];
|
||||
$ = start_pos + valoff;
|
||||
char value[vallen][[name("Value")]];
|
||||
$ = start_pos + indxentlen;
|
||||
};
|
||||
|
||||
struct ROOT_NODE{
|
||||
u32 start_pos = $;
|
||||
META_HEADERS pagehdr[[name("PageHeader")]];
|
||||
u32 rootsize[[name("RootSize")]];
|
||||
u16 fixed[[name("Fixed(0x28)")]];
|
||||
u16 unk1[[name("Unknown")]];
|
||||
u16 unk2[[name("Unknown")]];
|
||||
u16 unk3[[name("Unknown")]];
|
||||
u16 schema[[name("TableSchema")]];
|
||||
u16 unk4[[name("Unknown")]];
|
||||
u16 schemadup[[name("TableSchema")]];
|
||||
u16 unk5[[name("Unknown")]];
|
||||
u16 unk6[[name("Unknown")]];
|
||||
u16 unk7[[name("Unknown")]];
|
||||
u64 noofextends[[name("ExtendCount")]];
|
||||
u64 noofrows[[name("RowsCount")]];
|
||||
char comps[rootsize - ($ - start_pos) + 0x50][[name("Components")]];
|
||||
$ = (start_pos + 0x50 + rootsize);
|
||||
INDEX_HEADER indxhdr[[name("IndexHeader")]];
|
||||
// $ = start_pos + 0x50 + rootsize + indxhdr.keyindxoff;
|
||||
$ = (start_pos + 0x50 + rootsize + indxhdr.size);
|
||||
INDEX_ENTRY_STRUCTURE indxentrystruct[indxhdr.keycount][[name("IndexEntry")]];
|
||||
};
|
||||
|
||||
u32 keeptrack = 0;
|
||||
|
||||
struct EntryArray {
|
||||
u32 AttrOffsetEntry;
|
||||
struct GLOBALROOTNODE {
|
||||
u32 GlobalElemEntryOff;
|
||||
u32 prev = $;
|
||||
$ = (0x1000 * ($ / 0x1000));
|
||||
$ = $ + AttrOffsetEntry;
|
||||
$ = $ + GlobalElemEntryOff;
|
||||
keeptrack += 1;
|
||||
if (keeptrack == 1) {
|
||||
ATTRIBUTE ObjectTable;
|
||||
ATTRIBUTE ObjectIDTable;
|
||||
}
|
||||
else if (keeptrack == 2) {
|
||||
ATTRIBUTE UNKNOWN1;
|
||||
ATTRIBUTE MediumAllocatorTable;
|
||||
}
|
||||
else if (keeptrack == 3) {
|
||||
ATTRIBUTE UNKNOWN2;
|
||||
ATTRIBUTE ContainerAllocatorTable;
|
||||
}
|
||||
else if (keeptrack == 4) {
|
||||
ATTRIBUTE AttributeList;
|
||||
ATTRIBUTE SchemaTable;
|
||||
}
|
||||
else if (keeptrack == 5) {
|
||||
ATTRIBUTE DirectoryTree;
|
||||
ATTRIBUTE ParentChildTable[[comment("Parent Child Table")]];
|
||||
}
|
||||
else if (keeptrack == 6) {
|
||||
ATTRIBUTE UNKNOWN3;
|
||||
ATTRIBUTE ObjectIDDup;
|
||||
}
|
||||
else if (keeptrack == 7) {
|
||||
ATTRIBUTE UNKNOWN4;
|
||||
ATTRIBUTE BlockCountTable;
|
||||
}
|
||||
else if (keeptrack == 8) {
|
||||
ATTRIBUTE ContainerTable;
|
||||
u32 prev_pos = $;
|
||||
ROOT_NODE node1 @ (ContainerTable.LCN1 * clustersz)[[name("ContainerNode")]];
|
||||
$ = prev_pos;
|
||||
}
|
||||
else if (keeptrack == 9) {
|
||||
ATTRIBUTE ContainerTableDup;
|
||||
u32 prev_pos = $;
|
||||
ROOT_NODE node1 @ (ContainerTableDup.LCN1 * clustersz)[[name("ContainerDupNode")]];
|
||||
$ = prev_pos;
|
||||
}
|
||||
else if (keeptrack == 10) {
|
||||
ATTRIBUTE UNKNOWN5;
|
||||
ATTRIBUTE SchemaTableDup;
|
||||
}
|
||||
else if (keeptrack == 11) {
|
||||
ATTRIBUTE AllocatorLarge;
|
||||
ATTRIBUTE ContainerIndexTable;
|
||||
}
|
||||
else if (keeptrack == 12) {
|
||||
ATTRIBUTE UNKNOWN6;
|
||||
ATTRIBUTE IntegrityStateTable;
|
||||
}
|
||||
else if (keeptrack == 13) {
|
||||
ATTRIBUTE UNKNOWN7;
|
||||
ATTRIBUTE SmallAllocatorTable;
|
||||
u32 prev_pos = $;
|
||||
ROOT_NODE node1 @ (SmallAllocatorTable.LCN1 * clustersz)[[name("SmallAllocatorNode")]];
|
||||
$ = prev_pos;
|
||||
}
|
||||
$ = prev;
|
||||
};
|
||||
@@ -103,29 +210,31 @@ struct CHECKPOINT {
|
||||
META_HEADERS CheckPointMetaHeader[[name("FSPageMetaHeader")]];
|
||||
$ += (0x04);
|
||||
CheckPoint_REFS_Version ReFSVersion;
|
||||
u32 EntryOffset;
|
||||
u32 EntrySz[[name("EntrySize")]];
|
||||
u64 blockno[[name("BlockNumber")]];
|
||||
u32 offsetselfdescriptor[[comment("Self Descriptor Offset")]];
|
||||
u32 lenselfdescriptor[[comment("Self Descriptor Size"),name("SelfDescriptorSz")]];
|
||||
u64 blockno[[comment("Most Recent CheckPoint") , name("BlockNumber")]];
|
||||
u32 prev_pos = $;
|
||||
$ = ($ / clustersz) *clustersz + offsetselfdescriptor;
|
||||
SELF_DESCRIPTOR selfdes[[name("SelfDescriptor")]];
|
||||
$ = prev_pos;
|
||||
$ += (0x28);
|
||||
u32 NumOfEntries;
|
||||
EntryArray AttributeEntries[NumOfEntries];
|
||||
GLOBALROOTNODE GlobalRootNodes[NumOfEntries];
|
||||
$ += (0x08);
|
||||
u64 LCN1dup[[comment("Duplicate LCN of MetaPage of this block"), name("DupFirstLCN")]];
|
||||
u64 LCN2dup[[comment("Duplicate LCN of MetaPage of this block"), name("DupSecondLCN")]];
|
||||
u64 LCN3dup[[comment("Duplicate LCN of MetaPage of this block"), name("DupThirdLCN")]];
|
||||
u64 LCN4dup[[comment("Duplicate LCN of MetaPage of this block"), name("DupFourthLCN")]];;
|
||||
};
|
||||
|
||||
struct SUPERBLOCK {
|
||||
META_HEADERS SuperBlockMetaHeader[[name("FSPageMetaHeader")]];
|
||||
type::GUID GUID;
|
||||
$ = $ + (0x10 * 0x06);
|
||||
$ = $ + (0x10 * 0x01);
|
||||
u32 checkpointOffset[[name("CheckPointOffset")]];
|
||||
u32 noofcheckpoint[[name("NoOfCheckPointEntry")]];
|
||||
u32 offsetselfdescriptor[[name("SelfDescriptorOffset")]];
|
||||
u32 lenselfdescriptor[[name("SelfDescriptorLength")]];
|
||||
$ = $ + (0x10 * 0x04);
|
||||
u64 primarychekpoint[[name("PrimaryCheckPoint")]];
|
||||
u64 secondaychekpoint[[name("SecondaryCheckPoint")]];
|
||||
u64 LCN1dup[[name("DupFirstLCN")]];
|
||||
u64 LCN2dup[[name("DupSecondtLCN")]];
|
||||
u64 LCN3dup[[name("DupThirdLCN")]];
|
||||
u64 LCN4dup[[name("DupFourthLCN")]];
|
||||
SELF_DESCRIPTOR selfdes[[name("SelfDescriptor")]];
|
||||
};
|
||||
|
||||
struct VOLUME_BOOT_RECORD {
|
||||
@@ -141,22 +250,37 @@ struct VOLUME_BOOT_RECORD {
|
||||
ReFS_Version ReFSVersion;
|
||||
BYTE UnknownBuff[0x0e][[name("Unknown")]];
|
||||
u64 SerialNo[[name("SerialNumber")]];
|
||||
u64 BytesPerContainer[[name("BytesPerContainer")]];
|
||||
|
||||
};
|
||||
|
||||
struct REFS_FILE_SYSTEM {
|
||||
u64 checkVal = std::mem::read_unsigned($+3, 8);
|
||||
$ = 0;
|
||||
if(checkVal == FILESYSTEM::ReFS){
|
||||
VOLUME_BOOT_RECORD vbr @ 0x00[[name("VolumeBootRecord")]];
|
||||
SUPERBLOCK SuperBlock @ (0x1e * 0x1000);
|
||||
SUPERBLOCK SuperBlock1 @ (0x1e * 0x1000)[[name("SuperBlock1")]];
|
||||
u32 cluster_size = vbr.BytesPerSec * vbr.SectorPerCluster;
|
||||
|
||||
CHECKPOINT PrimaryCheckPoint @(SuperBlock.primarychekpoint * 0x1000);
|
||||
CHECKPOINT PrimaryCheckPoint @(SuperBlock1.primarychekpoint * cluster_size)[[name("PrimaryCheckPoint1")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT SecondaryCheckPoint @(SuperBlock.secondaychekpoint * 0x1000);
|
||||
CHECKPOINT SecondaryCheckPoint @(SuperBlock1.secondaychekpoint * cluster_size)[[name("SecondaryCheckPoint1")]];
|
||||
|
||||
SUPERBLOCK SuperBlock2 @(((vbr.TotalNoOfSectors / vbr.SectorPerCluster) - 3) * cluster_size)[[name("SuperBlock2")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT PrimaryCheckPoint2 @(SuperBlock2.primarychekpoint * cluster_size)[[name("PrimaryCheckPoint2")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT SecondaryCheckPoint2 @(SuperBlock2.secondaychekpoint * cluster_size)[[name("SecondaryCheckPoint2")]];
|
||||
|
||||
SUPERBLOCK SuperBlock3 @(((vbr.TotalNoOfSectors / vbr.SectorPerCluster) - 2) * cluster_size)[[name("SuperBlock3")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT PrimaryCheckPoint3 @(SuperBlock3.primarychekpoint * cluster_size)[[name("PrimaryCheckPoint3")]];
|
||||
keeptrack = 0;
|
||||
CHECKPOINT SecondaryCheckPoint3 @(SuperBlock3.secondaychekpoint * cluster_size)[[name("SecondaryCheckPoint3")]];
|
||||
}
|
||||
else{
|
||||
break;
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
u32 clustersz = std::mem::read_unsigned($ + 0x20, $+4) * std::mem::read_unsigned($ + 0x24, $+4);
|
||||
REFS_FILE_SYSTEM ReFSFileSystem @0x00;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma description TODO
|
||||
|
||||
import std.core;
|
||||
import std.io;
|
||||
import std.mem;
|
||||
|
||||
75
patterns/wintec_tes.hexpat
Normal file
75
patterns/wintec_tes.hexpat
Normal file
@@ -0,0 +1,75 @@
|
||||
// Wintec TES file
|
||||
//
|
||||
// Wintec produced small GPS-Loggers that created TES files. Each file
|
||||
// is a series of timestamps and coordinates. The format is exceedingly
|
||||
// simple. The same 16 byte struct is repeated from start to finish.
|
||||
//
|
||||
// This would be a valid line:
|
||||
// 01 00 31 F9 DE 60 A0 B1 9C 16 A0 AD 45 0E 88 00
|
||||
// ----- ----------- ----------- ----------- -----
|
||||
// flags timestamp latitude longitude altitude
|
||||
//
|
||||
// The line decodes to:
|
||||
// flag 0x01 -> split mark (start of a new file)
|
||||
// timestamp 2024-03-15 15:36:49
|
||||
// latitude 37.936784°
|
||||
// longitude 23.944746°
|
||||
// altitude 136m
|
||||
//
|
||||
// Made with help from a (since deleted) GPSBabel definition
|
||||
// https://github.com/GPSBabel/gpsbabel/blob/gpsbabel_1_8_0/wintec_tes.cc
|
||||
|
||||
#include "std/mem.pat"
|
||||
#include "std/string.pat"
|
||||
|
||||
using WBTTimestamp;
|
||||
|
||||
// helper to format latitude and longitude in a human-readable form
|
||||
// values are stored in an s32, but are actually scaled 1e-7 degrees.
|
||||
fn decimalDegrees(s32 input) {
|
||||
return double(input)/10000000;
|
||||
};
|
||||
|
||||
// same as above, but outputs a string for readability
|
||||
fn stringDegrees(s32 input) {
|
||||
return std::format("{:f}°", double(input)/10000000);
|
||||
};
|
||||
|
||||
// create the standard iso8601 format from any timestamp
|
||||
fn iso8601(WBTTimestamp input) {
|
||||
return std::format("20{:02d}-{:02d}-{:02d}T{:02d}:{:02d}:{:02d}Z",input.year, input.month, input.day, input.hours, input.minutes, input.seconds);
|
||||
};
|
||||
|
||||
|
||||
// This 16 bit field is barely used. Only these two are known.
|
||||
bitfield WBTFlags {
|
||||
split: 1 [[comment("start of a new file")]];
|
||||
waypoint: 1 [[comment("waypoint button pressed")]];
|
||||
padding: 14;
|
||||
};
|
||||
|
||||
|
||||
// The files store the timestamp in a somewhat uncommon 32 bit format
|
||||
bitfield WBTTimestamp {
|
||||
seconds: 6;
|
||||
minutes: 6;
|
||||
hours: 5;
|
||||
day: 5;
|
||||
month: 4;
|
||||
year: 6;
|
||||
} [[format("iso8601")]];
|
||||
|
||||
|
||||
// This is what parses each line of the file. From the very beginning to the very end,
|
||||
// all data is made up of this 16 byte struct.
|
||||
struct WBTLine {
|
||||
WBTFlags flags;
|
||||
WBTTimestamp timestamp [[color("ff0000")]];
|
||||
s32 lat [[color("007FFF"), format("stringDegrees")]];
|
||||
s32 lon [[color("7F00FF"), format("stringDegrees")]];
|
||||
s16 alt [[color("0000FF")]];
|
||||
} [[hex::visualize("coordinates", decimalDegrees(lat), decimalDegrees(lon))]];
|
||||
|
||||
|
||||
// parsing that whole file start to finish:
|
||||
WBTLine lines[while(!std::mem::eof())] @ 0x00;
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma author WerWolv
|
||||
#pragma description Nintendo Switch XCI cardridge ROM
|
||||
#pragma description Nintendo Switch XCI cartridge ROM
|
||||
|
||||
import std.core;
|
||||
|
||||
|
||||
157
patterns/xgspak.hexpat
Normal file
157
patterns/xgspak.hexpat
Normal file
@@ -0,0 +1,157 @@
|
||||
import std.mem;
|
||||
import std.core;
|
||||
import type.time;
|
||||
import type.magic;
|
||||
|
||||
//By LolHacksRule
|
||||
|
||||
/*
|
||||
XGSPAK VX only works with games using XGS Engine VX (I think First Touch Games use multiple?), using different versions with them is likely a bad idea as devs can only use one of the three.
|
||||
XGSPAKV1 can be used with ZLib or Raw content.
|
||||
Works nearly perfectly on PAKs WITH and WITHOUT folders.
|
||||
*/
|
||||
|
||||
/*
|
||||
TODO:
|
||||
Double check XGSPAKV0 from NFS Wii, it's probably similar?
|
||||
Fix FTG V1 PAK if possible, uses V0 layout
|
||||
*/
|
||||
|
||||
/*
|
||||
Format info I used:
|
||||
https://aluigi.altervista.org/bms/angry_birds_go.bms
|
||||
https://aluigi.altervista.org/bms/angry_birds_starwars.bms
|
||||
https://aluigi.altervista.org/bms/xpk2.bms
|
||||
https://aluigi.altervista.org/bms/dls20.bms
|
||||
*/
|
||||
|
||||
enum PakVersion : u8
|
||||
{
|
||||
Version0, //NFS Wii/Trilogy 3DS/DLS
|
||||
Version1, //ABGO V1/ABTF, AB Console Ports
|
||||
Version2 //ABGO V2+
|
||||
};
|
||||
|
||||
enum CompressionType : u32
|
||||
{
|
||||
Raw, //NFS Wii/Trilogy 3DS/DLS
|
||||
Zlib, //ABGO V1/ABTF, AB Console Ports
|
||||
LZ4 //ABGO V2+
|
||||
};
|
||||
|
||||
struct XGSPakHeader
|
||||
{
|
||||
if (std::mem::read_unsigned($, 1) > 2) //Assume BE
|
||||
{
|
||||
std::core::set_endian(std::mem::Endian::Big);
|
||||
char magic[3];
|
||||
PakVersion ver;
|
||||
}
|
||||
else
|
||||
{
|
||||
PakVersion ver;
|
||||
char magic[3];
|
||||
}
|
||||
u32 folders;
|
||||
u32 files; //-1 bcz init folder
|
||||
u32 fileContentTableSize;
|
||||
if (ver == PakVersion::Version2)
|
||||
{
|
||||
CompressionType compressionType;
|
||||
}
|
||||
};
|
||||
|
||||
struct XGSPakFolderBase
|
||||
{
|
||||
if (Head.ver == PakVersion::Version0)
|
||||
{
|
||||
char *name[] : u32[[pointer_base("offToStringTable")]];
|
||||
u32 filesInFolder;
|
||||
u32 subfolders;
|
||||
u32 filesPos;
|
||||
u32 foldersPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Head.magic == "XPK")
|
||||
{
|
||||
u32 dummy;
|
||||
char *name[] : u32 [[pointer_base("offToStringTable")]];
|
||||
u32 dummy2;
|
||||
u32 filesPos;
|
||||
u32 dummy3;
|
||||
u32 foldersPos;
|
||||
u32 filesInFolder;
|
||||
u32 subfolders;
|
||||
}
|
||||
else
|
||||
{
|
||||
//u64 name;
|
||||
char *name[] : u64 [[pointer_base("offToStringTable")]];
|
||||
u64 filesPos;
|
||||
u64 foldersPos;
|
||||
u32 filesInFolder;
|
||||
u32 subfolders;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct XGSPakContentMeta
|
||||
{
|
||||
if (Head.ver == PakVersion::Version0)
|
||||
{
|
||||
char *name[] : u32 [[pointer_base("offToStringTable")]];
|
||||
u32 decompFileSize;
|
||||
u32 fileOff;
|
||||
u32 compressed;
|
||||
type::time32_t timestamp;
|
||||
u32 compFileSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Head.magic == "XPK")
|
||||
{
|
||||
u32 dummy;
|
||||
char *name[] : u32 [[pointer_base("offToStringTable")]];
|
||||
u32 decompFileSize;
|
||||
u32 fileOff;
|
||||
u32 compressed;
|
||||
type::time32_t timestamp;
|
||||
u32 compFileSize;
|
||||
u32 dummy2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//u64 name;
|
||||
char *name[] : u64 [[pointer_base("offToStringTable")]];
|
||||
u32 decompFileSize;
|
||||
u32 fileOff;
|
||||
u32 compressed;
|
||||
type::time32_t timestamp;
|
||||
u64 compFileSize;
|
||||
}
|
||||
}
|
||||
if (compressed)
|
||||
{
|
||||
u8 compressedFile[compFileSize] @ fileOff;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 file[decompFileSize] @ fileOff;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
XGSPakHeader Head @ $;
|
||||
//u32 offToStringTable_old = ((0x20*Head.folders)+(0x20*Head.files))+sizeof (Head); //Finicky but it works
|
||||
|
||||
fn offToStringTable(u128 offset) {
|
||||
match (Head.ver)
|
||||
{
|
||||
(PakVersion::Version0): return ((0x14*Head.folders)+(0x18*Head.files))+sizeof (Head);
|
||||
(PakVersion::Version1 | PakVersion::Version2): return ((0x20*Head.folders)+(0x20*Head.files))+sizeof (Head);
|
||||
}
|
||||
};
|
||||
|
||||
XGSPakFolderBase FolderBase[Head.folders] @ $;
|
||||
XGSPakContentMeta ContentMeta[Head.files] @ $;
|
||||
113
patterns/xgstexture.hexpat
Normal file
113
patterns/xgstexture.hexpat
Normal file
@@ -0,0 +1,113 @@
|
||||
import type.magic;
|
||||
//By LolHacksRule
|
||||
|
||||
enum XGSPlatform : u8
|
||||
{
|
||||
WIN32_OR_ANDROID, //Android sure but Win32 p much was only used in EOP (Edge of Perception)?
|
||||
PS3, //PlayStation 3,
|
||||
iOS_OR_PSP, //iPhone/iPad or PSP (confusion, I think PSP was renamed to iOS but idk)
|
||||
REVOLUTION, //Nintendo Wii
|
||||
XENON, //Xbox 360
|
||||
iOS_IPHONE_LEGACY, //Legacy iPhone/iPad since ABGO V1
|
||||
CTR, //Nintendo 3DS
|
||||
PSP2, //PlayStation Vita
|
||||
OSX, //Mac OS X
|
||||
ANDROID_LEGACY, //Definitely Android since ABGO V1
|
||||
METRO_OR_WINSTORE, //WP7?
|
||||
CAFE, //Wii U
|
||||
BLACKBERRY,
|
||||
OGL, //?
|
||||
ORBIS, //PlayStation 4
|
||||
DURANGO, //Xbox One
|
||||
WINPHONE, //PCOGL
|
||||
WINPHONE_LEGACY, //WP8
|
||||
APPLE_TV, //Apple TV
|
||||
};
|
||||
|
||||
enum XGSTextureFormat : u16
|
||||
{
|
||||
RGB565_SWIZZLED, //AB SW Console, Vita/PS3 uses no swizzle
|
||||
RGB565, //ABTF but supported in GO
|
||||
RGBA4444, //On PS3 this is BGRA8888/ARGB8888?
|
||||
RGBA4444_2_OR_RGBA8888_OR_LA88, //On PS4/X360/XENON this is ARGB8888, on Win this is RGBA8888, on current Android this is RGBA4444 OR RGBA8888 (ABTF2017 Chi?), on caFe/Wii U or legacy iOS this is RGBA8888, on current iOS it's both, on Orbis/PS4 it's BGRA8888, on Wii it's linear indexed 32BPP LA88 with BC swizzle, on legacy Android or ABGO v101 crashes
|
||||
RGBA8888, //On GO v101, nothing is read
|
||||
PALLETIZED_RGBA5A3, //Palletized RGB5A3, AB SW Wii, doesn't crash in EOP or ABGO v101 (Android) but doesn't return any data
|
||||
//6, //crash on EOP and PS3 but not ABGO v101 but doesn't return any data
|
||||
//7, //crash on EOP and PS3 but not ABGO v101 but doesn't return any data
|
||||
AL88_OR_DXT1_OR_RGB565 = 8, //On Xbox 360/PS3 this is usually DXT, on Wii U, RGBA8888, on Android, this is usually AL88 unless the format is DXT, on 3DS, swizzled RGB565, on EOP, crash, on ABGO v101, nothing
|
||||
UNKNOWN_DXT, //DXT3? no XGS games so far use this one, crashes on EOP, on ABGO v101, nothing
|
||||
DXT5_SWIZZLED, //ABSW PS3/WinPhone/Legacy Android only? on ABGO v101, nothing
|
||||
PVR_UNK, //2BPP no alpha? Crashes in ABGO v101
|
||||
RGB888, //Greyscale? unused, crashes in EOP but works in ABGO v101
|
||||
AL88,
|
||||
//14, //8BPP something? Crash on EOP and PS3, on ABGO v101, nothing
|
||||
PVRTC_2BPP_RGBA = 15, //Crash on PS3, on ABGO v101, nothing
|
||||
PVRTC_4BPP_RGBA, //Crash on PS3 or is this 2bppRGBA, on ABGO v101, nothing
|
||||
PVRTC_4BPP_RGBA_2, //May need to swap these two, crash on PS3, on ABGO v101, nothing
|
||||
PVRTC_4BPP_RGBA_3, //Crashes on EOP and PS3, on ABGO v101, nothing
|
||||
//19, //Crash on PS3 and EOP, on ABGO v101, nothing
|
||||
//20, //Crash on PS3 and EOP, on ABGO v101, nothing
|
||||
//21, //Crash on PS3 and EOP, on ABGO v101, nothing
|
||||
RG88_OR_GR88 = 22, //Unused. On PS3, it's unswizzled GR88, crashes on EOP, on ABGO v101, nothing
|
||||
L4, //Unused, crashes on EOP, on ABGO v101, nothing
|
||||
DXT1_OR_ETC1, //On Android this is usually DXT1, old Android has this DXT1 swizzled, null on PS3, crash on EOP, on ABGO v101, nothing
|
||||
LA44, //Crash on EOP, on ABGO v101, nothing
|
||||
DXT5, //Crash on EOP, on ABGO v101, nothing
|
||||
//?, //Crash on EOP, on ABGO v101, nothing, note starting here PS3 crashes
|
||||
//?, //Crash on EOP, on ABGO v101, nothing
|
||||
PVRTC_2BPP_RGBA_2 = 29, //on ABGO v101, nothing
|
||||
PVRTC_4BPP_RGBA_V2, //on ABGO v101, nothing
|
||||
PVRTC_4BPP_RGB_V3, //on ABGO v101, nothing
|
||||
//? //on ABGO v101, nothing
|
||||
//? //on ABGO v101, nothing
|
||||
//? //on ABGO v101, nothing
|
||||
ETC2_RGB = 35, //on ABGO v101, nothing
|
||||
//? //on ABGO v101, nothing
|
||||
ATC = 37, //BC Swizzled, on ABGO v101, nothing
|
||||
//ATC_RGBA_Exp, //? on ABGO v101, nothing
|
||||
ATCA_Interpolated = 39, //BC Swizzled, on ABGO v101, nothing
|
||||
//? //on ABGO v101, nothing
|
||||
RGBA5A3 = 250, //on ABGO v101, nothing
|
||||
CMPR, //CMPR/DXT1 with different blocks, nothing on ABGO v101
|
||||
ETC2_RGB_2_OR_ETC1, //On CTR, ETC1 Z-Order 1, works on ABGO v101 (ETC1)
|
||||
ETC1_RGB_SPLITALPHA, //CTR only, nothing on ABGO v101
|
||||
ATC_RGB, //Confirm, nothing on ABGO v101
|
||||
ATC_RGBA_EXPLICIT, //Prob nothing on ABGO v101
|
||||
ATC_RGBA_INTERPOLATED, //Prob nothing on ABGO v101
|
||||
XGSTEXFMT_257, //Defined in ABGO v101 but idk what it is
|
||||
//258-263 are unknown
|
||||
DXT1_EXT = 264, //DXT1 EXT (?)
|
||||
DXT3_EXT, //DXT3 EXT (?)
|
||||
DXT5_EXT, //DXT1 EXT (?)
|
||||
};
|
||||
|
||||
bitfield XGSTextureFlags
|
||||
{
|
||||
Mips : 2; Twiddle : 2; Normal : 2; Border : 2; CubeMap : 2; MipMapDebugColoring : 2; Volume3D : 2; AlphaChannelPresent : 2; VFlip : 2;
|
||||
//Idk how this works
|
||||
};
|
||||
|
||||
struct XGSTextureHeader
|
||||
{
|
||||
type::Magic"XGST"> magic;
|
||||
u8 dataOffset;
|
||||
XGSPlatform compilationPlatform; //Definitely platform, this has no harm when modifying (except in Edge of Perception) but does help with knowing platform specific compressions, usually
|
||||
u16 headerSize; //?
|
||||
//byte dmy;
|
||||
u8 numMips;
|
||||
//? start
|
||||
XGSTextureFlags flags;
|
||||
//? end
|
||||
//char format[4];
|
||||
XGSTextureFormat format;
|
||||
u16 numColors; //Modifying this seems to have no known effect but idk
|
||||
u16 width;
|
||||
u16 height;
|
||||
u16 width2; //No use modifying
|
||||
u16 height2; //No use modifying
|
||||
u32 paletteSize; //Modifying this affects the game badly, take care
|
||||
u32 dataSize;
|
||||
};
|
||||
|
||||
XGSTextureHeader Head @ $;
|
||||
u8 Texture[Head.dataSize] @ $;
|
||||
@@ -65,7 +65,7 @@ int main(int argc, char **argv) {
|
||||
if (!runtime.executeString(patternFile.readString(), "<Source Code>")) {
|
||||
fmt::print("Error during execution!\n");
|
||||
|
||||
if (const auto &hardError = runtime.getError(); hardError.has_value())
|
||||
if (const auto &hardError = runtime.getEvalError(); hardError.has_value())
|
||||
fmt::print("Hard error: {}:{} - {}\n\n", hardError->line, hardError->column, hardError->message);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
|
||||
@@ -39,8 +39,13 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Setup Pattern Language Runtime
|
||||
pl::PatternLanguage runtime;
|
||||
bool hasDescription = false;
|
||||
{
|
||||
constexpr auto DummyPragmaHandler = [](const auto&, const auto&){ return true; };
|
||||
auto DescPragmaHandler = [&hasDescription](const auto&, const auto&){
|
||||
hasDescription = true;
|
||||
return true;
|
||||
};
|
||||
|
||||
runtime.setDataSource(0x00, testFile.getSize(),
|
||||
[&](pl::u64 address, pl::u8 *data, size_t size) {
|
||||
@@ -51,6 +56,7 @@ int main(int argc, char **argv) {
|
||||
runtime.setDangerousFunctionCallHandler([]{ return true; });
|
||||
runtime.setIncludePaths({ includePath });
|
||||
runtime.addPragma("MIME", DummyPragmaHandler);
|
||||
runtime.addPragma("description", DescPragmaHandler);
|
||||
runtime.addDefine("__PL_UNIT_TESTS__");
|
||||
|
||||
runtime.setLogCallback([](auto level, const std::string &message) {
|
||||
@@ -71,11 +77,11 @@ int main(int argc, char **argv) {
|
||||
if (!runtime.executeString(patternFile.readString(), "<Source Code>")) {
|
||||
fmt::print("Error during execution!\n");
|
||||
|
||||
if (const auto &hardError = runtime.getError(); hardError.has_value())
|
||||
if (const auto &hardError = runtime.getEvalError(); hardError.has_value())
|
||||
fmt::print("Hard error: {}:{} - {}\n\n", hardError->line, hardError->column, hardError->message);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return hasDescription ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
BIN
tests/patterns/test_data/ani.hexpat.ani
Normal file
BIN
tests/patterns/test_data/ani.hexpat.ani
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/dted.hexpat.dt0
Normal file
BIN
tests/patterns/test_data/dted.hexpat.dt0
Normal file
Binary file not shown.
BIN
tests/patterns/test_data/gguf.hexpat.gguf
Normal file
BIN
tests/patterns/test_data/gguf.hexpat.gguf
Normal file
Binary file not shown.
Reference in New Issue
Block a user