mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
patterns: Added new WebP and VGM patterns (#294)
* README: fix square bracket * patterns: add WebP pattern * patterns/dds: add x-dds mimetype * patterns: add vgm pattern * patterns/vgm: remove old pointer * patterns/protobuf: fix field number handling * patterns/protobuf: add .pb file extension * patterns/uf2: updating the family IDs again * patterns/png: add cHRM and tIME chunks * patterns/png: whoops, old description snuck back in * new quantized-mesh pattern * add quantized-mesh to README, implement oct16 decoding
This commit is contained in:
248
patterns/vgm.hexpat
Normal file
248
patterns/vgm.hexpat
Normal file
@@ -0,0 +1,248 @@
|
||||
#pragma author applecuckoo
|
||||
#pragma description VGM (Video Game Music) sound log
|
||||
|
||||
#pragma endian little
|
||||
|
||||
import type.magic;
|
||||
import std.string;
|
||||
import std.io;
|
||||
|
||||
u32 versionValue;
|
||||
u32 gd3TagPos;
|
||||
u32 chpClkBase;
|
||||
u32 chpVolBase;
|
||||
|
||||
// note: the versionValue variable exists to help check which fields exist and which don't, otherwise the actual log data would show up as part of the header.
|
||||
|
||||
bitfield VGMVersion {
|
||||
bugfix : 4;
|
||||
minor : 4;
|
||||
major : 24;
|
||||
|
||||
versionValue = major * 100 + minor * 10 + bugfix;
|
||||
|
||||
} [[format("format_VGMVersion")]];
|
||||
|
||||
fn format_VGMVersion(auto version) {
|
||||
return std::format("{}.{}{}", version.major, version.minor, version.bugfix);
|
||||
};
|
||||
|
||||
bitfield SN76489Flags {
|
||||
frequency : 1;
|
||||
negateOutput : 1;
|
||||
GameGearStereo : 1;
|
||||
clockDiv : 1;
|
||||
XNORNoiseMode : 1;
|
||||
padding : 3;
|
||||
};
|
||||
|
||||
bitfield AY8910Flags {
|
||||
legacyOutput : 1;
|
||||
singleOutput : 1;
|
||||
discreteOutput : 1;
|
||||
RAWOutput : 1;
|
||||
YMclockDivLow : 1;
|
||||
padding : 3;
|
||||
};
|
||||
|
||||
bitfield OKIM6258Flags {
|
||||
clockDiv : 2;
|
||||
ADPCMsel : 1;
|
||||
outputBitDepth : 1;
|
||||
padding : 4;
|
||||
};
|
||||
|
||||
bitfield K054539Flags {
|
||||
reverseStereo : 1;
|
||||
disableReverb : 1;
|
||||
KeyOnUpdate : 1;
|
||||
padding : 5;
|
||||
};
|
||||
|
||||
enum AY8190Type : u8 {
|
||||
AY8910,
|
||||
AY8912,
|
||||
AY8913,
|
||||
AY8914,
|
||||
YM2149 = 0x10,
|
||||
YM3439,
|
||||
YMZ284,
|
||||
YMZ294,
|
||||
};
|
||||
|
||||
enum C140Type : u8 {
|
||||
C140_NamcoSystem2,
|
||||
C140_NamcoSystem21,
|
||||
ASIC219_NamcoNA,
|
||||
};
|
||||
|
||||
struct Gd3 {
|
||||
type::Magic<"Gd3 "> ident;
|
||||
VGMVersion version;
|
||||
u32 Gd3Length;
|
||||
std::string::NullString16 trackNameEng;
|
||||
std::string::NullString16 trackNameOriginal;
|
||||
std::string::NullString16 gameNameEng;
|
||||
std::string::NullString16 gameNameOriginal;
|
||||
std::string::NullString16 sysNameEng;
|
||||
std::string::NullString16 sysNameOriginal;
|
||||
std::string::NullString16 trackAuthorEnglish;
|
||||
std::string::NullString16 trackAuthorOriginal;
|
||||
std::string::NullString16 gameReleaseDate;
|
||||
std::string::NullString16 VGMConverter;
|
||||
std::string::NullString16 Notes;
|
||||
};
|
||||
|
||||
struct baseHeader {
|
||||
type::Magic<"Vgm "> ident;
|
||||
u32 eofOffset;
|
||||
VGMVersion version;
|
||||
u32 SN76489_clk;
|
||||
u32 YM2413_clk;
|
||||
gd3TagPos = $;
|
||||
u32 Gd3Offset;
|
||||
u32 sampleCount;
|
||||
u32 loopOffset;
|
||||
u32 loopSamples;
|
||||
};
|
||||
|
||||
struct Header : baseHeader {
|
||||
if (versionValue >= 101) {
|
||||
u32 rate;
|
||||
} if (versionValue >= 110) {
|
||||
u16 SN76489_feedback;
|
||||
u8 SN76489_shift_width;
|
||||
} if (versionValue >= 151) {
|
||||
SN76489Flags snflags;
|
||||
} else {
|
||||
padding[1];
|
||||
} if (versionValue >= 110) {
|
||||
u32 YM2612_clk;
|
||||
u32 YM2151_clk;
|
||||
} if (versionValue >= 150) {
|
||||
u32 VGMOffset;
|
||||
} if (versionValue >= 151) {
|
||||
u32 SegaPCM_clk;
|
||||
u32 SegaPCM_reg;
|
||||
u32 RF5C68_clk;
|
||||
u32 YM2203_clk;
|
||||
u32 YM2608_clk;
|
||||
u32 YM2610_clk;
|
||||
u32 YM3812_clk;
|
||||
u32 YM3526_clk;
|
||||
u32 Y8950_clk;
|
||||
u32 YMF262_clk;
|
||||
u32 YMF278B_clk;
|
||||
u32 YMF271_clk;
|
||||
u32 YMZ280B_clk;
|
||||
u32 RF5C164_clk;
|
||||
u32 PWM_clk;
|
||||
u32 AY8910_clk;
|
||||
AY8190Type AY8910_type;
|
||||
AY8910Flags AY8910_flags;
|
||||
u8 YM2203_flags;
|
||||
u8 YM2608_flags;
|
||||
} if (versionValue >= 160) {
|
||||
u8 volumeMod;
|
||||
padding[1];
|
||||
u8 loopBase;
|
||||
} else {
|
||||
padding[3];
|
||||
} if (versionValue >= 151) {
|
||||
u8 loopMod;
|
||||
} if (versionValue >= 161) {
|
||||
u32 DMG_clk;
|
||||
u32 APU_clk;
|
||||
u32 MultiPCM_clk;
|
||||
u32 uPD7759_clk;
|
||||
u32 OKIM6258_clk;
|
||||
OKIM6258Flags OKIM6258_flags;
|
||||
K054539Flags K054539_flags;
|
||||
C140Type C140_type;
|
||||
padding[1];
|
||||
u32 OKIM6295_clk;
|
||||
u32 K051649_clk;
|
||||
u32 K054539_clk;
|
||||
u32 HuC6280_clk;
|
||||
u32 C140_clk;
|
||||
u32 K053260_clk;
|
||||
u32 Pokey_clk;
|
||||
u32 QSound_clk;
|
||||
} if (versionValue >= 171) {
|
||||
u32 SCSP_clk;
|
||||
} else {
|
||||
padding[4];
|
||||
} if (versionValue >= 170) {
|
||||
u32 extraHeaderOffset;
|
||||
} if (versionValue >= 171) {
|
||||
u32 WonderSwan_clk;
|
||||
u32 VSU_clk;
|
||||
u32 SAA1099_clk;
|
||||
u32 ES5503_clk;
|
||||
u32 ES5005_clk;
|
||||
u8 ES5503_ch;
|
||||
u8 ES5505_ch;
|
||||
u8 C352_clockDiv;
|
||||
padding[1];
|
||||
u32 X1_010_clk;
|
||||
u32 C352_clk;
|
||||
u32 GA20_clk;
|
||||
} if (versionValue > 172) {
|
||||
u32 Mikey_clk;
|
||||
}
|
||||
};
|
||||
|
||||
struct chpClkEntry {
|
||||
u8 chpID;
|
||||
u32 chpClk;
|
||||
};
|
||||
|
||||
struct chpClkHeader {
|
||||
u8 entryCount;
|
||||
chpClkEntry entries[entryCount];
|
||||
};
|
||||
|
||||
bitfield chpVolume {
|
||||
volume : 15;
|
||||
absoluteRelative : 1;
|
||||
};
|
||||
|
||||
struct chpVolEntry {
|
||||
u8 chpID;
|
||||
u8 flags;
|
||||
chpVolume chpVol;
|
||||
};
|
||||
|
||||
struct chpVolHeader {
|
||||
u8 entryCount;
|
||||
chpVolEntry entries[entryCount];
|
||||
};
|
||||
|
||||
struct ExtraHeader {
|
||||
u32 headerSize;
|
||||
chpClkBase = $;
|
||||
u32 chpClkOffset;
|
||||
chpVolBase = $;
|
||||
u32 chpVolOffset;
|
||||
|
||||
if (chpClkOffset > 0) {
|
||||
$ = chpClkBase + chpClkOffset;
|
||||
chpClkHeader chpClk;
|
||||
} if (chpVolOffset > 0) {
|
||||
$ = chpVolBase + chpVolOffset;
|
||||
chpVolHeader chpVol;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct VGM {
|
||||
Header header;
|
||||
if (versionValue >= 170) {
|
||||
if (header.extraHeaderOffset > 0) {
|
||||
ExtraHeader extraHeader;
|
||||
}
|
||||
}
|
||||
Gd3 tag @ (gd3TagPos + header.Gd3Offset);
|
||||
};
|
||||
|
||||
VGM vgm @ 0x00;
|
||||
Reference in New Issue
Block a user