From bf56d4ff49d7c143fa2f042f1e2486c0f9012a2b Mon Sep 17 00:00:00 2001 From: bake Date: Mon, 13 Jan 2025 21:21:05 +0100 Subject: [PATCH] patterns: Add veado pattern (#339) * Add veado pattern * Add veado to README * Add veado example file --- README.md | 1 + patterns/veado.hexpat | 182 ++++++++++++++++++++ tests/patterns/test_data/veado.hexpat.veado | Bin 0 -> 4854 bytes 3 files changed, 183 insertions(+) create mode 100644 patterns/veado.hexpat create mode 100644 tests/patterns/test_data/veado.hexpat.veado diff --git a/README.md b/README.md index f0f2424..2c6ee0d 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | UF2 | | [`patterns/uf2.hexpat`](patterns/uf2.hexpat) | [USB Flashing Format](https://github.com/microsoft/uf2) | | VBMeta | | [`patterns/vbmeta.hexpat`](patterns/vbmeta.hexpat) | Android VBMeta image | | VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files | +| VEADO | | [`patterns/veado.hexpat`](patterns/veado.hexpat) | veadotube mini avatar file | | VGM | | [`patterns/vgm.hexpat`](patterns/vgm.hexpat) | VGM (Video Game Music) sound log | | VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format | | WAV | `audio/x-wav` | [`patterns/wav.hexpat`](patterns/wav.hexpat) | RIFF header, WAVE header, PCM header | diff --git a/patterns/veado.hexpat b/patterns/veado.hexpat new file mode 100644 index 0000000..6ba7f64 --- /dev/null +++ b/patterns/veado.hexpat @@ -0,0 +1,182 @@ +#pragma author bake +#pragma description veadotube mini avatar file + +import std.mem; +import std.io; + +struct varint { + u8 value; +}; + +struct String { + varint length; + char string[length.value]; +}; + +struct Header { + char magic[9]; +}; + +struct Meta { + String software; + String credits; + String description; +}; + +enum EffectFlag : u8 { + Active = 0x1, + UsePreset = 0x2, + UsePresetChunk = 0x4, +}; + +struct Effect { + String effect_id; + EffectFlag flag; + if (u8(flag) & EffectFlag::UsePresetChunk) { + u32 chunk_id; + } + if (u8(flag) & EffectFlag::UsePreset) { + String preset_id; + } + varint num_values; + double values[num_values.value]; +}; + +struct Effects { + varint num_effects; + Effect effects[num_effects.value]; +}; + +enum StateFlag : u32 { + Pixelated = 0x1, + Blink = 0x2, + Start = 0x4, +}; + +struct Signal { + String source; + String name; +}; + +enum ShortcutMode : char { + Press = "PRES", + Release = "RLSE", + WhilePressed = "PRED", +}; + +struct Msta { + String name; + StateFlag state; + u32 thumbnail_closed_mouth; + u32 thumbnail_open_mouth; + u32 thumbnail_blinking_closed_mouth; + u32 thumbnail_blinking_open_mouth; + u32 closed_mouth; + u32 open_mouth; + u32 blinking_closed_mouth; + u32 blinking_open_mouth; + double blink_duration; + double min_blink_interval; + double max_blink_interval; + Effects closed_mouth_effects; + Effects open_mouth_effects; + Effects on_open_mouth_effects; + Effects on_close_mouth_effects; + varint num_signals; + Signal signals[num_signals.value]; + char shortcut_mode[4]; +}; + +struct AsfdMetadata { + char type[4]; + varint num_metadata; + u8 metadata[num_metadata.value]; +}; + +struct AsfdEntry { + String entry_name; + u32 chunk_id; + varint num_metadata; + AsfdMetadata metadata[num_metadata.value]; +}; + +struct Asfd { + char root_code[4]; + AsfdEntry entries[]; +}; + +struct Thmb {}; + +struct AimgFrame { + u32 chunk_id; + s32 offset_x; + s32 offset_y; + double duration; +}; + +struct Aimg { + u32 width; + u32 height; + varint num_frames; + if (num_frames.value > 1) { + varint num_loops; + } + AimgFrame frames[num_frames.value]; +}; + +struct Abmp { + u32 width; + u32 height; + char format[4]; + u32 num_as; + u32 num_rs; + u32 num_gs; + u32 num_bs; + if (format == "VDD." && num_as < 0xffffff00) { + u32 _as[num_as]; + } + if (format == "VDD." && num_rs < 0xffffff00) { + u32 _rs[num_rs]; + } + if (format == "VDD." && num_gs < 0xffffff00) { + u32 _gs[num_gs]; + } + if (format == "VDD." && num_bs < 0xffffff00) { + u32 _bs[num_bs]; + } + if (format == "RAW.") { + u32 data[]; + } +}; + +struct Chunk { + u32 id; + char type[4]; + u32 length; + if (type == "META") { + Meta meta; + } else if (type == "MLST") { + u32 chunk_ids[length / 4]; + } else if (type == "MSTA") { + Msta msta; + } else if (type == "ASFD") { + u64 startAddress = $; + Asfd asfd; + AsfdEntry entries[while ($ - startAddress < length)]; + } else if (type == "THMB") { + Thmb thmb; + padding[length]; + } else if (type == "AIMG") { + Aimg aimg; + } else if (type == "ABMP") { + Abmp abmp; + padding[length - sizeof(abmp)]; + } else { + std::print("unknown type {}", type); + padding[length]; + break; + } +}; + +Header header @0x00; +Chunk data[while (!std::mem::eof())] @$; diff --git a/tests/patterns/test_data/veado.hexpat.veado b/tests/patterns/test_data/veado.hexpat.veado new file mode 100644 index 0000000000000000000000000000000000000000..aac2b9f07c7de32e4c96c4a777e520bc531e31c7 GIT binary patch literal 4854 zcmeHJk5^Oo6@MWN0yY#pQh`L*CO|zvm9`T! zSlV$`tv{ygwB4kgqTMJj**bUH0MPE{HGM>^%vqf z?SGXg)i*Y`w&Xo-+hlFBY^YJzF5oLxl}MB@owQ6pAG4ucELYb%EOoYgHgv^|8D9|< zGI9{*jAe#mqS$j4VyQYYBM~BXd6|9{<^uYu;_%EY>VAXc6er8|I^#w~c(2DXtWEA( zt=*NlzBBWTzP;@3d4Kr$&5CKQBf7+~pSZ@#_GIzr&;8~6(H(6wA5d?8v3m3Mo7+Y- z*Hm9hs!y(rwio^V^56EoReK}jw~aSu9m{Ed=VC>ivG6-jocgkvt~yXE z_K%HJ=cpz$U-Zvd{DpI`?~uQt@9etz9rN3EEo)F5obf_QTg=Y_s-1bu+w;}R{nK>2 zy8E+w9zHtHJ3ZxFyZzny*XIbcR|w}`|LlPLYVFp3<&H~_ol1YOIekvuz`=W0&)zjF z<-?knOD-;n={;;+{c52wzC<&uPkVo3)7m~EPX5|KBY;Un^Af7#By6nZvOsNjqiMZ`IY70Z~JxKvFx|9f8Ub!?W~=F z4|69*w|MH`{ru%;{531o{A)`e)Lf|NSAO%z4}1r;d%JUHy?*(^om3^S=o#tw z+qeD^4o^6O!QFoz_+F*uR!ZUiBiqtDd(Fot`t0|PmU;4bT1)ebUMk4_$lc()+Tr}= zcb~}ldDU~tQZje-+WFMSTW;p2TVt%cr{B(ee$l*@4IOEn3m?dsx&0e8ifV12;;%~m zvZ}>5Q?6wpvs`(JsQ*Q=c?%IjS8gbsg_$KDv!V}=uMd*xiVYPvK#a+aReF8iEsPiN zZ4Z7g;-|co+;!;<)z;zGK zxqN(bzhr^|m+bR;y#c#HaH}~xtwq7XGzli3C}j0RgTW-rJ}AT2fJ^PS4Ui|KO@;%e8jID_-4-Cccc{Zvsy~DgI zZ3}Ilo2~C6!*g|d-3NRSaPc4y;TC)YVh1AYA`cO4w+6l;G7@4Im62!gjTq==JCJ#n z7n3p78F1B_{QPXLkO29bKoSb%9leq72JXkbYv8iDMFpw`1v9w?(A zILSa8#GmK}+7ljP4cHB17*f#B2btCgDF_A9$o3IaJp9;z1o{y~kPGf9o>g;VPLDF>>AR~B-L-E)!bDc=r%S77S#OT5{%JwYiQdkXny&Y^r|+yt$UJqZ zn0-swJ<{1TKO$b(l9oD9Y&+Fcp0T(m^7+#EQs>c%^n!I~l-(+(_foe0Jy`0EPf_Gj zLXvOK%~)t6%HlGs0h+BO{gzlk_xSh_zSX9ic!W&4Y9(*LpA8iWRw_`w-}^O72zu) zNyf-3GGZqoYXoR_WD>lMh@dgp@d1?!>kq^?Z_<4X6F~6f1qA3vG>9;ibJ0Z1f@$<@ zke=Xa$uF>*bt7P=!S$m%5tkSTMgt)`iia2qn4<(IvK|c(!GqDHgL8a7dMou+sse@p z23VIv6il)P#bOL1ddxl8h07Ym8@B8|2w9k^4^y2* g>az3(P{mW1<