diff --git a/patterns/3ds.hexpat b/patterns/3ds.hexpat index 73d80e87..964eaa5d 100644 --- a/patterns/3ds.hexpat +++ b/patterns/3ds.hexpat @@ -1,1138 +1,1141 @@ -#include -#include - -#pragma MIME image/x-3ds - -// Heavily based off of ZiZi's 010 Editor 3DS Template -enum ChunkIdentifier : u16 { - NULL_CHUNK = 0x0000, - ChunkType = 0x0995, - ChunkUnique = 0x0996, - NotChunk = 0x0997, - Container = 0x0998, - IsChunk = 0x0999, - - /* Dummy Chunk that sometimes appears in 3ds files created by prerelease 3D Studio R2 */ - DUMMY = 0xFFFF, - - /* Chunk Types for Open*, Write*, Close* functions */ - POINT_ARRAY_ENTRY = 0xF110, - POINT_FLAG_ARRAY_ENTRY = 0xF111, - FACE_ARRAY_ENTRY = 0xF120, - MSH_MAT_GROUP_ENTRY = 0xF130, - TEX_VERTS_ENTRY = 0xF140, - SMOOTH_GROUP_ENTRY = 0xF150, - POS_TRACK_TAG_KEY = 0xF020, - ROT_TRACK_TAG_KEY = 0xF021, - SCL_TRACK_TAG_KEY = 0xF022, - FOV_TRACK_TAG_KEY = 0xF023, - ROLL_TRACK_TAG_KEY = 0xF024, - COL_TRACK_TAG_KEY = 0xF025, - MORPH_TRACK_TAG_KEY = 0xF026, - HOT_TRACK_TAG_KEY = 0xF027, - FALL_TRACK_TAG_KEY = 0xF028, - - /* 3DS File Chunk IDs */ - COLOR_F = 0x0010, // r,g,b: Single precision float - COLOR_24 = 0x0011, // r,g,b: Byte - LIN_COLOR_24 = 0x0012, // r,g,b: Byte (gamma corrected) - LIN_COLOR_F = 0x0013, // r,g,b: Single precision float (gamma corrected) - - INT_PERCENTAGE = 0x0030, // u16 integer - FLOAT_PERCENTAGE = 0x0031, // Single precision float - - M3DMAGIC = 0x4D4D, - SMAGIC = 0x2D2D, - LMAGIC = 0x2D3D, - MLIBMAGIC = 0x3DAA, - MATMAGIC = 0x3DFF, - M3D_VERSION = 0x0002, - MDATA = 0x3D3D, - MESH_VERSION = 0x3D3E, - WORLD_VIEWPORT_DATA = 0x7011, - WORLD_VIEWPORT_DATA3 = 0x7012, - WORLD_VIEWPORT_SIZE = 0x7020, - WORLD_VIEWPORT_LAYOUT = 0x7001, - MASTER_SCALE = 0x0100, - BIT_MAP = 0x1100, // Background bitmap filename - USE_BIT_MAP = 0x1101, // Use background bitmap - SOLID_BGND = 0x1200, // Background color - USE_SOLID_BGND = 0x1201, // Use background color - V_GRADIENT = 0x1300, // Background gradient colors - USE_V_GRADIENT = 0x1301, // Use background gradient colors - LO_SHADOW_BIAS = 0x1400, - HI_SHADOW_BIAS = 0x1410, - SHADOW_MAP_SIZE = 0x1420, - SHADOW_SAMPLES = 0x1430, - SHADOW_RANGE = 0x1440, - SHADOW_FILTER = 0x1450, - RAY_BIAS = 0x1460, - USE_RAYTRACE = 0x1470, - O_CONSTS = 0x1500, - - AMBIENT_LIGHT = 0x2100, - - FOG = 0x2200, - USE_FOG = 0x2201, - FOG_BGND = 0x2210, - DISTANCE_CUE = 0x2300, - USE_DISTANCE_CUE = 0x2301, - WORLD_LAYERED_FOG = 0x2302, - WORLD_USE_LAYERED_FOG = 0x2303, - - DEFAULT_VIEW = 0x3000, - VIEW_TOP = 0x3010, - VIEW_BOTTOM = 0x3020, - VIEW_LEFT = 0x3030, - VIEW_RIGHT = 0x3040, - VIEW_FRONT = 0x3050, - VIEW_BACK = 0x3060, - VIEW_USER = 0x3070, - VIEW_CAMERA = 0x3080, - VIEW_WINDOW = 0x3090, - - NAMED_OBJECT = 0x4000, - OBJ_HIDDEN = 0x4010, - OBJ_VIS_LOFTER = 0x4011, - OBJ_DOESNT_CAST = 0x4012, - OBJ_MATTE = 0x4013, - OBJ_FAST = 0x4014, - OBJ_PROCEDURAL = 0x4015, - OBJ_FROZEN = 0x4016, - OBJ_DONT_RCVSHADOW = 0x4017, - - N_TRI_OBJECT = 0x4100, - POINT_ARRAY = 0x4110, - POINT_FLAG_ARRAY = 0x4111, - FACE_ARRAY = 0x4120, - MSH_MAT_GROUP = 0x4130, - OLD_MAT_GROUP = 0x4131, - SMOOTH_GROUP = 0x4150, - TEX_VERTS = 0x4140, - MESH_MATRIX = 0x4160, - MESH_COLOR = 0x4165, - MESH_TEXTURE_INFO = 0x4170, - PROC_NAME = 0x4181, - PROC_DATA = 0x4182, - MSH_BOXMAP = 0x4190, - - N_D_L_OLD = 0x4400, - - N_CAM_OLD = 0x4500, - - N_DIRECT_LIGHT = 0x4600, - DL_SPOTLIGHT = 0x4610, - DL_RAYSHAD = 0x4627, - DL_SHADOWED = 0x4630, - DL_LOCAL_SHADOW = 0x4640, - DL_LOCAL_SHADOW2 = 0x4641, - DL_SEE_CONE = 0x4650, - DL_SPOT_RECTANGULAR = 0x4651, - DL_SPOT_OVERSHOOT = 0x4652, - DL_SPOT_PROJECTOR = 0x4653, - DL_EXCLUDE = 0x4654, - DL_RANGE = 0x4655, /* Not used in R3 */ - DL_SPOT_ROLL = 0x4656, - DL_SPOT_ASPECT = 0x4657, - DL_RAY_BIAS = 0x4658, - DL_OFF = 0x4620, - DL_ATTENUATE = 0x4625, - DL_INNER_RANGE = 0x4659, - DL_OUTER_RANGE = 0x465A, - DL_MULTIPLIER = 0x465B, - - N_AMBIENT_LIGHT = 0x4680, - - N_CAMERA = 0x4700, - CAM_SEE_CONE = 0x4710, - CAM_RANGES = 0x4720, - - HIERARCHY = 0x4F00, - PARENT_OBJECT = 0x4F10, - PIVOT_OBJECT = 0x4F20, - PIVOT_LIMITS = 0x4F30, - PIVOT_ORDER = 0x4F40, - XLATE_RANGE = 0x4F50, - - POLY_2D = 0x5000, - - /* Flags in shaper file that tell whether polys make up an ok shape */ - SHAPE_OK = 0x5010, - SHAPE_NOT_OK = 0x5011, - - SHAPE_HOOK = 0x5020, - - PATH_3D = 0x6000, - PATH_MATRIX = 0x6005, - SHAPE_2D = 0x6010, - M_SCALE = 0x6020, - M_TWIST = 0x6030, - M_TEETER = 0x6040, - M_FIT = 0x6050, - M_BEVEL = 0x6060, - XZ_CURVE = 0x6070, - YZ_CURVE = 0x6080, - INTERPCT = 0x6090, - DEFORM_LIMIT = 0x60A0, - - /* Flags for Modeler options */ - USE_CONTOUR = 0x6100, - USE_TWEEN = 0x6110, - USE_SCALE = 0x6120, - USE_TWIST = 0x6130, - USE_TEETER = 0x6140, - USE_FIT = 0x6150, - USE_BEVEL = 0x6160, - - /* Viewport description chunks */ - VIEWPORT_LAYOUT_OLD = 0x7000, - VIEWPORT_DATA_OLD = 0x7010, - VIEWPORT_LAYOUT = 0x7001, - VIEWPORT_DATA = 0x7011, - VIEWPORT_DATA_3 = 0x7012, - VIEWPORT_SIZE = 0x7020, - NETWORK_VIEW = 0x7030, - - /* External Application Data */ - XDATA_SECTION = 0x8000, - XDATA_ENTRY = 0x8001, - XDATA_APPNAME = 0x8002, - XDATA_STRING = 0x8003, - XDATA_FLOAT = 0x8004, - XDATA_DOUBLE = 0x8005, - XDATA_SHORT = 0x8006, - XDATA_LONG = 0x8007, - XDATA_VOID = 0x8008, - XDATA_GROUP = 0x8009, - XDATA_RFU6 = 0x800A, - XDATA_RFU5 = 0x800B, - XDATA_RFU4 = 0x800C, - XDATA_RFU3 = 0x800D, - XDATA_RFU2 = 0x800E, - XDATA_RFU1 = 0x800F, - - PARENT_NAME = 0x80F0, - - /* Material Chunk IDs */ - MAT_ENTRY = 0xAFFF, - MAT_NAME = 0xA000, - MAT_AMBIENT = 0xA010, - MAT_DIFFUSE = 0xA020, - MAT_SPECULAR = 0xA030, - MAT_SHININESS = 0xA040, - MAT_SHIN2PCT = 0xA041, - MAT_SHIN3PCT = 0xA042, - MAT_TRANSPARENCY = 0xA050, - MAT_XPFALL = 0xA052, - MAT_REFBLUR = 0xA053, - - MAT_SELF_ILLUM = 0xA080, - MAT_TWO_SIDE = 0xA081, - MAT_DECAL = 0xA082, - MAT_ADDITIVE = 0xA083, - MAT_SELF_ILPCT = 0xA084, - MAT_WIRE = 0xA085, - MAT_SUPERSMP = 0xA086, - MAT_WIRESIZE = 0xA087, - MAT_FACEMAP = 0xA088, - MAT_XPFALLIN = 0xA08A, - MAT_PHONGSOFT = 0xA08C, - MAT_WIREABS = 0xA08E, - - MAT_SHADING = 0xA100, - - MAT_TEXMAP = 0xA200, - MAT_MAPNAME = 0xA300, - MAT_ACUBIC = 0xA310, - - MAT_MAP_TILINGOLD = 0xA350, - MAT_MAP_TILING = 0xA351, - MAT_MAP_TEXBLUR_OLD = 0xA352, - MAT_MAP_TEXBLUR = 0xA353, - MAT_MAP_USCALE = 0xA354, - MAT_MAP_VSCALE = 0xA356, - MAT_MAP_UOFFSET = 0xA358, - MAT_MAP_VOFFSET = 0xA35A, - MAT_MAP_ANG = 0xA35C, - MAT_MAP_COL1 = 0xA360, - MAT_MAP_COL2 = 0xA362, - MAT_MAP_RCOL = 0xA364, - MAT_MAP_GCOL = 0xA366, - MAT_MAP_BCOL = 0xA368, - - MAT_SPECMAP = 0xA204, - MAT_OPACMAP = 0xA210, - MAT_REFLMAP = 0xA220, - MAT_BUMPMAP = 0xA230, - MAT_USE_REFBLUR = 0xA250, - MAT_BUMP_PERCENT = 0xA252, - - MAT_SXP_TEXT_DATA = 0xA320, - MAT_SXP_TEXT2_DATA = 0xA321, - MAT_SXP_OPAC_DATA = 0xA322, - MAT_SXP_BUMP_DATA = 0xA324, - MAT_SXP_SPEC_DATA = 0xA325, - MAT_SXP_SHIN_DATA = 0xA326, - MAT_SXP_SELFI_DATA = 0xA328, - MAT_SXP_TEXT_MASKDATA = 0xA32A, - MAT_SXP_TEXT2_MASKDATA = 0xA32C, - MAT_SXP_OPAC_MASKDATA = 0xA32E, - MAT_SXP_BUMP_MASKDATA = 0xA330, - MAT_SXP_SPEC_MASKDATA = 0xA332, - MAT_SXP_SHIN_MASKDATA = 0xA334, - MAT_SXP_SELFI_MASKDATA = 0xA336, - MAT_SXP_REFL_MASKDATA = 0xA338, - - MAT_TEX2MAP = 0xA33A, - MAT_SHINMAP = 0xA33C, - MAT_SELFIMAP = 0xA33D, - MAT_TEXMASK = 0xA33E, - MAT_TEX2MASK = 0xA340, - MAT_OPACMASK = 0xA342, - MAT_BUMPMASK = 0xA344, - MAT_SHINMASK = 0xA346, - MAT_SPECMASK = 0xA348, - MAT_SELFIMASK = 0xA34A, - MAT_REFLMASK = 0xA34C, - - /* Keyframe Chunk IDs */ - KFDATA = 0xB000, - KFHDR = 0xB00A, - AMBIENT_NODE_TAG = 0xB001, - OBJECT_NODE_TAG = 0xB002, - CAMERA_NODE_TAG = 0xB003, - TARGET_NODE_TAG = 0xB004, - LIGHT_NODE_TAG = 0xB005, - L_TARGET_NODE_TAG = 0xB006, - SPOTLIGHT_NODE_TAG = 0xB007, - - KFSEG = 0xB008, - KFCURTIME = 0xB009, - - NODE_HDR = 0xB010, - INSTANCE_NAME = 0xB011, - PRESCALE = 0xB012, - PIVOT = 0xB013, - BOUNDBOX = 0xB014, - MORPH_SMOOTH = 0xB015, - POS_TRACK_TAG = 0xB020, - ROT_TRACK_TAG = 0xB021, - SCL_TRACK_TAG = 0xB022, - FOV_TRACK_TAG = 0xB023, - ROLL_TRACK_TAG = 0xB024, - COL_TRACK_TAG = 0xB025, - MORPH_TRACK_TAG = 0xB026, - HOT_TRACK_TAG = 0xB027, - FALL_TRACK_TAG = 0xB028, - HIDE_TRACK_TAG = 0xB029, - NODE_ID = 0xB030, - - - CMAGIC = 0xC23D, - - C_MDRAWER = 0xC010, - C_TDRAWER = 0xC020, - C_SHPDRAWER = 0xC030, - C_MODDRAWER = 0xC040, - C_RIPDRAWER = 0xC050, - C_TXDRAWER = 0xC060, - C_PDRAWER = 0xC062, - C_MTLDRAWER = 0xC064, - C_FLIDRAWER = 0xC066, - C_CUBDRAWER = 0xC067, - C_MFILE = 0xC070, - C_SHPFILE = 0xC080, - C_MODFILE = 0xC090, - C_RIPFILE = 0xC0A0, - C_TXFILE = 0xC0B0, - C_PFILE = 0xC0B2, - C_MTLFILE = 0xC0B4, - C_FLIFILE = 0xC0B6, - C_PALFILE = 0xC0B8, - C_TX_STRING = 0xC0C0, - C_CONSTS = 0xC0D0, - C_SNAPS = 0xC0E0, - C_GRIDS = 0xC0F0, - C_ASNAPS = 0xC100, - C_GRID_RANGE = 0xC110, - C_RENDTYPE = 0xC120, - C_PROGMODE = 0xC130, - C_PREVMODE = 0xC140, - C_MODWMODE = 0xC150, - C_MODMODEL = 0xC160, - C_ALL_LINES = 0xC170, - C_BACK_TYPE = 0xC180, - C_MD_CS = 0xC190, - C_MD_CE = 0xC1A0, - C_MD_SML = 0xC1B0, - C_MD_SMW = 0xC1C0, - C_LOFT_WITH_TEXTURE = 0xC1C3, - C_LOFT_L_REPEAT = 0xC1C4, - C_LOFT_W_REPEAT = 0xC1C5, - C_LOFT_UV_NORMALIZE = 0xC1C6, - C_WELD_LOFT = 0xC1C7, - C_MD_PDET = 0xC1D0, - C_MD_SDET = 0xC1E0, - C_RGB_RMODE = 0xC1F0, - C_RGB_HIDE = 0xC200, - C_RGB_MAPSW = 0xC202, - C_RGB_TWOSIDE = 0xC204, - C_RGB_SHADOW = 0xC208, - C_RGB_AA = 0xC210, - C_RGB_OVW = 0xC220, - C_RGB_OVH = 0xC230, - C_RGB_PICTYPE = 0xC240, - C_RGB_OUTPUT = 0xC250, - C_RGB_TODISK = 0xC253, - C_RGB_COMPRESS = 0xC254, - C_JPEG_COMPRESSION = 0xC255, - C_RGB_DISPDEV = 0xC256, - C_RGB_HARDDEV = 0xC259, - C_RGB_PATH = 0xC25A, - C_BITMAP_DRAWER = 0xC25B, - C_RGB_FILE = 0xC260, - C_RGB_OVASPECT = 0xC270, - - C_RGB_ANIMTYPE = 0xC271, - C_RENDER_ALL = 0xC272, - C_REND_FROM = 0xC273, - C_REND_TO = 0xC274, - C_REND_NTH = 0xC275, - C_PAL_TYPE = 0xC276, - C_RND_TURBO = 0xC277, - C_RND_MIP = 0xC278, - C_BGND_METHOD = 0xC279, - C_AUTO_REFLECT = 0xC27A, - C_VP_FROM = 0xC27B, - C_VP_TO = 0xC27C, - C_VP_NTH = 0xC27D, - C_REND_TSTEP = 0xC27E, - C_VP_TSTEP = 0xC27F, - - C_SRDIAM = 0xC280, - C_SRDEG = 0xC290, - C_SRSEG = 0xC2A0, - C_SRDIR = 0xC2B0, - C_HETOP = 0xC2C0, - C_HEBOT = 0xC2D0, - C_HEHT = 0xC2E0, - C_HETURNS = 0xC2F0, - C_HEDEG = 0xC300, - C_HESEG = 0xC310, - C_HEDIR = 0xC320, - C_QUIKSTUFF = 0xC330, - C_SEE_LIGHTS = 0xC340, - C_SEE_CAMERAS = 0xC350, - C_SEE_3D = 0xC360, - C_MESHSEL = 0xC370, - C_MESHUNSEL = 0xC380, - C_POLYSEL = 0xC390, - C_POLYUNSEL = 0xC3A0, - C_SHPLOCAL = 0xC3A2, - C_MSHLOCAL = 0xC3A4, - C_NUM_FORMAT = 0xC3B0, - C_ARCH_DENOM = 0xC3C0, - C_IN_DEVICE = 0xC3D0, - C_MSCALE = 0xC3E0, - C_COMM_PORT = 0xC3F0, - C_TAB_BASES = 0xC400, - C_TAB_DIVS = 0xC410, - C_MASTER_SCALES = 0xC420, - C_SHOW_1STVERT = 0xC430, - C_SHAPER_OK = 0xC440, - C_LOFTER_OK = 0xC450, - C_EDITOR_OK = 0xC460, - C_KEYFRAMER_OK = 0xC470, - C_PICKSIZE = 0xC480, - C_MAPTYPE = 0xC490, - C_MAP_DISPLAY = 0xC4A0, - C_TILE_XY = 0xC4B0, - C_MAP_XYZ = 0xC4C0, - C_MAP_SCALE = 0xC4D0, - C_MAP_MATRIX_OLD = 0xC4E0, - C_MAP_MATRIX = 0xC4E1, - C_MAP_WID_HT = 0xC4F0, - C_OBNAME = 0xC500, - C_CAMNAME = 0xC510, - C_LTNAME = 0xC520, - C_CUR_MNAME = 0xC525, - C_CURMTL_FROM_MESH = 0xC526, - C_GET_SHAPE_MAKE_FACES = 0xC527, - C_DETAIL = 0xC530, - C_VERTMARK = 0xC540, - C_MSHAX = 0xC550, - C_MSHCP = 0xC560, - C_USERAX = 0xC570, - C_SHOOK = 0xC580, - C_RAX = 0xC590, - C_STAPE = 0xC5A0, - C_LTAPE = 0xC5B0, - C_ETAPE = 0xC5C0, - C_KTAPE = 0xC5C8, - C_SPHSEGS = 0xC5D0, - C_GEOSMOOTH = 0xC5E0, - C_HEMISEGS = 0xC5F0, - C_PRISMSEGS = 0xC600, - C_PRISMSIDES = 0xC610, - C_TUBESEGS = 0xC620, - C_TUBESIDES = 0xC630, - C_TORSEGS = 0xC640, - C_TORSIDES = 0xC650, - C_CONESIDES = 0xC660, - C_CONESEGS = 0xC661, - C_NGPARMS = 0xC670, - C_PTHLEVEL = 0xC680, - C_MSCSYM = 0xC690, - C_MFTSYM = 0xC6A0, - C_MTTSYM = 0xC6B0, - C_SMOOTHING = 0xC6C0, - C_MODICOUNT = 0xC6D0, - C_FONTSEL = 0xC6E0, - C_TESS_TYPE = 0xC6f0, - C_TESS_TENSION = 0xC6f1, - - C_SEG_START = 0xC700, - C_SEG_END = 0xC705, - C_CURTIME = 0xC710, - C_ANIMLENGTH = 0xC715, - C_PV_FROM = 0xC720, - C_PV_TO = 0xC725, - C_PV_DOFNUM = 0xC730, - C_PV_RNG = 0xC735, - C_PV_NTH = 0xC740, - C_PV_TYPE = 0xC745, - C_PV_METHOD = 0xC750, - C_PV_FPS = 0xC755, - C_VTR_FRAMES = 0xC765, - C_VTR_HDTL = 0xC770, - C_VTR_HD = 0xC771, - C_VTR_TL = 0xC772, - C_VTR_IN = 0xC775, - C_VTR_PK = 0xC780, - C_VTR_SH = 0xC785, - -/* Material chunks */ - C_WORK_MTLS = 0xC790, /* Old-style -- now ignored */ - C_WORK_MTLS_2 = 0xC792, /* Old-style -- now ignored */ - C_WORK_MTLS_3 = 0xC793, /* Old-style -- now ignored */ - C_WORK_MTLS_4 = 0xC794, /* Old-style -- now ignored */ - C_WORK_MTLS_5 = 0xCB00, /* Old-style -- now ignored */ - C_WORK_MTLS_6 = 0xCB01, /* Old-style -- now ignored */ - C_WORK_MTLS_7 = 0xCB02, /* Old-style -- now ignored */ - C_WORK_MTLS_8 = 0xCB03, /* Old-style -- now ignored */ - C_WORKMTL = 0xCB04, - C_SXP_TEXT_DATA = 0xCB10, - C_SXP_TEXT2_DATA = 0xCB20, - C_SXP_OPAC_DATA = 0xCB11, - C_SXP_BUMP_DATA = 0xCB12, - C_SXP_SPEC_DATA = 0xCB24, - C_SXP_SHIN_DATA = 0xCB13, - C_SXP_SELFI_DATA = 0xCB28, - C_SXP_TEXT_MASKDATA = 0xCB30, - C_SXP_TEXT2_MASKDATA = 0xCB32, - C_SXP_OPAC_MASKDATA = 0xCB34, - C_SXP_BUMP_MASKDATA = 0xCB36, - C_SXP_SPEC_MASKDATA = 0xCB38, - C_SXP_SHIN_MASKDATA = 0xCB3A, - C_SXP_SELFI_MASKDATA = 0xC3C, - C_SXP_REFL_MASKDATA = 0xCB3E, - - C_BGTYPE = 0xC7A1, - C_MEDTILE = 0xC7B0, - -/* Contrast */ - C_LO_CONTRAST = 0xC7D0, - C_HI_CONTRAST = 0xC7D1, - -/* 3d frozen display */ - C_FROZ_DISPLAY = 0xC7E0, - -/* Booleans */ - C_BOOLWELD = 0xc7f0, - C_BOOLTYPE = 0xc7f1, - - C_ANG_THRESH = 0xC900, - C_SS_THRESH = 0xC901, - C_TEXTURE_BLUR_DEFAULT = 0xC903, - - C_MAPDRAWER = 0xCA00, - C_MAPDRAWER1 = 0xCA01, - C_MAPDRAWER2 = 0xCA02, - C_MAPDRAWER3 = 0xCA03, - C_MAPDRAWER4 = 0xCA04, - C_MAPDRAWER5 = 0xCA05, - C_MAPDRAWER6 = 0xCA06, - C_MAPDRAWER7 = 0xCA07, - C_MAPDRAWER8 = 0xCA08, - C_MAPDRAWER9 = 0xCA09, - C_MAPDRAWER_ENTRY = 0xCA10, - -/* System Options */ - C_BACKUP_FILE = 0xCA20, - C_DITHER_256 = 0xCA21, - C_SAVE_LAST = 0xCA22, - C_USE_ALPHA = 0xCA23, - C_TGA_DEPTH = 0xCA24, - C_REND_FIELDS = 0xCA25, - C_REFLIP = 0xCA26, - C_SEL_ITEMTOG = 0xCA27, - C_SEL_RESET = 0xCA28, - C_STICKY_KEYINF = 0xCA29, - C_WELD_THRESHOLD = 0xCA2A, - C_ZCLIP_POINT = 0xCA2B, - C_ALPHA_SPLIT = 0xCA2C, - C_KF_SHOW_BACKFACE = 0xCA30, - C_OPTIMIZE_LOFT = 0xCA40, - C_TENS_DEFAULT = 0xCA42, - C_CONT_DEFAULT = 0xCA44, - C_BIAS_DEFAULT = 0xCA46, - - C_DXFNAME_SRC = 0xCA50, - C_AUTO_WELD = 0xCA60, - C_AUTO_UNIFY = 0xCA70, - C_AUTO_SMOOTH = 0xCA80, - C_DXF_SMOOTH_ANG = 0xCA90, - C_SMOOTH_ANG = 0xCAA0, - -/* Special network-use chunks */ - C_NET_USE_VPOST = 0xCC00, - C_NET_USE_GAMMA = 0xCC10, - C_NET_FIELD_ORDER = 0xCC20, - - C_BLUR_FRAMES = 0xCD00, - C_BLUR_SAMPLES = 0xCD10, - C_BLUR_DUR = 0xCD20, - C_HOT_METHOD = 0xCD30, - C_HOT_CHECK = 0xCD40, - C_PIXEL_SIZE = 0xCD50, - C_DISP_GAMMA = 0xCD60, - C_FBUF_GAMMA = 0xCD70, - C_FILE_OUT_GAMMA = 0xCD80, - C_FILE_IN_GAMMA = 0xCD82, - C_GAMMA_CORRECT = 0xCD84, - C_APPLY_DISP_GAMMA = 0xCD90, /* OBSOLETE */ - C_APPLY_FBUF_GAMMA = 0xCDA0, /* OBSOLETE */ - C_APPLY_FILE_GAMMA = 0xCDB0, /* OBSOLETE */ - C_FORCE_WIRE = 0xCDC0, - C_RAY_SHADOWS = 0xCDD0, - C_MASTER_AMBIENT = 0xCDE0, - C_SUPER_SAMPLE = 0xCDF0, - C_OBJECT_MBLUR = 0xCE00, - C_MBLUR_DITHER = 0xCE10, - C_DITHER_24 = 0xCE20, - C_SUPER_BLACK = 0xCE30, - C_SAFE_FRAME = 0xCE40, - C_VIEW_PRES_RATIO = 0xCE50, - C_BGND_PRES_RATIO = 0xCE60, - C_NTH_SERIAL_NUM = 0xCE70, - - /* Video Post */ - VPDATA = 0xd000, - - P_QUEUE_ENTRY = 0xd100, - P_QUEUE_IMAGE = 0xd110, - P_QUEUE_USEIGAMMA = 0xd114, - P_QUEUE_PROC = 0xd120, - P_QUEUE_SOLID = 0xd130, - P_QUEUE_GRADIENT = 0xd140, - P_QUEUE_KF = 0xd150, - P_QUEUE_MOTBLUR = 0xd152, - P_QUEUE_MB_REPEAT = 0xd153, - P_QUEUE_NONE = 0xd160, - - P_QUEUE_RESIZE = 0xd180, - P_QUEUE_OFFSET = 0xd185, - P_QUEUE_ALIGN = 0xd190, - - P_CUSTOM_SIZE = 0xd1a0, - - P_ALPH_NONE = 0xd210, - P_ALPH_PSEUDO = 0xd220, /* Old chunk */ - P_ALPH_OP_PSEUDO = 0xd221, /* Old chunk */ - P_ALPH_BLUR = 0xd222, /* Replaces pseudo */ - P_ALPH_PCOL = 0xd225, - P_ALPH_C0 = 0xd230, - P_ALPH_OP_KEY = 0xd231, - P_ALPH_KCOL = 0xd235, - P_ALPH_OP_NOCONV = 0xd238, - P_ALPH_IMAGE = 0xd240, - P_ALPH_ALPHA = 0xd250, - P_ALPH_QUES = 0xd260, - P_ALPH_QUEIMG = 0xd265, - P_ALPH_CUTOFF = 0xd270, - P_ALPHANEG = 0xd280, - - P_TRAN_NONE = 0xd300, - P_TRAN_IMAGE = 0xd310, - P_TRAN_FRAMES = 0xd312, - P_TRAN_FADEIN = 0xd320, - P_TRAN_FADEOUT = 0xd330, - P_TRANNEG = 0xd340, - - P_RANGES = 0xd400, - - P_PROC_DATA = 0xd500 -}; - -struct Vector2f { - float x, y; -} [[static]]; - -struct Vector3f { - float x, y, z; -} [[static]]; - -bitfield FaceFlags { - CA_Visible : 1; - BC_Visible : 1; - AB_Visible : 1; - Mapped : 1; - padding : 9; - CA_Selected : 1; - BC_Selected : 1; - AB_Selected : 1; -}; - -struct Face { - u16 v0, v1,v2; - FaceFlags flags; -}; - -bitfield VertexFlags { - padding : 13; - selected3 : 1; - selected2 : 1; - selected1 : 1; -}; - -bitfield KeyFlags1 { - Show_Path : 1; - Smooth : 1; - padding : 2; - Motion_Blur : 1; - padding : 1; - Morph_Mat : 1; -}; - -bitfield KeyFlags2 { - padding : 10; - Hidden : 1; -}; - -struct RGB { - T r, g, b; -}; - -bitfield Spline { - Use_Tension : 1; - Use_Continuity : 1; - Use_Bias : 1; - Use_Ease_To : 1; - Use_Ease_From : 1; - - padding : 3; - - if (Use_Tension == 1) - float Tension; - if (Use_Continuity == 1) - float Continuity; - if (Use_Bias == 1) - float Bias; - if (Use_Ease_To == 1) - float Ease_To; - if (Use_Ease_From == 1) - float Ease_From; - - padding : 8; -}; - -struct VectorKey { - u32 index; - Spline splineData; - Vector3f value; -}; - -struct RotationKey { - u32 index; - Spline splineData; - float angle; - Vector3f vector; -}; - -struct AngleKey { - u32 index; - Spline splineData; - float angle; -}; - -struct MorphKey{ - u32 index; - Spline splineData; - char objectName[]; -}; - -struct HideKey { - u32 index; - Spline splineData; -}; - -struct Keys { - u32 count; - match (identifier) { - ( - ChunkIdentifier::POS_TRACK_TAG | - ChunkIdentifier::SCL_TRACK_TAG | - ChunkIdentifier::COL_TRACK_TAG - ) : { - VectorKey data[count]; - } - - ( - ChunkIdentifier::ROT_TRACK_TAG - ) : { - RotationKey data[count]; - } - - ( - ChunkIdentifier::FOV_TRACK_TAG | - ChunkIdentifier::ROLL_TRACK_TAG | - ChunkIdentifier::HOT_TRACK_TAG | - ChunkIdentifier::FALL_TRACK_TAG - ) : { - AngleKey data[count]; - } - - ( - ChunkIdentifier::MORPH_TRACK_TAG - ) : { - MorphKey data[count]; - } - - ( - ChunkIdentifier::HIDE_TRACK_TAG - ) : { - HideKey data[count]; - } - } -}; - -enum TrackMode : u16 { - MODE_SINGLE = 0, - MODE_REPEAT = 1, - MODE_LOOP = 2, -}; - -bitfield TrackFlags { - TrackMode Mode : 2; - padding : 1; - Lock_X : 1; - Lock_Y : 1; - Lock_Z : 1; - padding : 1; - Unlink_X : 1; - Unlink_Y : 1; - Unlink_Z : 1; -}; - -struct Chunk { - ChunkIdentifier identifier; - u32 chunkSize; - u32 dataLength = chunkSize - 6 [[export]]; - u32 chunkEnd = $ + dataLength; - - if (chunkSize > 0) { - std::print("{}", identifier); - match (identifier) { - ( - ChunkIdentifier::M3DMAGIC | - ChunkIdentifier::MDATA | - ChunkIdentifier::N_TRI_OBJECT | - ChunkIdentifier::KFDATA | - ChunkIdentifier::AMBIENT_NODE_TAG | - ChunkIdentifier::OBJECT_NODE_TAG | - ChunkIdentifier::CAMERA_NODE_TAG | - ChunkIdentifier::TARGET_NODE_TAG | - ChunkIdentifier::LIGHT_NODE_TAG | - ChunkIdentifier::L_TARGET_NODE_TAG | - ChunkIdentifier::SPOTLIGHT_NODE_TAG | - ChunkIdentifier::MAT_ENTRY | - ChunkIdentifier::MAT_AMBIENT | - ChunkIdentifier::MAT_DIFFUSE | - ChunkIdentifier::MAT_SPECULAR | - ChunkIdentifier::MAT_SHININESS | - ChunkIdentifier::MAT_SHIN2PCT | - ChunkIdentifier::MAT_SHIN3PCT | - ChunkIdentifier::MAT_TRANSPARENCY | - ChunkIdentifier::MAT_XPFALL | - ChunkIdentifier::MAT_REFBLUR | - ChunkIdentifier::MAT_SELF_ILPCT | - ChunkIdentifier::MAT_TEXMAP | - ChunkIdentifier::MAT_SPECMAP | - ChunkIdentifier::MAT_OPACMAP | - ChunkIdentifier::MAT_REFLMAP | - ChunkIdentifier::MAT_BUMPMAP | - ChunkIdentifier::MAT_BUMP_PERCENT | - ChunkIdentifier::MAT_TEX2MAP | - ChunkIdentifier::MAT_SHINMAP | - ChunkIdentifier::MAT_SELFIMAP | - ChunkIdentifier::MAT_TEXMASK | - ChunkIdentifier::MAT_TEX2MASK | - ChunkIdentifier::MAT_OPACMASK | - ChunkIdentifier::MAT_BUMPMASK | - ChunkIdentifier::MAT_SHINMASK | - ChunkIdentifier::MAT_SPECMASK | - ChunkIdentifier::MAT_SELFIMASK | - ChunkIdentifier::MAT_REFLMASK | - ChunkIdentifier::WORLD_VIEWPORT_DATA | - ChunkIdentifier::WORLD_VIEWPORT_DATA3 | - ChunkIdentifier::WORLD_VIEWPORT_LAYOUT | - ChunkIdentifier::SOLID_BGND | - ChunkIdentifier::AMBIENT_LIGHT - ): { - Chunk chunks[while($ < chunkEnd)]; - } - - ( - ChunkIdentifier::M3D_VERSION | - ChunkIdentifier::MESH_VERSION - ): { - u32 version; - } - - ( - ChunkIdentifier::LO_SHADOW_BIAS | - ChunkIdentifier::HI_SHADOW_BIAS | - ChunkIdentifier::SHADOW_FILTER | - ChunkIdentifier::RAY_BIAS | - ChunkIdentifier::FLOAT_PERCENTAGE | - ChunkIdentifier::MASTER_SCALE | - ChunkIdentifier::MAT_MAP_TEXBLUR | - ChunkIdentifier::MAT_MAP_USCALE | - ChunkIdentifier::MAT_MAP_VSCALE | - ChunkIdentifier::MAT_MAP_UOFFSET | - ChunkIdentifier::MAT_MAP_VOFFSET | - ChunkIdentifier::MAT_MAP_ANG | - ChunkIdentifier::MAT_WIRESIZE | - ChunkIdentifier::DL_SPOT_ROLL | - ChunkIdentifier::MORPH_SMOOTH - ): { - float value; - } - - ( - ChunkIdentifier::V_GRADIENT - ) : { - float position; - Chunk chunks[while($ < chunkEnd)]; - } - - ( - ChunkIdentifier::NAMED_OBJECT - ) : { - char name[]; - Chunk chunks[while($ < chunkEnd)]; - } - - ( - ChunkIdentifier::POINT_ARRAY - ) : { - u16 count; - Vector3f vectices[count] [[hex::visualize("3d", this, null)]]; - } - - ( - ChunkIdentifier::TEX_VERTS - ) : { - u16 count; - Vector2f coords[count]; - } - - ( - ChunkIdentifier::MESH_MATRIX - ) : { - Vector3f x, y, z, w; - } - - ( - ChunkIdentifier::FACE_ARRAY - ) : { - u16 count; - Face faces[count]; - Chunk chunks[while($ < chunkEnd)]; - } - - ( - ChunkIdentifier::POINT_FLAG_ARRAY - ) : { - u16 count; - VertexFlags flags[count]; - } - - ( - ChunkIdentifier::SMOOTH_GROUP - ) : { - u32 groups[dataLength / sizeof(u32)]; - } - - ( - ChunkIdentifier::MESH_COLOR - ) : { - u8 value; - } - - ( - ChunkIdentifier::MSH_MAT_GROUP - ) : { - char name[]; - u16 count; - u16 groups[count]; - } - - ( - ChunkIdentifier::KFHDR - ) : { - u16 revision; - char name[]; - u32 animationLength; - } - - ( - ChunkIdentifier::KFSEG - ) : { - u32 start, end; - } - - ( - ChunkIdentifier::KFCURTIME - ) : { - u32 frameIndex; - } - - ( - ChunkIdentifier::NODE_ID - ) : { - type::Hex id; - } - - ( - ChunkIdentifier::NODE_HDR - ) : { - char name[]; - padding[1]; - KeyFlags1 flags1; - KeyFlags2 flags2; - type::Hex parentId; - } - - ( - ChunkIdentifier::PIVOT - ) : { - Vector3f value; - } - - ( - ChunkIdentifier::BOUNDBOX - ) : { - Vector3f min, max; - } - - ( - ChunkIdentifier::COLOR_24 | - ChunkIdentifier::LIN_COLOR_24 - ) : { - RGB color; - } - - ( - ChunkIdentifier::COLOR_F | - ChunkIdentifier::LIN_COLOR_F - ) : { - RGB color; - } - - ( - ChunkIdentifier::INT_PERCENTAGE | - ChunkIdentifier::MAT_BUMP_PERCENT - ) : { - u16 value; - } - - ( - ChunkIdentifier::SHADOW_MAP_SIZE | - ChunkIdentifier::MAT_SHADING - ) : { - u16 value; - } - - ( - ChunkIdentifier::POS_TRACK_TAG | - ChunkIdentifier::ROT_TRACK_TAG | - ChunkIdentifier::SCL_TRACK_TAG | - ChunkIdentifier::FOV_TRACK_TAG | - ChunkIdentifier::ROLL_TRACK_TAG | - ChunkIdentifier::COL_TRACK_TAG | - ChunkIdentifier::MORPH_TRACK_TAG | - ChunkIdentifier::HOT_TRACK_TAG | - ChunkIdentifier::FALL_TRACK_TAG | - ChunkIdentifier::HIDE_TRACK_TAG - ) : { - TrackFlags flags; - u8 unknown[8]; - Keys keys; - } - - ( - ChunkIdentifier::INSTANCE_NAME | - ChunkIdentifier::BIT_MAP | - ChunkIdentifier::DL_SPOT_PROJECTOR | - ChunkIdentifier::MAT_NAME | - ChunkIdentifier::MAT_MAPNAME - ) : { - char name[]; - } - - ( - ChunkIdentifier::MAT_MAP_TILING - ) : { - u16 tiling; - } - - ( - ChunkIdentifier::WORLD_VIEWPORT_SIZE - ) : { - u16 x, y, w, h; - } - - ( - ChunkIdentifier::N_DIRECT_LIGHT - ) : { - Vector3f position; - Chunk chunks[while($ < chunkEnd)]; - } - - ( - ChunkIdentifier::DL_SPOTLIGHT - ) : { - Vector3f target; - float hotspot, falloff; - Chunk chunks[while($ < chunkEnd)]; - } - - ( - ChunkIdentifier::N_CAMERA - ) : { - Vector3f position, target; - float roll, fov; - } - - - - (_) : { - std::warning(std::format("Unhandled Chunk ID: {}, Skipping 0x{:04X} bytes", identifier, dataLength)); - $ += dataLength; - } - } - } -}; - +#pragma author WerWolv +#pragma description Autodesk 3DS Max Model file + +#include +#include + +#pragma MIME image/x-3ds + +// Heavily based off of ZiZi's 010 Editor 3DS Template +enum ChunkIdentifier : u16 { + NULL_CHUNK = 0x0000, + ChunkType = 0x0995, + ChunkUnique = 0x0996, + NotChunk = 0x0997, + Container = 0x0998, + IsChunk = 0x0999, + + /* Dummy Chunk that sometimes appears in 3ds files created by prerelease 3D Studio R2 */ + DUMMY = 0xFFFF, + + /* Chunk Types for Open*, Write*, Close* functions */ + POINT_ARRAY_ENTRY = 0xF110, + POINT_FLAG_ARRAY_ENTRY = 0xF111, + FACE_ARRAY_ENTRY = 0xF120, + MSH_MAT_GROUP_ENTRY = 0xF130, + TEX_VERTS_ENTRY = 0xF140, + SMOOTH_GROUP_ENTRY = 0xF150, + POS_TRACK_TAG_KEY = 0xF020, + ROT_TRACK_TAG_KEY = 0xF021, + SCL_TRACK_TAG_KEY = 0xF022, + FOV_TRACK_TAG_KEY = 0xF023, + ROLL_TRACK_TAG_KEY = 0xF024, + COL_TRACK_TAG_KEY = 0xF025, + MORPH_TRACK_TAG_KEY = 0xF026, + HOT_TRACK_TAG_KEY = 0xF027, + FALL_TRACK_TAG_KEY = 0xF028, + + /* 3DS File Chunk IDs */ + COLOR_F = 0x0010, // r,g,b: Single precision float + COLOR_24 = 0x0011, // r,g,b: Byte + LIN_COLOR_24 = 0x0012, // r,g,b: Byte (gamma corrected) + LIN_COLOR_F = 0x0013, // r,g,b: Single precision float (gamma corrected) + + INT_PERCENTAGE = 0x0030, // u16 integer + FLOAT_PERCENTAGE = 0x0031, // Single precision float + + M3DMAGIC = 0x4D4D, + SMAGIC = 0x2D2D, + LMAGIC = 0x2D3D, + MLIBMAGIC = 0x3DAA, + MATMAGIC = 0x3DFF, + M3D_VERSION = 0x0002, + MDATA = 0x3D3D, + MESH_VERSION = 0x3D3E, + WORLD_VIEWPORT_DATA = 0x7011, + WORLD_VIEWPORT_DATA3 = 0x7012, + WORLD_VIEWPORT_SIZE = 0x7020, + WORLD_VIEWPORT_LAYOUT = 0x7001, + MASTER_SCALE = 0x0100, + BIT_MAP = 0x1100, // Background bitmap filename + USE_BIT_MAP = 0x1101, // Use background bitmap + SOLID_BGND = 0x1200, // Background color + USE_SOLID_BGND = 0x1201, // Use background color + V_GRADIENT = 0x1300, // Background gradient colors + USE_V_GRADIENT = 0x1301, // Use background gradient colors + LO_SHADOW_BIAS = 0x1400, + HI_SHADOW_BIAS = 0x1410, + SHADOW_MAP_SIZE = 0x1420, + SHADOW_SAMPLES = 0x1430, + SHADOW_RANGE = 0x1440, + SHADOW_FILTER = 0x1450, + RAY_BIAS = 0x1460, + USE_RAYTRACE = 0x1470, + O_CONSTS = 0x1500, + + AMBIENT_LIGHT = 0x2100, + + FOG = 0x2200, + USE_FOG = 0x2201, + FOG_BGND = 0x2210, + DISTANCE_CUE = 0x2300, + USE_DISTANCE_CUE = 0x2301, + WORLD_LAYERED_FOG = 0x2302, + WORLD_USE_LAYERED_FOG = 0x2303, + + DEFAULT_VIEW = 0x3000, + VIEW_TOP = 0x3010, + VIEW_BOTTOM = 0x3020, + VIEW_LEFT = 0x3030, + VIEW_RIGHT = 0x3040, + VIEW_FRONT = 0x3050, + VIEW_BACK = 0x3060, + VIEW_USER = 0x3070, + VIEW_CAMERA = 0x3080, + VIEW_WINDOW = 0x3090, + + NAMED_OBJECT = 0x4000, + OBJ_HIDDEN = 0x4010, + OBJ_VIS_LOFTER = 0x4011, + OBJ_DOESNT_CAST = 0x4012, + OBJ_MATTE = 0x4013, + OBJ_FAST = 0x4014, + OBJ_PROCEDURAL = 0x4015, + OBJ_FROZEN = 0x4016, + OBJ_DONT_RCVSHADOW = 0x4017, + + N_TRI_OBJECT = 0x4100, + POINT_ARRAY = 0x4110, + POINT_FLAG_ARRAY = 0x4111, + FACE_ARRAY = 0x4120, + MSH_MAT_GROUP = 0x4130, + OLD_MAT_GROUP = 0x4131, + SMOOTH_GROUP = 0x4150, + TEX_VERTS = 0x4140, + MESH_MATRIX = 0x4160, + MESH_COLOR = 0x4165, + MESH_TEXTURE_INFO = 0x4170, + PROC_NAME = 0x4181, + PROC_DATA = 0x4182, + MSH_BOXMAP = 0x4190, + + N_D_L_OLD = 0x4400, + + N_CAM_OLD = 0x4500, + + N_DIRECT_LIGHT = 0x4600, + DL_SPOTLIGHT = 0x4610, + DL_RAYSHAD = 0x4627, + DL_SHADOWED = 0x4630, + DL_LOCAL_SHADOW = 0x4640, + DL_LOCAL_SHADOW2 = 0x4641, + DL_SEE_CONE = 0x4650, + DL_SPOT_RECTANGULAR = 0x4651, + DL_SPOT_OVERSHOOT = 0x4652, + DL_SPOT_PROJECTOR = 0x4653, + DL_EXCLUDE = 0x4654, + DL_RANGE = 0x4655, /* Not used in R3 */ + DL_SPOT_ROLL = 0x4656, + DL_SPOT_ASPECT = 0x4657, + DL_RAY_BIAS = 0x4658, + DL_OFF = 0x4620, + DL_ATTENUATE = 0x4625, + DL_INNER_RANGE = 0x4659, + DL_OUTER_RANGE = 0x465A, + DL_MULTIPLIER = 0x465B, + + N_AMBIENT_LIGHT = 0x4680, + + N_CAMERA = 0x4700, + CAM_SEE_CONE = 0x4710, + CAM_RANGES = 0x4720, + + HIERARCHY = 0x4F00, + PARENT_OBJECT = 0x4F10, + PIVOT_OBJECT = 0x4F20, + PIVOT_LIMITS = 0x4F30, + PIVOT_ORDER = 0x4F40, + XLATE_RANGE = 0x4F50, + + POLY_2D = 0x5000, + + /* Flags in shaper file that tell whether polys make up an ok shape */ + SHAPE_OK = 0x5010, + SHAPE_NOT_OK = 0x5011, + + SHAPE_HOOK = 0x5020, + + PATH_3D = 0x6000, + PATH_MATRIX = 0x6005, + SHAPE_2D = 0x6010, + M_SCALE = 0x6020, + M_TWIST = 0x6030, + M_TEETER = 0x6040, + M_FIT = 0x6050, + M_BEVEL = 0x6060, + XZ_CURVE = 0x6070, + YZ_CURVE = 0x6080, + INTERPCT = 0x6090, + DEFORM_LIMIT = 0x60A0, + + /* Flags for Modeler options */ + USE_CONTOUR = 0x6100, + USE_TWEEN = 0x6110, + USE_SCALE = 0x6120, + USE_TWIST = 0x6130, + USE_TEETER = 0x6140, + USE_FIT = 0x6150, + USE_BEVEL = 0x6160, + + /* Viewport description chunks */ + VIEWPORT_LAYOUT_OLD = 0x7000, + VIEWPORT_DATA_OLD = 0x7010, + VIEWPORT_LAYOUT = 0x7001, + VIEWPORT_DATA = 0x7011, + VIEWPORT_DATA_3 = 0x7012, + VIEWPORT_SIZE = 0x7020, + NETWORK_VIEW = 0x7030, + + /* External Application Data */ + XDATA_SECTION = 0x8000, + XDATA_ENTRY = 0x8001, + XDATA_APPNAME = 0x8002, + XDATA_STRING = 0x8003, + XDATA_FLOAT = 0x8004, + XDATA_DOUBLE = 0x8005, + XDATA_SHORT = 0x8006, + XDATA_LONG = 0x8007, + XDATA_VOID = 0x8008, + XDATA_GROUP = 0x8009, + XDATA_RFU6 = 0x800A, + XDATA_RFU5 = 0x800B, + XDATA_RFU4 = 0x800C, + XDATA_RFU3 = 0x800D, + XDATA_RFU2 = 0x800E, + XDATA_RFU1 = 0x800F, + + PARENT_NAME = 0x80F0, + + /* Material Chunk IDs */ + MAT_ENTRY = 0xAFFF, + MAT_NAME = 0xA000, + MAT_AMBIENT = 0xA010, + MAT_DIFFUSE = 0xA020, + MAT_SPECULAR = 0xA030, + MAT_SHININESS = 0xA040, + MAT_SHIN2PCT = 0xA041, + MAT_SHIN3PCT = 0xA042, + MAT_TRANSPARENCY = 0xA050, + MAT_XPFALL = 0xA052, + MAT_REFBLUR = 0xA053, + + MAT_SELF_ILLUM = 0xA080, + MAT_TWO_SIDE = 0xA081, + MAT_DECAL = 0xA082, + MAT_ADDITIVE = 0xA083, + MAT_SELF_ILPCT = 0xA084, + MAT_WIRE = 0xA085, + MAT_SUPERSMP = 0xA086, + MAT_WIRESIZE = 0xA087, + MAT_FACEMAP = 0xA088, + MAT_XPFALLIN = 0xA08A, + MAT_PHONGSOFT = 0xA08C, + MAT_WIREABS = 0xA08E, + + MAT_SHADING = 0xA100, + + MAT_TEXMAP = 0xA200, + MAT_MAPNAME = 0xA300, + MAT_ACUBIC = 0xA310, + + MAT_MAP_TILINGOLD = 0xA350, + MAT_MAP_TILING = 0xA351, + MAT_MAP_TEXBLUR_OLD = 0xA352, + MAT_MAP_TEXBLUR = 0xA353, + MAT_MAP_USCALE = 0xA354, + MAT_MAP_VSCALE = 0xA356, + MAT_MAP_UOFFSET = 0xA358, + MAT_MAP_VOFFSET = 0xA35A, + MAT_MAP_ANG = 0xA35C, + MAT_MAP_COL1 = 0xA360, + MAT_MAP_COL2 = 0xA362, + MAT_MAP_RCOL = 0xA364, + MAT_MAP_GCOL = 0xA366, + MAT_MAP_BCOL = 0xA368, + + MAT_SPECMAP = 0xA204, + MAT_OPACMAP = 0xA210, + MAT_REFLMAP = 0xA220, + MAT_BUMPMAP = 0xA230, + MAT_USE_REFBLUR = 0xA250, + MAT_BUMP_PERCENT = 0xA252, + + MAT_SXP_TEXT_DATA = 0xA320, + MAT_SXP_TEXT2_DATA = 0xA321, + MAT_SXP_OPAC_DATA = 0xA322, + MAT_SXP_BUMP_DATA = 0xA324, + MAT_SXP_SPEC_DATA = 0xA325, + MAT_SXP_SHIN_DATA = 0xA326, + MAT_SXP_SELFI_DATA = 0xA328, + MAT_SXP_TEXT_MASKDATA = 0xA32A, + MAT_SXP_TEXT2_MASKDATA = 0xA32C, + MAT_SXP_OPAC_MASKDATA = 0xA32E, + MAT_SXP_BUMP_MASKDATA = 0xA330, + MAT_SXP_SPEC_MASKDATA = 0xA332, + MAT_SXP_SHIN_MASKDATA = 0xA334, + MAT_SXP_SELFI_MASKDATA = 0xA336, + MAT_SXP_REFL_MASKDATA = 0xA338, + + MAT_TEX2MAP = 0xA33A, + MAT_SHINMAP = 0xA33C, + MAT_SELFIMAP = 0xA33D, + MAT_TEXMASK = 0xA33E, + MAT_TEX2MASK = 0xA340, + MAT_OPACMASK = 0xA342, + MAT_BUMPMASK = 0xA344, + MAT_SHINMASK = 0xA346, + MAT_SPECMASK = 0xA348, + MAT_SELFIMASK = 0xA34A, + MAT_REFLMASK = 0xA34C, + + /* Keyframe Chunk IDs */ + KFDATA = 0xB000, + KFHDR = 0xB00A, + AMBIENT_NODE_TAG = 0xB001, + OBJECT_NODE_TAG = 0xB002, + CAMERA_NODE_TAG = 0xB003, + TARGET_NODE_TAG = 0xB004, + LIGHT_NODE_TAG = 0xB005, + L_TARGET_NODE_TAG = 0xB006, + SPOTLIGHT_NODE_TAG = 0xB007, + + KFSEG = 0xB008, + KFCURTIME = 0xB009, + + NODE_HDR = 0xB010, + INSTANCE_NAME = 0xB011, + PRESCALE = 0xB012, + PIVOT = 0xB013, + BOUNDBOX = 0xB014, + MORPH_SMOOTH = 0xB015, + POS_TRACK_TAG = 0xB020, + ROT_TRACK_TAG = 0xB021, + SCL_TRACK_TAG = 0xB022, + FOV_TRACK_TAG = 0xB023, + ROLL_TRACK_TAG = 0xB024, + COL_TRACK_TAG = 0xB025, + MORPH_TRACK_TAG = 0xB026, + HOT_TRACK_TAG = 0xB027, + FALL_TRACK_TAG = 0xB028, + HIDE_TRACK_TAG = 0xB029, + NODE_ID = 0xB030, + + + CMAGIC = 0xC23D, + + C_MDRAWER = 0xC010, + C_TDRAWER = 0xC020, + C_SHPDRAWER = 0xC030, + C_MODDRAWER = 0xC040, + C_RIPDRAWER = 0xC050, + C_TXDRAWER = 0xC060, + C_PDRAWER = 0xC062, + C_MTLDRAWER = 0xC064, + C_FLIDRAWER = 0xC066, + C_CUBDRAWER = 0xC067, + C_MFILE = 0xC070, + C_SHPFILE = 0xC080, + C_MODFILE = 0xC090, + C_RIPFILE = 0xC0A0, + C_TXFILE = 0xC0B0, + C_PFILE = 0xC0B2, + C_MTLFILE = 0xC0B4, + C_FLIFILE = 0xC0B6, + C_PALFILE = 0xC0B8, + C_TX_STRING = 0xC0C0, + C_CONSTS = 0xC0D0, + C_SNAPS = 0xC0E0, + C_GRIDS = 0xC0F0, + C_ASNAPS = 0xC100, + C_GRID_RANGE = 0xC110, + C_RENDTYPE = 0xC120, + C_PROGMODE = 0xC130, + C_PREVMODE = 0xC140, + C_MODWMODE = 0xC150, + C_MODMODEL = 0xC160, + C_ALL_LINES = 0xC170, + C_BACK_TYPE = 0xC180, + C_MD_CS = 0xC190, + C_MD_CE = 0xC1A0, + C_MD_SML = 0xC1B0, + C_MD_SMW = 0xC1C0, + C_LOFT_WITH_TEXTURE = 0xC1C3, + C_LOFT_L_REPEAT = 0xC1C4, + C_LOFT_W_REPEAT = 0xC1C5, + C_LOFT_UV_NORMALIZE = 0xC1C6, + C_WELD_LOFT = 0xC1C7, + C_MD_PDET = 0xC1D0, + C_MD_SDET = 0xC1E0, + C_RGB_RMODE = 0xC1F0, + C_RGB_HIDE = 0xC200, + C_RGB_MAPSW = 0xC202, + C_RGB_TWOSIDE = 0xC204, + C_RGB_SHADOW = 0xC208, + C_RGB_AA = 0xC210, + C_RGB_OVW = 0xC220, + C_RGB_OVH = 0xC230, + C_RGB_PICTYPE = 0xC240, + C_RGB_OUTPUT = 0xC250, + C_RGB_TODISK = 0xC253, + C_RGB_COMPRESS = 0xC254, + C_JPEG_COMPRESSION = 0xC255, + C_RGB_DISPDEV = 0xC256, + C_RGB_HARDDEV = 0xC259, + C_RGB_PATH = 0xC25A, + C_BITMAP_DRAWER = 0xC25B, + C_RGB_FILE = 0xC260, + C_RGB_OVASPECT = 0xC270, + + C_RGB_ANIMTYPE = 0xC271, + C_RENDER_ALL = 0xC272, + C_REND_FROM = 0xC273, + C_REND_TO = 0xC274, + C_REND_NTH = 0xC275, + C_PAL_TYPE = 0xC276, + C_RND_TURBO = 0xC277, + C_RND_MIP = 0xC278, + C_BGND_METHOD = 0xC279, + C_AUTO_REFLECT = 0xC27A, + C_VP_FROM = 0xC27B, + C_VP_TO = 0xC27C, + C_VP_NTH = 0xC27D, + C_REND_TSTEP = 0xC27E, + C_VP_TSTEP = 0xC27F, + + C_SRDIAM = 0xC280, + C_SRDEG = 0xC290, + C_SRSEG = 0xC2A0, + C_SRDIR = 0xC2B0, + C_HETOP = 0xC2C0, + C_HEBOT = 0xC2D0, + C_HEHT = 0xC2E0, + C_HETURNS = 0xC2F0, + C_HEDEG = 0xC300, + C_HESEG = 0xC310, + C_HEDIR = 0xC320, + C_QUIKSTUFF = 0xC330, + C_SEE_LIGHTS = 0xC340, + C_SEE_CAMERAS = 0xC350, + C_SEE_3D = 0xC360, + C_MESHSEL = 0xC370, + C_MESHUNSEL = 0xC380, + C_POLYSEL = 0xC390, + C_POLYUNSEL = 0xC3A0, + C_SHPLOCAL = 0xC3A2, + C_MSHLOCAL = 0xC3A4, + C_NUM_FORMAT = 0xC3B0, + C_ARCH_DENOM = 0xC3C0, + C_IN_DEVICE = 0xC3D0, + C_MSCALE = 0xC3E0, + C_COMM_PORT = 0xC3F0, + C_TAB_BASES = 0xC400, + C_TAB_DIVS = 0xC410, + C_MASTER_SCALES = 0xC420, + C_SHOW_1STVERT = 0xC430, + C_SHAPER_OK = 0xC440, + C_LOFTER_OK = 0xC450, + C_EDITOR_OK = 0xC460, + C_KEYFRAMER_OK = 0xC470, + C_PICKSIZE = 0xC480, + C_MAPTYPE = 0xC490, + C_MAP_DISPLAY = 0xC4A0, + C_TILE_XY = 0xC4B0, + C_MAP_XYZ = 0xC4C0, + C_MAP_SCALE = 0xC4D0, + C_MAP_MATRIX_OLD = 0xC4E0, + C_MAP_MATRIX = 0xC4E1, + C_MAP_WID_HT = 0xC4F0, + C_OBNAME = 0xC500, + C_CAMNAME = 0xC510, + C_LTNAME = 0xC520, + C_CUR_MNAME = 0xC525, + C_CURMTL_FROM_MESH = 0xC526, + C_GET_SHAPE_MAKE_FACES = 0xC527, + C_DETAIL = 0xC530, + C_VERTMARK = 0xC540, + C_MSHAX = 0xC550, + C_MSHCP = 0xC560, + C_USERAX = 0xC570, + C_SHOOK = 0xC580, + C_RAX = 0xC590, + C_STAPE = 0xC5A0, + C_LTAPE = 0xC5B0, + C_ETAPE = 0xC5C0, + C_KTAPE = 0xC5C8, + C_SPHSEGS = 0xC5D0, + C_GEOSMOOTH = 0xC5E0, + C_HEMISEGS = 0xC5F0, + C_PRISMSEGS = 0xC600, + C_PRISMSIDES = 0xC610, + C_TUBESEGS = 0xC620, + C_TUBESIDES = 0xC630, + C_TORSEGS = 0xC640, + C_TORSIDES = 0xC650, + C_CONESIDES = 0xC660, + C_CONESEGS = 0xC661, + C_NGPARMS = 0xC670, + C_PTHLEVEL = 0xC680, + C_MSCSYM = 0xC690, + C_MFTSYM = 0xC6A0, + C_MTTSYM = 0xC6B0, + C_SMOOTHING = 0xC6C0, + C_MODICOUNT = 0xC6D0, + C_FONTSEL = 0xC6E0, + C_TESS_TYPE = 0xC6f0, + C_TESS_TENSION = 0xC6f1, + + C_SEG_START = 0xC700, + C_SEG_END = 0xC705, + C_CURTIME = 0xC710, + C_ANIMLENGTH = 0xC715, + C_PV_FROM = 0xC720, + C_PV_TO = 0xC725, + C_PV_DOFNUM = 0xC730, + C_PV_RNG = 0xC735, + C_PV_NTH = 0xC740, + C_PV_TYPE = 0xC745, + C_PV_METHOD = 0xC750, + C_PV_FPS = 0xC755, + C_VTR_FRAMES = 0xC765, + C_VTR_HDTL = 0xC770, + C_VTR_HD = 0xC771, + C_VTR_TL = 0xC772, + C_VTR_IN = 0xC775, + C_VTR_PK = 0xC780, + C_VTR_SH = 0xC785, + +/* Material chunks */ + C_WORK_MTLS = 0xC790, /* Old-style -- now ignored */ + C_WORK_MTLS_2 = 0xC792, /* Old-style -- now ignored */ + C_WORK_MTLS_3 = 0xC793, /* Old-style -- now ignored */ + C_WORK_MTLS_4 = 0xC794, /* Old-style -- now ignored */ + C_WORK_MTLS_5 = 0xCB00, /* Old-style -- now ignored */ + C_WORK_MTLS_6 = 0xCB01, /* Old-style -- now ignored */ + C_WORK_MTLS_7 = 0xCB02, /* Old-style -- now ignored */ + C_WORK_MTLS_8 = 0xCB03, /* Old-style -- now ignored */ + C_WORKMTL = 0xCB04, + C_SXP_TEXT_DATA = 0xCB10, + C_SXP_TEXT2_DATA = 0xCB20, + C_SXP_OPAC_DATA = 0xCB11, + C_SXP_BUMP_DATA = 0xCB12, + C_SXP_SPEC_DATA = 0xCB24, + C_SXP_SHIN_DATA = 0xCB13, + C_SXP_SELFI_DATA = 0xCB28, + C_SXP_TEXT_MASKDATA = 0xCB30, + C_SXP_TEXT2_MASKDATA = 0xCB32, + C_SXP_OPAC_MASKDATA = 0xCB34, + C_SXP_BUMP_MASKDATA = 0xCB36, + C_SXP_SPEC_MASKDATA = 0xCB38, + C_SXP_SHIN_MASKDATA = 0xCB3A, + C_SXP_SELFI_MASKDATA = 0xC3C, + C_SXP_REFL_MASKDATA = 0xCB3E, + + C_BGTYPE = 0xC7A1, + C_MEDTILE = 0xC7B0, + +/* Contrast */ + C_LO_CONTRAST = 0xC7D0, + C_HI_CONTRAST = 0xC7D1, + +/* 3d frozen display */ + C_FROZ_DISPLAY = 0xC7E0, + +/* Booleans */ + C_BOOLWELD = 0xc7f0, + C_BOOLTYPE = 0xc7f1, + + C_ANG_THRESH = 0xC900, + C_SS_THRESH = 0xC901, + C_TEXTURE_BLUR_DEFAULT = 0xC903, + + C_MAPDRAWER = 0xCA00, + C_MAPDRAWER1 = 0xCA01, + C_MAPDRAWER2 = 0xCA02, + C_MAPDRAWER3 = 0xCA03, + C_MAPDRAWER4 = 0xCA04, + C_MAPDRAWER5 = 0xCA05, + C_MAPDRAWER6 = 0xCA06, + C_MAPDRAWER7 = 0xCA07, + C_MAPDRAWER8 = 0xCA08, + C_MAPDRAWER9 = 0xCA09, + C_MAPDRAWER_ENTRY = 0xCA10, + +/* System Options */ + C_BACKUP_FILE = 0xCA20, + C_DITHER_256 = 0xCA21, + C_SAVE_LAST = 0xCA22, + C_USE_ALPHA = 0xCA23, + C_TGA_DEPTH = 0xCA24, + C_REND_FIELDS = 0xCA25, + C_REFLIP = 0xCA26, + C_SEL_ITEMTOG = 0xCA27, + C_SEL_RESET = 0xCA28, + C_STICKY_KEYINF = 0xCA29, + C_WELD_THRESHOLD = 0xCA2A, + C_ZCLIP_POINT = 0xCA2B, + C_ALPHA_SPLIT = 0xCA2C, + C_KF_SHOW_BACKFACE = 0xCA30, + C_OPTIMIZE_LOFT = 0xCA40, + C_TENS_DEFAULT = 0xCA42, + C_CONT_DEFAULT = 0xCA44, + C_BIAS_DEFAULT = 0xCA46, + + C_DXFNAME_SRC = 0xCA50, + C_AUTO_WELD = 0xCA60, + C_AUTO_UNIFY = 0xCA70, + C_AUTO_SMOOTH = 0xCA80, + C_DXF_SMOOTH_ANG = 0xCA90, + C_SMOOTH_ANG = 0xCAA0, + +/* Special network-use chunks */ + C_NET_USE_VPOST = 0xCC00, + C_NET_USE_GAMMA = 0xCC10, + C_NET_FIELD_ORDER = 0xCC20, + + C_BLUR_FRAMES = 0xCD00, + C_BLUR_SAMPLES = 0xCD10, + C_BLUR_DUR = 0xCD20, + C_HOT_METHOD = 0xCD30, + C_HOT_CHECK = 0xCD40, + C_PIXEL_SIZE = 0xCD50, + C_DISP_GAMMA = 0xCD60, + C_FBUF_GAMMA = 0xCD70, + C_FILE_OUT_GAMMA = 0xCD80, + C_FILE_IN_GAMMA = 0xCD82, + C_GAMMA_CORRECT = 0xCD84, + C_APPLY_DISP_GAMMA = 0xCD90, /* OBSOLETE */ + C_APPLY_FBUF_GAMMA = 0xCDA0, /* OBSOLETE */ + C_APPLY_FILE_GAMMA = 0xCDB0, /* OBSOLETE */ + C_FORCE_WIRE = 0xCDC0, + C_RAY_SHADOWS = 0xCDD0, + C_MASTER_AMBIENT = 0xCDE0, + C_SUPER_SAMPLE = 0xCDF0, + C_OBJECT_MBLUR = 0xCE00, + C_MBLUR_DITHER = 0xCE10, + C_DITHER_24 = 0xCE20, + C_SUPER_BLACK = 0xCE30, + C_SAFE_FRAME = 0xCE40, + C_VIEW_PRES_RATIO = 0xCE50, + C_BGND_PRES_RATIO = 0xCE60, + C_NTH_SERIAL_NUM = 0xCE70, + + /* Video Post */ + VPDATA = 0xd000, + + P_QUEUE_ENTRY = 0xd100, + P_QUEUE_IMAGE = 0xd110, + P_QUEUE_USEIGAMMA = 0xd114, + P_QUEUE_PROC = 0xd120, + P_QUEUE_SOLID = 0xd130, + P_QUEUE_GRADIENT = 0xd140, + P_QUEUE_KF = 0xd150, + P_QUEUE_MOTBLUR = 0xd152, + P_QUEUE_MB_REPEAT = 0xd153, + P_QUEUE_NONE = 0xd160, + + P_QUEUE_RESIZE = 0xd180, + P_QUEUE_OFFSET = 0xd185, + P_QUEUE_ALIGN = 0xd190, + + P_CUSTOM_SIZE = 0xd1a0, + + P_ALPH_NONE = 0xd210, + P_ALPH_PSEUDO = 0xd220, /* Old chunk */ + P_ALPH_OP_PSEUDO = 0xd221, /* Old chunk */ + P_ALPH_BLUR = 0xd222, /* Replaces pseudo */ + P_ALPH_PCOL = 0xd225, + P_ALPH_C0 = 0xd230, + P_ALPH_OP_KEY = 0xd231, + P_ALPH_KCOL = 0xd235, + P_ALPH_OP_NOCONV = 0xd238, + P_ALPH_IMAGE = 0xd240, + P_ALPH_ALPHA = 0xd250, + P_ALPH_QUES = 0xd260, + P_ALPH_QUEIMG = 0xd265, + P_ALPH_CUTOFF = 0xd270, + P_ALPHANEG = 0xd280, + + P_TRAN_NONE = 0xd300, + P_TRAN_IMAGE = 0xd310, + P_TRAN_FRAMES = 0xd312, + P_TRAN_FADEIN = 0xd320, + P_TRAN_FADEOUT = 0xd330, + P_TRANNEG = 0xd340, + + P_RANGES = 0xd400, + + P_PROC_DATA = 0xd500 +}; + +struct Vector2f { + float x, y; +} [[static]]; + +struct Vector3f { + float x, y, z; +} [[static]]; + +bitfield FaceFlags { + CA_Visible : 1; + BC_Visible : 1; + AB_Visible : 1; + Mapped : 1; + padding : 9; + CA_Selected : 1; + BC_Selected : 1; + AB_Selected : 1; +}; + +struct Face { + u16 v0, v1,v2; + FaceFlags flags; +}; + +bitfield VertexFlags { + padding : 13; + selected3 : 1; + selected2 : 1; + selected1 : 1; +}; + +bitfield KeyFlags1 { + Show_Path : 1; + Smooth : 1; + padding : 2; + Motion_Blur : 1; + padding : 1; + Morph_Mat : 1; +}; + +bitfield KeyFlags2 { + padding : 10; + Hidden : 1; +}; + +struct RGB { + T r, g, b; +}; + +bitfield Spline { + Use_Tension : 1; + Use_Continuity : 1; + Use_Bias : 1; + Use_Ease_To : 1; + Use_Ease_From : 1; + + padding : 3; + + if (Use_Tension == 1) + float Tension; + if (Use_Continuity == 1) + float Continuity; + if (Use_Bias == 1) + float Bias; + if (Use_Ease_To == 1) + float Ease_To; + if (Use_Ease_From == 1) + float Ease_From; + + padding : 8; +}; + +struct VectorKey { + u32 index; + Spline splineData; + Vector3f value; +}; + +struct RotationKey { + u32 index; + Spline splineData; + float angle; + Vector3f vector; +}; + +struct AngleKey { + u32 index; + Spline splineData; + float angle; +}; + +struct MorphKey{ + u32 index; + Spline splineData; + char objectName[]; +}; + +struct HideKey { + u32 index; + Spline splineData; +}; + +struct Keys { + u32 count; + match (identifier) { + ( + ChunkIdentifier::POS_TRACK_TAG | + ChunkIdentifier::SCL_TRACK_TAG | + ChunkIdentifier::COL_TRACK_TAG + ) : { + VectorKey data[count]; + } + + ( + ChunkIdentifier::ROT_TRACK_TAG + ) : { + RotationKey data[count]; + } + + ( + ChunkIdentifier::FOV_TRACK_TAG | + ChunkIdentifier::ROLL_TRACK_TAG | + ChunkIdentifier::HOT_TRACK_TAG | + ChunkIdentifier::FALL_TRACK_TAG + ) : { + AngleKey data[count]; + } + + ( + ChunkIdentifier::MORPH_TRACK_TAG + ) : { + MorphKey data[count]; + } + + ( + ChunkIdentifier::HIDE_TRACK_TAG + ) : { + HideKey data[count]; + } + } +}; + +enum TrackMode : u16 { + MODE_SINGLE = 0, + MODE_REPEAT = 1, + MODE_LOOP = 2, +}; + +bitfield TrackFlags { + TrackMode Mode : 2; + padding : 1; + Lock_X : 1; + Lock_Y : 1; + Lock_Z : 1; + padding : 1; + Unlink_X : 1; + Unlink_Y : 1; + Unlink_Z : 1; +}; + +struct Chunk { + ChunkIdentifier identifier; + u32 chunkSize; + u32 dataLength = chunkSize - 6 [[export]]; + u32 chunkEnd = $ + dataLength; + + if (chunkSize > 0) { + std::print("{}", identifier); + match (identifier) { + ( + ChunkIdentifier::M3DMAGIC | + ChunkIdentifier::MDATA | + ChunkIdentifier::N_TRI_OBJECT | + ChunkIdentifier::KFDATA | + ChunkIdentifier::AMBIENT_NODE_TAG | + ChunkIdentifier::OBJECT_NODE_TAG | + ChunkIdentifier::CAMERA_NODE_TAG | + ChunkIdentifier::TARGET_NODE_TAG | + ChunkIdentifier::LIGHT_NODE_TAG | + ChunkIdentifier::L_TARGET_NODE_TAG | + ChunkIdentifier::SPOTLIGHT_NODE_TAG | + ChunkIdentifier::MAT_ENTRY | + ChunkIdentifier::MAT_AMBIENT | + ChunkIdentifier::MAT_DIFFUSE | + ChunkIdentifier::MAT_SPECULAR | + ChunkIdentifier::MAT_SHININESS | + ChunkIdentifier::MAT_SHIN2PCT | + ChunkIdentifier::MAT_SHIN3PCT | + ChunkIdentifier::MAT_TRANSPARENCY | + ChunkIdentifier::MAT_XPFALL | + ChunkIdentifier::MAT_REFBLUR | + ChunkIdentifier::MAT_SELF_ILPCT | + ChunkIdentifier::MAT_TEXMAP | + ChunkIdentifier::MAT_SPECMAP | + ChunkIdentifier::MAT_OPACMAP | + ChunkIdentifier::MAT_REFLMAP | + ChunkIdentifier::MAT_BUMPMAP | + ChunkIdentifier::MAT_BUMP_PERCENT | + ChunkIdentifier::MAT_TEX2MAP | + ChunkIdentifier::MAT_SHINMAP | + ChunkIdentifier::MAT_SELFIMAP | + ChunkIdentifier::MAT_TEXMASK | + ChunkIdentifier::MAT_TEX2MASK | + ChunkIdentifier::MAT_OPACMASK | + ChunkIdentifier::MAT_BUMPMASK | + ChunkIdentifier::MAT_SHINMASK | + ChunkIdentifier::MAT_SPECMASK | + ChunkIdentifier::MAT_SELFIMASK | + ChunkIdentifier::MAT_REFLMASK | + ChunkIdentifier::WORLD_VIEWPORT_DATA | + ChunkIdentifier::WORLD_VIEWPORT_DATA3 | + ChunkIdentifier::WORLD_VIEWPORT_LAYOUT | + ChunkIdentifier::SOLID_BGND | + ChunkIdentifier::AMBIENT_LIGHT + ): { + Chunk chunks[while($ < chunkEnd)]; + } + + ( + ChunkIdentifier::M3D_VERSION | + ChunkIdentifier::MESH_VERSION + ): { + u32 version; + } + + ( + ChunkIdentifier::LO_SHADOW_BIAS | + ChunkIdentifier::HI_SHADOW_BIAS | + ChunkIdentifier::SHADOW_FILTER | + ChunkIdentifier::RAY_BIAS | + ChunkIdentifier::FLOAT_PERCENTAGE | + ChunkIdentifier::MASTER_SCALE | + ChunkIdentifier::MAT_MAP_TEXBLUR | + ChunkIdentifier::MAT_MAP_USCALE | + ChunkIdentifier::MAT_MAP_VSCALE | + ChunkIdentifier::MAT_MAP_UOFFSET | + ChunkIdentifier::MAT_MAP_VOFFSET | + ChunkIdentifier::MAT_MAP_ANG | + ChunkIdentifier::MAT_WIRESIZE | + ChunkIdentifier::DL_SPOT_ROLL | + ChunkIdentifier::MORPH_SMOOTH + ): { + float value; + } + + ( + ChunkIdentifier::V_GRADIENT + ) : { + float position; + Chunk chunks[while($ < chunkEnd)]; + } + + ( + ChunkIdentifier::NAMED_OBJECT + ) : { + char name[]; + Chunk chunks[while($ < chunkEnd)]; + } + + ( + ChunkIdentifier::POINT_ARRAY + ) : { + u16 count; + Vector3f vectices[count] [[hex::visualize("3d", this, null)]]; + } + + ( + ChunkIdentifier::TEX_VERTS + ) : { + u16 count; + Vector2f coords[count]; + } + + ( + ChunkIdentifier::MESH_MATRIX + ) : { + Vector3f x, y, z, w; + } + + ( + ChunkIdentifier::FACE_ARRAY + ) : { + u16 count; + Face faces[count]; + Chunk chunks[while($ < chunkEnd)]; + } + + ( + ChunkIdentifier::POINT_FLAG_ARRAY + ) : { + u16 count; + VertexFlags flags[count]; + } + + ( + ChunkIdentifier::SMOOTH_GROUP + ) : { + u32 groups[dataLength / sizeof(u32)]; + } + + ( + ChunkIdentifier::MESH_COLOR + ) : { + u8 value; + } + + ( + ChunkIdentifier::MSH_MAT_GROUP + ) : { + char name[]; + u16 count; + u16 groups[count]; + } + + ( + ChunkIdentifier::KFHDR + ) : { + u16 revision; + char name[]; + u32 animationLength; + } + + ( + ChunkIdentifier::KFSEG + ) : { + u32 start, end; + } + + ( + ChunkIdentifier::KFCURTIME + ) : { + u32 frameIndex; + } + + ( + ChunkIdentifier::NODE_ID + ) : { + type::Hex id; + } + + ( + ChunkIdentifier::NODE_HDR + ) : { + char name[]; + padding[1]; + KeyFlags1 flags1; + KeyFlags2 flags2; + type::Hex parentId; + } + + ( + ChunkIdentifier::PIVOT + ) : { + Vector3f value; + } + + ( + ChunkIdentifier::BOUNDBOX + ) : { + Vector3f min, max; + } + + ( + ChunkIdentifier::COLOR_24 | + ChunkIdentifier::LIN_COLOR_24 + ) : { + RGB color; + } + + ( + ChunkIdentifier::COLOR_F | + ChunkIdentifier::LIN_COLOR_F + ) : { + RGB color; + } + + ( + ChunkIdentifier::INT_PERCENTAGE | + ChunkIdentifier::MAT_BUMP_PERCENT + ) : { + u16 value; + } + + ( + ChunkIdentifier::SHADOW_MAP_SIZE | + ChunkIdentifier::MAT_SHADING + ) : { + u16 value; + } + + ( + ChunkIdentifier::POS_TRACK_TAG | + ChunkIdentifier::ROT_TRACK_TAG | + ChunkIdentifier::SCL_TRACK_TAG | + ChunkIdentifier::FOV_TRACK_TAG | + ChunkIdentifier::ROLL_TRACK_TAG | + ChunkIdentifier::COL_TRACK_TAG | + ChunkIdentifier::MORPH_TRACK_TAG | + ChunkIdentifier::HOT_TRACK_TAG | + ChunkIdentifier::FALL_TRACK_TAG | + ChunkIdentifier::HIDE_TRACK_TAG + ) : { + TrackFlags flags; + u8 unknown[8]; + Keys keys; + } + + ( + ChunkIdentifier::INSTANCE_NAME | + ChunkIdentifier::BIT_MAP | + ChunkIdentifier::DL_SPOT_PROJECTOR | + ChunkIdentifier::MAT_NAME | + ChunkIdentifier::MAT_MAPNAME + ) : { + char name[]; + } + + ( + ChunkIdentifier::MAT_MAP_TILING + ) : { + u16 tiling; + } + + ( + ChunkIdentifier::WORLD_VIEWPORT_SIZE + ) : { + u16 x, y, w, h; + } + + ( + ChunkIdentifier::N_DIRECT_LIGHT + ) : { + Vector3f position; + Chunk chunks[while($ < chunkEnd)]; + } + + ( + ChunkIdentifier::DL_SPOTLIGHT + ) : { + Vector3f target; + float hotspot, falloff; + Chunk chunks[while($ < chunkEnd)]; + } + + ( + ChunkIdentifier::N_CAMERA + ) : { + Vector3f position, target; + float roll, fov; + } + + + + (_) : { + std::warning(std::format("Unhandled Chunk ID: {}, Skipping 0x{:04X} bytes", identifier, dataLength)); + $ += dataLength; + } + } + } +}; + Chunk chunk @ 0x00; \ No newline at end of file diff --git a/patterns/7z.hexpat b/patterns/7z.hexpat index 7fddee7e..bda9ae3d 100644 --- a/patterns/7z.hexpat +++ b/patterns/7z.hexpat @@ -1,3 +1,5 @@ +#pragma description 7z File Format + #include #include #include diff --git a/patterns/Crashlvl.hexpat b/patterns/Crashlvl.hexpat index 37edf6a0..5687e73d 100644 --- a/patterns/Crashlvl.hexpat +++ b/patterns/Crashlvl.hexpat @@ -1,3 +1,5 @@ +#pragma description Crash Bandicoot - Back in Time (fan game) User created flashback tapes level format + #include #include #include diff --git a/patterns/afe2.hexpat b/patterns/afe2.hexpat index 28577c9c..80fd6146 100644 --- a/patterns/afe2.hexpat +++ b/patterns/afe2.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Nintendo Switch Atmosphère CFW Fatal Error log + #pragma endian little #include diff --git a/patterns/ar.hexpat b/patterns/ar.hexpat index 9c754b20..1c95964d 100644 --- a/patterns/ar.hexpat +++ b/patterns/ar.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Static library archive files + #pragma MIME application/x-archive #include diff --git a/patterns/arm_cm_vtor.hexpat b/patterns/arm_cm_vtor.hexpat index 1c10969a..d95f7e58 100644 --- a/patterns/arm_cm_vtor.hexpat +++ b/patterns/arm_cm_vtor.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description ARM Cortex M Vector Table Layout + #pragma endian little #include diff --git a/patterns/bencode.hexpat b/patterns/bencode.hexpat index 0065c03d..49f3b729 100644 --- a/patterns/bencode.hexpat +++ b/patterns/bencode.hexpat @@ -1,73 +1,76 @@ -#pragma MIME application/x-bittorrent - -#include -#include -#include - -namespace bencode { - - struct ASCIIDecimal { - char value[while(std::ctype::isdigit(std::mem::read_unsigned($, 1)))]; - } [[sealed, format("bencode::format_ascii_decimal"), transform("bencode::format_ascii_decimal")]]; - - fn format_ascii_decimal(ASCIIDecimal adsasd) { - return std::string::parse_int(adsasd.value, 10); - }; - - enum Type : u8 { - Integer = 'i', - Dictionary = 'd', - List = 'l', - - String0 = '0', - String1 = '1', - String2 = '2', - String3 = '3', - String4 = '4', - String5 = '5', - String6 = '6', - String7 = '7', - String8 = '8', - String9 = '9' - }; - - struct String { - ASCIIDecimal length; - char separator [[hidden]]; - char value[length]; - } [[sealed, format("bencode::format_string"), transform("bencode::format_string")]]; - - fn format_string(String string) { - return string.value; - }; - - using Bencode; - using Value; - - struct DictionaryEntry { - String key; - Value value; - }; - - struct Value { - Type type; - - if (type == Type::Dictionary) { - DictionaryEntry entry[while(std::mem::read_unsigned($, 1) != 'e')]; - } else if (type == Type::Integer) { - ASCIIDecimal value; - char end; - } else { - $ -= 1; - String value; - } - }; - - struct Bencode { - Value value[while(!std::mem::eof())] [[inline]]; - char end; - }; - -} - -bencode::Bencode bencode @ 0x00; +#pragma author WerWolv +#pragma description Bencode encoding, used by Torrent files + +#pragma MIME application/x-bittorrent + +#include +#include +#include + +namespace bencode { + + struct ASCIIDecimal { + char value[while(std::ctype::isdigit(std::mem::read_unsigned($, 1)))]; + } [[sealed, format("bencode::format_ascii_decimal"), transform("bencode::format_ascii_decimal")]]; + + fn format_ascii_decimal(ASCIIDecimal adsasd) { + return std::string::parse_int(adsasd.value, 10); + }; + + enum Type : u8 { + Integer = 'i', + Dictionary = 'd', + List = 'l', + + String0 = '0', + String1 = '1', + String2 = '2', + String3 = '3', + String4 = '4', + String5 = '5', + String6 = '6', + String7 = '7', + String8 = '8', + String9 = '9' + }; + + struct String { + ASCIIDecimal length; + char separator [[hidden]]; + char value[length]; + } [[sealed, format("bencode::format_string"), transform("bencode::format_string")]]; + + fn format_string(String string) { + return string.value; + }; + + using Bencode; + using Value; + + struct DictionaryEntry { + String key; + Value value; + }; + + struct Value { + Type type; + + if (type == Type::Dictionary) { + DictionaryEntry entry[while(std::mem::read_unsigned($, 1) != 'e')]; + } else if (type == Type::Integer) { + ASCIIDecimal value; + char end; + } else { + $ -= 1; + String value; + } + }; + + struct Bencode { + Value value[while(!std::mem::eof())] [[inline]]; + char end; + }; + +} + +bencode::Bencode bencode @ 0x00; diff --git a/patterns/bmp.hexpat b/patterns/bmp.hexpat index 4fb201de..861acba8 100644 --- a/patterns/bmp.hexpat +++ b/patterns/bmp.hexpat @@ -1,3 +1,5 @@ +#pragma description OS2/Windows Bitmap files + #pragma MIME image/bmp #pragma endian little #include diff --git a/patterns/bson.hexpat b/patterns/bson.hexpat index 85f30261..8ca8d3cd 100644 --- a/patterns/bson.hexpat +++ b/patterns/bson.hexpat @@ -1,128 +1,131 @@ -#pragma MIME application/bson - -#include - -enum Type : u8 { - Double = 0x01, - String = 0x02, - EmbeddedDocument = 0x03, - Array = 0x04, - Binary = 0x05, - Undefined = 0x06, - ObjectId = 0x07, - Boolean = 0x08, - UTCDatetime = 0x09, - Null = 0x0A, - Regex = 0x0B, - DBPointer = 0x0C, - JavaScript = 0x0D, - Symbol = 0x0E, - JavaScriptWithScope = 0x0F, - Int32 = 0x10, - Timestamp = 0x11, - Int64 = 0x12, - Decimal128 = 0x13, - - MinKey = 0xFF, - MaxKey = 0x7F -}; - -enum Subtype : u8 { - GenericBinarySubtype = 0x00, - Function = 0x01, - BinaryOld = 0x02, - UUIDOld = 0x03, - UUID = 0x04, - MD5 = 0x05, - EncryptedBSONValue = 0x06, - CompressedBSONColumn = 0x07, - UserDefined = 0x80 -}; - -struct Binary { - s32 length; - Subtype subtype; - u8 data[length]; -}; - -struct String { - u32 length [[hidden]]; - char value[length]; -} [[sealed, format("format_string")]]; - -struct CString { - char value[]; -} [[sealed, format("format_string")]]; - -fn format_string(auto string) { - return string.value; -}; - -struct ObjectId { - type::time32_t timestamp; - u8 randomValue[5]; - u24 counter; -}; - -struct DBPointer { - String name; - ObjectId value; -}; - - -using Document; - -struct Element { - Type type; - - CString name; - - if (type == Type::Double) { - double value; - } else if (type == Type::String) { - String value; - } else if (type == Type::EmbeddedDocument) { - Document value; - } else if (type == Type::Array) { - Document value; - } else if (type == Type::Binary) { - Binary value; - } else if (type == Type::Undefined) { - /* undefined */ - } else if (type == Type::ObjectId) { - ObjectId value; - } else if (type == Type::Boolean) { - bool value; - } else if (type == Type::UTCDatetime) { - type::time64_t value; - } else if (type == Type::Null) { - /* null */ - } else if (type == Type::Regex) { - CString regexPattern; - CString regexOptions; - } else if (type == Type::DBPointer) { - DBPointer value; - } else if (type == Type::JavaScript) { - String value; - } else if (type == Type::Symbol) { - String value; - } else if (type == Type::JavaScriptWithScope) { - String value; - } else if (type == Type::Int32) { - s32 value; - } else if (type == Type::Timestamp) { - u64 value; - } else if (type == Type::Int64) { - s64 value; - } else if (type == Type::Decimal128) { - u128 value; - } -}; - -struct Document { - s32 listLength; - Element elements[while($ < ((addressof(this) + listLength) - 1))]; - padding[1]; -}; - +#pragma author WerWolv +#pragma description BSON (Binary JSON) format + +#pragma MIME application/bson + +#include + +enum Type : u8 { + Double = 0x01, + String = 0x02, + EmbeddedDocument = 0x03, + Array = 0x04, + Binary = 0x05, + Undefined = 0x06, + ObjectId = 0x07, + Boolean = 0x08, + UTCDatetime = 0x09, + Null = 0x0A, + Regex = 0x0B, + DBPointer = 0x0C, + JavaScript = 0x0D, + Symbol = 0x0E, + JavaScriptWithScope = 0x0F, + Int32 = 0x10, + Timestamp = 0x11, + Int64 = 0x12, + Decimal128 = 0x13, + + MinKey = 0xFF, + MaxKey = 0x7F +}; + +enum Subtype : u8 { + GenericBinarySubtype = 0x00, + Function = 0x01, + BinaryOld = 0x02, + UUIDOld = 0x03, + UUID = 0x04, + MD5 = 0x05, + EncryptedBSONValue = 0x06, + CompressedBSONColumn = 0x07, + UserDefined = 0x80 +}; + +struct Binary { + s32 length; + Subtype subtype; + u8 data[length]; +}; + +struct String { + u32 length [[hidden]]; + char value[length]; +} [[sealed, format("format_string")]]; + +struct CString { + char value[]; +} [[sealed, format("format_string")]]; + +fn format_string(auto string) { + return string.value; +}; + +struct ObjectId { + type::time32_t timestamp; + u8 randomValue[5]; + u24 counter; +}; + +struct DBPointer { + String name; + ObjectId value; +}; + + +using Document; + +struct Element { + Type type; + + CString name; + + if (type == Type::Double) { + double value; + } else if (type == Type::String) { + String value; + } else if (type == Type::EmbeddedDocument) { + Document value; + } else if (type == Type::Array) { + Document value; + } else if (type == Type::Binary) { + Binary value; + } else if (type == Type::Undefined) { + /* undefined */ + } else if (type == Type::ObjectId) { + ObjectId value; + } else if (type == Type::Boolean) { + bool value; + } else if (type == Type::UTCDatetime) { + type::time64_t value; + } else if (type == Type::Null) { + /* null */ + } else if (type == Type::Regex) { + CString regexPattern; + CString regexOptions; + } else if (type == Type::DBPointer) { + DBPointer value; + } else if (type == Type::JavaScript) { + String value; + } else if (type == Type::Symbol) { + String value; + } else if (type == Type::JavaScriptWithScope) { + String value; + } else if (type == Type::Int32) { + s32 value; + } else if (type == Type::Timestamp) { + u64 value; + } else if (type == Type::Int64) { + s64 value; + } else if (type == Type::Decimal128) { + u128 value; + } +}; + +struct Document { + s32 listLength; + Element elements[while($ < ((addressof(this) + listLength) - 1))]; + padding[1]; +}; + Document document @ 0x00; \ No newline at end of file diff --git a/patterns/bsp_goldsrc.hexpat b/patterns/bsp_goldsrc.hexpat index 4f3058c0..aa64771a 100644 --- a/patterns/bsp_goldsrc.hexpat +++ b/patterns/bsp_goldsrc.hexpat @@ -1,3 +1,5 @@ +#pragma description GoldSrc engine maps format (used in Half-Life 1) + #include #include #include diff --git a/patterns/cchva.hexpat b/patterns/cchva.hexpat index 971009c7..dc729261 100644 --- a/patterns/cchva.hexpat +++ b/patterns/cchva.hexpat @@ -1,3 +1,5 @@ +#pragma description Command and Conquer Voxel Animation + // Command and conquer voxel animation format struct vec4_s { diff --git a/patterns/ccpal.hexpat b/patterns/ccpal.hexpat index c7d7c134..ffda525d 100644 --- a/patterns/ccpal.hexpat +++ b/patterns/ccpal.hexpat @@ -1,3 +1,5 @@ +#pragma description Command and Conquer Voxel Palette + // Command and conquer palette format struct Color { diff --git a/patterns/ccvxl.hexpat b/patterns/ccvxl.hexpat index dcda5c35..eb914c4a 100644 --- a/patterns/ccvxl.hexpat +++ b/patterns/ccvxl.hexpat @@ -1,3 +1,5 @@ +#pragma description Command and Conquer Voxel Model + // Command and Conquer voxel model format struct vec4_s { diff --git a/patterns/cda.hexpat b/patterns/cda.hexpat index 0df588f5..c8194149 100644 --- a/patterns/cda.hexpat +++ b/patterns/cda.hexpat @@ -1,3 +1,5 @@ +#pragma description Compact Disc Audio track + struct Header { u32 RIFF; s32 size; diff --git a/patterns/chm.hexpat b/patterns/chm.hexpat index b5e3bf02..bb029c2a 100644 --- a/patterns/chm.hexpat +++ b/patterns/chm.hexpat @@ -1,395 +1,398 @@ -#include -#include -#include -#include -#include - -enum WindowsLanguageId : u32 { - Arabic_SaudiArabia = 0x401, - Arabic_Iraq = 0x801, - Arabic_Egypt = 0xc01, - Arabic_Libya = 0x1001, - Arabic_Algeria = 0x1401, - Arabic_Morocco = 0x1801, - Arabic_Tunisia = 0x1c01, - Arabic_Oman = 0x2001, - Arabic_Yemen = 0x2401, - Arabic_Syria = 0x2801, - Arabic_Jordan = 0x2c01, - Arabic_Lebanon = 0x3001, - Arabic_Kuwait = 0x3401, - Arabic_UAE = 0x3801, - Arabic_Bahrain = 0x3c01, - Arabic_Qatar = 0x4001, - Bulgarian = 0x402, - Catalan = 0x403, - Valencian = 0x803, - Chinese_Taiwan = 0x404, - Chinese_PRC = 0x804, - Chinese_HongKongSAR = 0xc04, - Chinese_Singapore = 0x1004, - Chinese_MacaoSAR = 0x1404, - Czech = 0x405, - Danish = 0x406, - German_Germany = 0x407, - German_Switzerland = 0x807, - German_Austria = 0xc07, - German_Luxembourg = 0x1007, - German_Liechtenstein = 0x1407, - Greek = 0x408, - English_UnitedStates = 0x409, - English_UnitedKingdom = 0x809, - English_Australia = 0xc09, - English_Canada = 0x1009, - English_NewZealand = 0x1409, - English_Ireland = 0x1809, - English_SouthAfrica = 0x1c09, - English_Jamaica = 0x2009, - English_Caribbean = 0x2409, - English_Belize = 0x2809, - English_TrinidadandTobago = 0x2c09, - English_Zimbabwe = 0x3009, - English_Philippines = 0x3409, - English_Indonesia = 0x3809, - English_HongKongSAR = 0x3c09, - English_India = 0x4009, - English_Malaysia = 0x4409, - English_Singapore = 0x4809, - Spanish_SpainTraditionalSort = 0x40a, - Spanish_Mexico = 0x80a, - Spanish_Spain = 0xc0a, - Spanish_Guatemala = 0x100a, - Spanish_CostaRica = 0x140a, - Spanish_Panama = 0x180a, - Spanish_DominicanRepublic = 0x1c0a, - Spanish_Venezuela = 0x200a, - Spanish_Colombia = 0x240a, - Spanish_Peru = 0x280a, - Spanish_Argentina = 0x2c0a, - Spanish_Ecuador = 0x300a, - Spanish_Chile = 0x340a, - Spanish_Uruguay = 0x380a, - Spanish_Paraguay = 0x3c0a, - Spanish_Bolivia = 0x400a, - Spanish_ElSalvador = 0x440a, - Spanish_Honduras = 0x480a, - Spanish_Nicaragua = 0x4c0a, - Spanish_PuertoRico = 0x500a, - Spanish_UnitedStates = 0x540a, - Spanish_LatinAmerica = 0x580a, - Finnish = 0x40b, - French_France = 0x40c, - French_Belgium = 0x80c, - French_Canada = 0xc0c, - French_Switzerland = 0x100c, - French_Luxembourg = 0x140c, - French_Monaco = 0x180c, - French_Caribbean = 0x1c0c, - French_Reunion = 0x200c, - French_CongoDRC = 0x240c, - French_Senegal = 0x280c, - French_Cameroon = 0x2c0c, - French_CoteDIvoire = 0x300c, - French_Mali = 0x340c, - French_Morocco = 0x380c, - French_Haiti = 0x3c0c, - Hebrew = 0x40d, - Hungarian = 0x40e, - Icelandic = 0x40f, - Italian_Italy = 0x410, - Italian_Switzerland = 0x810, - Japanese = 0x411, - Korean = 0x412, - Dutch_Netherlands = 0x413, - Dutch_Belgium = 0x813, - Norwegian_Bokmal = 0x414, - Norwegian_Nynorsk = 0x814, - Polish = 0x415, - Portuguese_Brazil = 0x416, - Portuguese_Portugal = 0x816, - Romansh = 0x417, - Romanian = 0x418, - Romanian_Moldova = 0x818, - Russian = 0x419, - Russian_Moldova = 0x819, - Croatian_Croatia = 0x41a, - Serbian_LatinSerbiaandMontenegroFormer = 0x81a, - Serbian_CyrillicSerbiaAndMontenegroFormer = 0xc1a, - Croatian_BosniaAndHerzegovina = 0x101a, - Bosnian_Latin = 0x141a, - Serbian_LatinBosniaAndHerzegovina = 0x181a, - Serbian_CyrillicBosniaAndHerzegovina = 0x1c1a, - Bosnian_Cyrillic = 0x201a, - Serbian_LatinSerbia = 0x241a, - Serbian_CyrillicSerbia = 0x281a, - Serbian_LatinMontenegro = 0x2c1a, - Serbian_CyrillicMontenegro = 0x301a, - Slovak = 0x41b, - Albanian = 0x41c, - Swedish_Sweden = 0x41d, - Swedish_Finland = 0x81d, - Thai = 0x41e, - Turkish = 0x41f, - Urdu_Pakistan = 0x420, - Urdu_India = 0x820, - Indonesian = 0x421, - Ukrainian = 0x422, - Belarusian = 0x423, - Slovenian = 0x424, - Estonian = 0x425, - Latvian = 0x426, - Lithuanian = 0x427, - Tajik = 0x428, - Persian = 0x429, - Vietnamese = 0x42a, - Armenian = 0x42b, - Azerbaijani_Latin = 0x42c, - Azerbaijani_Cyrillic = 0x82c, - Basque = 0x42d, - UpperSorbian = 0x42e, - LowerSorbian = 0x82e, - Macedonian = 0x42f, - Sesotho_SouthAfrica = 0x430, - Xitsonga = 0x431, - Setswana_SouthAfrica = 0x432, - Setswana_Botswana = 0x832, - Venda = 0x433, - isiXhosa = 0x434, - isiZulu = 0x435, - Afrikaans = 0x436, - Georgian = 0x437, - Faroese = 0x438, - Hindi = 0x439, - Maltese = 0x43a, - NorthernSami_Norway = 0x43b, - NorthernSami_Sweden = 0x83b, - NorthernSami_Finland = 0xc3b, - LuleSami_Norway = 0x103b, - LuleSami_Sweden = 0x143b, - SouthernSami_Norway = 0x183b, - SouthernSami_Sweden = 0x1c3b, - SkoltSami_Finland = 0x203b, - InariSami_Finland = 0x243b, - Irish = 0x83c, - Yiddish = 0x43d, - Malay_Malaysia = 0x43e, - Malay_BruneiDarussalam = 0x83e, - Kazakh = 0x43f, - Kyrgyz = 0x440, - Kiswahili = 0x441, - Turkmen = 0x442, - Uzbek_Latin = 0x443, - Uzbek_Cyrillic = 0x843, - Tatar = 0x444, - Bangla_India = 0x445, - Bangla_Bangladesh = 0x845, - Punjabi_India = 0x446, - Punjabi_Pakistan = 0x846, - Gujarati = 0x447, - Odia = 0x448, - Tamil_India = 0x449, - Tamil_SriLanka = 0x849, - Telugu = 0x44a, - Kannada = 0x44b, - Malayalam = 0x44c, - Assamese = 0x44d, - Marathi = 0x44e, - Sanskrit = 0x44f, - Mongolian_Cyrillic = 0x450, - Mongolian_TraditionalMongolianPRC = 0x850, - Mongolian_TraditionalMongolianMongolia = 0xc50, - Tibetan_PRC = 0x451, - Welsh = 0x452, - Khmer = 0x453, - Lao = 0x454, - Burmese = 0x455, - Galician = 0x456, - Konkani = 0x457, - Manipuri = 0x458, - Sindhi_Devanagari = 0x459, - Sindhi_Arabic = 0x859, - Syriac = 0x45a, - Sinhala = 0x45b, - Cherokee_Cherokee = 0x45c, - Inuktitut_Syllabics = 0x45d, - Inuktitut_Latin = 0x85d, - Amharic = 0x45e, - Tamazight_ArabicMorocco = 0x45f, - Tamazight_LatinAlgeria = 0x85f, - Tamazight_TifinaghMorocco = 0x105f, - Kashmiri_Arabic = 0x460, - Kashmiri = 0x860, - Nepali = 0x461, - Nepali_India = 0x861, - Frisian = 0x462, - Pashto = 0x463, - Filipino = 0x464, - Divehi = 0x465, - Edo = 0x466, - Fulah_Nigeria = 0x467, - Fulah_LatinSenegal = 0x867, - Hausa = 0x468, - Ibibio_Nigeria = 0x469, - Yoruba = 0x46a, - Quechua_Bolivia = 0x46b, - Quechua_Ecuador = 0x86b, - Quechua_Peru = 0xc6b, - SesothoSaLeboa = 0x46c, - Bashkir = 0x46d, - Luxembourgish = 0x46e, - Greenlandic = 0x46f, - Igbo = 0x470, - Kanuri = 0x471, - Oromo = 0x472, - Tigrinya_Ethiopia = 0x473, - Tigrinya_Eritrea = 0x873, - Guarani = 0x474, - Hawaiian = 0x475, - Latin = 0x476, - Somali = 0x477, - Yi_PRC = 0x478, - Papiamentu = 0x479, - Mapudungun = 0x47a, - Mohawk = 0x47c, - Breton = 0x47e, - Uyghur_PRC = 0x480, - Maori = 0x481, - Occitan = 0x482, - Corsican = 0x483, - Alsatian = 0x484, - Sakha = 0x485, - Kiche = 0x486, - Kinyarwanda = 0x487, - Wolof = 0x488, - Dari = 0x48c, - ScottishGaelic_UnitedKingdom = 0x491, - CentralKurdish_Iraq = 0x492 -}; - -struct DirectoryListingEntry { - type::LEB128 nameLength; - char name[nameLength]; - type::LEB128 contentSection; - type::LEB128 offset; - type::LEB128 length; -}; - -struct DirectoryIndexEntry { - type::LEB128 nameLength; - char name[nameLength]; - type::LEB128 directoryListingChunk; -}; - -struct ListingChunk { - char magic[4]; - - if (magic == "PMGL") { - type::Size freeSpaceLength; - u32; - u32 prevChunkNumber, nextChunkNumber; - - u16 directoryListingEntryCount @ addressof(this) + parent.directoryChunkSize - 2; - u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryListingEntryCount) - (freeSpaceLength - 2); - - DirectoryListingEntry directories[directoryListingEntryCount]; - - $ = addressof(directoryListingEntryCount) + sizeof(directoryListingEntryCount); - } else if (magic == "PMGI") { - type::Size freeSpaceLength; - - u16 directoryIndexEntryCount @ addressof(this) + parent.directoryChunkSize - 2; - u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryIndexEntryCount) - (freeSpaceLength - 2); - - DirectoryIndexEntry indexes[directoryIndexEntryCount]; - - $ = addressof(directoryIndexEntryCount) + sizeof(directoryIndexEntryCount); - } else { - std::error("Invalid chunk magic!"); - } -}; - -struct HeaderSection { - char magic[4]; - - if (magic == "\xFE\x01\x00\x00") { - u32; - type::Size fileSize; - u32; - u32; - } else if (magic == "ITSP") { - u32 version; - type::Size directoryHeaderLength1; - u32; - u32 directoryChunkSize; - u32 quickRefSectionDensity; - u32 indexTreeDepth; - u32 rootIndexChunkNumber; - u32 firstPMGLChunkNumber; - u32 lastPMGLChunkNumber; - u32; - u32 directoryChunkCount; - WindowsLanguageId languageId; - type::GUID guid; - type::Size directoryHeaderLength2; - u32; - u32; - u32; - - ListingChunk chunk[directoryChunkCount]; - } else { - std::error("Invalid header section magic!"); - } -}; - -struct HeaderSectionTableEntry { - u64 offset; - type::Size size; - - HeaderSection headerSection @ offset; -}; - -struct NameListEntry { - type::Size nameLength; - char16 name[nameLength]; - padding[2]; -}; - -struct NameListFile { - u16 fileLengthWords; - u16 entriesInFile; - - NameListEntry nameList[entriesInFile]; - - padding[0x2E]; -}; - -struct SectionData { - u32 fileLengthWords; - type::Magic<"LZXC"> magic; - u32 version; - u32 lzxResetInterval; - type::Size windowSize; - type::Size cacheSize; - u32; -}; - -struct Content { - NameListFile nameListFile; - SectionData sectionData; -}; - -struct CHM { - type::Magic<"ITSF"> magic; - u32 version; - type::Size headerSize; - u32; - be u32 timeStamp; - WindowsLanguageId languageId; - type::GUID guids[2]; - - HeaderSectionTableEntry headerSectionTable[2]; - - Content *dataOffset : u64; -}; - -CHM chm @ 0x00; +#pragma author WerWolv +#pragma description Windows HtmlHelp Data (ITSF / CHM) + +#include +#include +#include +#include +#include + +enum WindowsLanguageId : u32 { + Arabic_SaudiArabia = 0x401, + Arabic_Iraq = 0x801, + Arabic_Egypt = 0xc01, + Arabic_Libya = 0x1001, + Arabic_Algeria = 0x1401, + Arabic_Morocco = 0x1801, + Arabic_Tunisia = 0x1c01, + Arabic_Oman = 0x2001, + Arabic_Yemen = 0x2401, + Arabic_Syria = 0x2801, + Arabic_Jordan = 0x2c01, + Arabic_Lebanon = 0x3001, + Arabic_Kuwait = 0x3401, + Arabic_UAE = 0x3801, + Arabic_Bahrain = 0x3c01, + Arabic_Qatar = 0x4001, + Bulgarian = 0x402, + Catalan = 0x403, + Valencian = 0x803, + Chinese_Taiwan = 0x404, + Chinese_PRC = 0x804, + Chinese_HongKongSAR = 0xc04, + Chinese_Singapore = 0x1004, + Chinese_MacaoSAR = 0x1404, + Czech = 0x405, + Danish = 0x406, + German_Germany = 0x407, + German_Switzerland = 0x807, + German_Austria = 0xc07, + German_Luxembourg = 0x1007, + German_Liechtenstein = 0x1407, + Greek = 0x408, + English_UnitedStates = 0x409, + English_UnitedKingdom = 0x809, + English_Australia = 0xc09, + English_Canada = 0x1009, + English_NewZealand = 0x1409, + English_Ireland = 0x1809, + English_SouthAfrica = 0x1c09, + English_Jamaica = 0x2009, + English_Caribbean = 0x2409, + English_Belize = 0x2809, + English_TrinidadandTobago = 0x2c09, + English_Zimbabwe = 0x3009, + English_Philippines = 0x3409, + English_Indonesia = 0x3809, + English_HongKongSAR = 0x3c09, + English_India = 0x4009, + English_Malaysia = 0x4409, + English_Singapore = 0x4809, + Spanish_SpainTraditionalSort = 0x40a, + Spanish_Mexico = 0x80a, + Spanish_Spain = 0xc0a, + Spanish_Guatemala = 0x100a, + Spanish_CostaRica = 0x140a, + Spanish_Panama = 0x180a, + Spanish_DominicanRepublic = 0x1c0a, + Spanish_Venezuela = 0x200a, + Spanish_Colombia = 0x240a, + Spanish_Peru = 0x280a, + Spanish_Argentina = 0x2c0a, + Spanish_Ecuador = 0x300a, + Spanish_Chile = 0x340a, + Spanish_Uruguay = 0x380a, + Spanish_Paraguay = 0x3c0a, + Spanish_Bolivia = 0x400a, + Spanish_ElSalvador = 0x440a, + Spanish_Honduras = 0x480a, + Spanish_Nicaragua = 0x4c0a, + Spanish_PuertoRico = 0x500a, + Spanish_UnitedStates = 0x540a, + Spanish_LatinAmerica = 0x580a, + Finnish = 0x40b, + French_France = 0x40c, + French_Belgium = 0x80c, + French_Canada = 0xc0c, + French_Switzerland = 0x100c, + French_Luxembourg = 0x140c, + French_Monaco = 0x180c, + French_Caribbean = 0x1c0c, + French_Reunion = 0x200c, + French_CongoDRC = 0x240c, + French_Senegal = 0x280c, + French_Cameroon = 0x2c0c, + French_CoteDIvoire = 0x300c, + French_Mali = 0x340c, + French_Morocco = 0x380c, + French_Haiti = 0x3c0c, + Hebrew = 0x40d, + Hungarian = 0x40e, + Icelandic = 0x40f, + Italian_Italy = 0x410, + Italian_Switzerland = 0x810, + Japanese = 0x411, + Korean = 0x412, + Dutch_Netherlands = 0x413, + Dutch_Belgium = 0x813, + Norwegian_Bokmal = 0x414, + Norwegian_Nynorsk = 0x814, + Polish = 0x415, + Portuguese_Brazil = 0x416, + Portuguese_Portugal = 0x816, + Romansh = 0x417, + Romanian = 0x418, + Romanian_Moldova = 0x818, + Russian = 0x419, + Russian_Moldova = 0x819, + Croatian_Croatia = 0x41a, + Serbian_LatinSerbiaandMontenegroFormer = 0x81a, + Serbian_CyrillicSerbiaAndMontenegroFormer = 0xc1a, + Croatian_BosniaAndHerzegovina = 0x101a, + Bosnian_Latin = 0x141a, + Serbian_LatinBosniaAndHerzegovina = 0x181a, + Serbian_CyrillicBosniaAndHerzegovina = 0x1c1a, + Bosnian_Cyrillic = 0x201a, + Serbian_LatinSerbia = 0x241a, + Serbian_CyrillicSerbia = 0x281a, + Serbian_LatinMontenegro = 0x2c1a, + Serbian_CyrillicMontenegro = 0x301a, + Slovak = 0x41b, + Albanian = 0x41c, + Swedish_Sweden = 0x41d, + Swedish_Finland = 0x81d, + Thai = 0x41e, + Turkish = 0x41f, + Urdu_Pakistan = 0x420, + Urdu_India = 0x820, + Indonesian = 0x421, + Ukrainian = 0x422, + Belarusian = 0x423, + Slovenian = 0x424, + Estonian = 0x425, + Latvian = 0x426, + Lithuanian = 0x427, + Tajik = 0x428, + Persian = 0x429, + Vietnamese = 0x42a, + Armenian = 0x42b, + Azerbaijani_Latin = 0x42c, + Azerbaijani_Cyrillic = 0x82c, + Basque = 0x42d, + UpperSorbian = 0x42e, + LowerSorbian = 0x82e, + Macedonian = 0x42f, + Sesotho_SouthAfrica = 0x430, + Xitsonga = 0x431, + Setswana_SouthAfrica = 0x432, + Setswana_Botswana = 0x832, + Venda = 0x433, + isiXhosa = 0x434, + isiZulu = 0x435, + Afrikaans = 0x436, + Georgian = 0x437, + Faroese = 0x438, + Hindi = 0x439, + Maltese = 0x43a, + NorthernSami_Norway = 0x43b, + NorthernSami_Sweden = 0x83b, + NorthernSami_Finland = 0xc3b, + LuleSami_Norway = 0x103b, + LuleSami_Sweden = 0x143b, + SouthernSami_Norway = 0x183b, + SouthernSami_Sweden = 0x1c3b, + SkoltSami_Finland = 0x203b, + InariSami_Finland = 0x243b, + Irish = 0x83c, + Yiddish = 0x43d, + Malay_Malaysia = 0x43e, + Malay_BruneiDarussalam = 0x83e, + Kazakh = 0x43f, + Kyrgyz = 0x440, + Kiswahili = 0x441, + Turkmen = 0x442, + Uzbek_Latin = 0x443, + Uzbek_Cyrillic = 0x843, + Tatar = 0x444, + Bangla_India = 0x445, + Bangla_Bangladesh = 0x845, + Punjabi_India = 0x446, + Punjabi_Pakistan = 0x846, + Gujarati = 0x447, + Odia = 0x448, + Tamil_India = 0x449, + Tamil_SriLanka = 0x849, + Telugu = 0x44a, + Kannada = 0x44b, + Malayalam = 0x44c, + Assamese = 0x44d, + Marathi = 0x44e, + Sanskrit = 0x44f, + Mongolian_Cyrillic = 0x450, + Mongolian_TraditionalMongolianPRC = 0x850, + Mongolian_TraditionalMongolianMongolia = 0xc50, + Tibetan_PRC = 0x451, + Welsh = 0x452, + Khmer = 0x453, + Lao = 0x454, + Burmese = 0x455, + Galician = 0x456, + Konkani = 0x457, + Manipuri = 0x458, + Sindhi_Devanagari = 0x459, + Sindhi_Arabic = 0x859, + Syriac = 0x45a, + Sinhala = 0x45b, + Cherokee_Cherokee = 0x45c, + Inuktitut_Syllabics = 0x45d, + Inuktitut_Latin = 0x85d, + Amharic = 0x45e, + Tamazight_ArabicMorocco = 0x45f, + Tamazight_LatinAlgeria = 0x85f, + Tamazight_TifinaghMorocco = 0x105f, + Kashmiri_Arabic = 0x460, + Kashmiri = 0x860, + Nepali = 0x461, + Nepali_India = 0x861, + Frisian = 0x462, + Pashto = 0x463, + Filipino = 0x464, + Divehi = 0x465, + Edo = 0x466, + Fulah_Nigeria = 0x467, + Fulah_LatinSenegal = 0x867, + Hausa = 0x468, + Ibibio_Nigeria = 0x469, + Yoruba = 0x46a, + Quechua_Bolivia = 0x46b, + Quechua_Ecuador = 0x86b, + Quechua_Peru = 0xc6b, + SesothoSaLeboa = 0x46c, + Bashkir = 0x46d, + Luxembourgish = 0x46e, + Greenlandic = 0x46f, + Igbo = 0x470, + Kanuri = 0x471, + Oromo = 0x472, + Tigrinya_Ethiopia = 0x473, + Tigrinya_Eritrea = 0x873, + Guarani = 0x474, + Hawaiian = 0x475, + Latin = 0x476, + Somali = 0x477, + Yi_PRC = 0x478, + Papiamentu = 0x479, + Mapudungun = 0x47a, + Mohawk = 0x47c, + Breton = 0x47e, + Uyghur_PRC = 0x480, + Maori = 0x481, + Occitan = 0x482, + Corsican = 0x483, + Alsatian = 0x484, + Sakha = 0x485, + Kiche = 0x486, + Kinyarwanda = 0x487, + Wolof = 0x488, + Dari = 0x48c, + ScottishGaelic_UnitedKingdom = 0x491, + CentralKurdish_Iraq = 0x492 +}; + +struct DirectoryListingEntry { + type::LEB128 nameLength; + char name[nameLength]; + type::LEB128 contentSection; + type::LEB128 offset; + type::LEB128 length; +}; + +struct DirectoryIndexEntry { + type::LEB128 nameLength; + char name[nameLength]; + type::LEB128 directoryListingChunk; +}; + +struct ListingChunk { + char magic[4]; + + if (magic == "PMGL") { + type::Size freeSpaceLength; + u32; + u32 prevChunkNumber, nextChunkNumber; + + u16 directoryListingEntryCount @ addressof(this) + parent.directoryChunkSize - 2; + u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryListingEntryCount) - (freeSpaceLength - 2); + + DirectoryListingEntry directories[directoryListingEntryCount]; + + $ = addressof(directoryListingEntryCount) + sizeof(directoryListingEntryCount); + } else if (magic == "PMGI") { + type::Size freeSpaceLength; + + u16 directoryIndexEntryCount @ addressof(this) + parent.directoryChunkSize - 2; + u16 offsets[(freeSpaceLength - 2) / 2] @ addressof(directoryIndexEntryCount) - (freeSpaceLength - 2); + + DirectoryIndexEntry indexes[directoryIndexEntryCount]; + + $ = addressof(directoryIndexEntryCount) + sizeof(directoryIndexEntryCount); + } else { + std::error("Invalid chunk magic!"); + } +}; + +struct HeaderSection { + char magic[4]; + + if (magic == "\xFE\x01\x00\x00") { + u32; + type::Size fileSize; + u32; + u32; + } else if (magic == "ITSP") { + u32 version; + type::Size directoryHeaderLength1; + u32; + u32 directoryChunkSize; + u32 quickRefSectionDensity; + u32 indexTreeDepth; + u32 rootIndexChunkNumber; + u32 firstPMGLChunkNumber; + u32 lastPMGLChunkNumber; + u32; + u32 directoryChunkCount; + WindowsLanguageId languageId; + type::GUID guid; + type::Size directoryHeaderLength2; + u32; + u32; + u32; + + ListingChunk chunk[directoryChunkCount]; + } else { + std::error("Invalid header section magic!"); + } +}; + +struct HeaderSectionTableEntry { + u64 offset; + type::Size size; + + HeaderSection headerSection @ offset; +}; + +struct NameListEntry { + type::Size nameLength; + char16 name[nameLength]; + padding[2]; +}; + +struct NameListFile { + u16 fileLengthWords; + u16 entriesInFile; + + NameListEntry nameList[entriesInFile]; + + padding[0x2E]; +}; + +struct SectionData { + u32 fileLengthWords; + type::Magic<"LZXC"> magic; + u32 version; + u32 lzxResetInterval; + type::Size windowSize; + type::Size cacheSize; + u32; +}; + +struct Content { + NameListFile nameListFile; + SectionData sectionData; +}; + +struct CHM { + type::Magic<"ITSF"> magic; + u32 version; + type::Size headerSize; + u32; + be u32 timeStamp; + WindowsLanguageId languageId; + type::GUID guids[2]; + + HeaderSectionTableEntry headerSectionTable[2]; + + Content *dataOffset : u64; +}; + +CHM chm @ 0x00; diff --git a/patterns/coff.hexpat b/patterns/coff.hexpat index 4c9bad5e..9b34139c 100644 --- a/patterns/coff.hexpat +++ b/patterns/coff.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Common Object File Format (COFF) executable + #pragma MIME application/x-coff #include diff --git a/patterns/cpio.hexpat b/patterns/cpio.hexpat index cba08886..dca9c3b1 100644 --- a/patterns/cpio.hexpat +++ b/patterns/cpio.hexpat @@ -1,66 +1,69 @@ -#include - -#include -#include -#include -#include - -#pragma MIME application/x-cpio - -namespace old_binary { - - using Time = u32 [[format("old_binary::format_time")]]; - - fn swap_32bit(u32 value) { - return ((value >> 16) & 0xFFFF) | ((value & 0xFFFF) << 16); - }; - - fn format_time(u32 value) { - return std::time::format(std::time::to_utc(swap_32bit(value))); - }; - - using SwappedU32 = u32 [[transform("old_binary::swap_32bit"), format("old_binary::swap_32bit")]]; - - bitfield Mode { - x : 3; - w : 3; - r : 3; - sticky : 1; - sgid : 1; - suid : 1; - file_type : 4; - }; - - struct CpioHeader { - type::Oct magic; - if (magic == be u16(0o070707)) - std::core::set_endian(std::mem::Endian::Big); - else if (magic == le u16(0o070707)) - std::core::set_endian(std::mem::Endian::Little); - else - std::error("Invalid CPIO Magic!"); - - u16 dev; - u16 ino; - Mode mode; - u16 uid; - u16 gid; - u16 nlink; - u16 rdev; - Time mtime; - u16 namesize; - SwappedU32 filesize; - }; - - struct Cpio { - CpioHeader header; - char pathname[header.namesize % 2 == 0 ? header.namesize : header.namesize + 1]; - u8 data[header.filesize % 2 == 0 ? header.filesize : header.filesize + 1]; - - if (pathname == "TRAILER!!!\x00\x00") - break; - }; - -} - -old_binary::Cpio cpio[while(true)] @ 0x00; +#pragma author WerWolv +#pragma description Old Binary CPIO Format + +#include + +#include +#include +#include +#include + +#pragma MIME application/x-cpio + +namespace old_binary { + + using Time = u32 [[format("old_binary::format_time")]]; + + fn swap_32bit(u32 value) { + return ((value >> 16) & 0xFFFF) | ((value & 0xFFFF) << 16); + }; + + fn format_time(u32 value) { + return std::time::format(std::time::to_utc(swap_32bit(value))); + }; + + using SwappedU32 = u32 [[transform("old_binary::swap_32bit"), format("old_binary::swap_32bit")]]; + + bitfield Mode { + x : 3; + w : 3; + r : 3; + sticky : 1; + sgid : 1; + suid : 1; + file_type : 4; + }; + + struct CpioHeader { + type::Oct magic; + if (magic == be u16(0o070707)) + std::core::set_endian(std::mem::Endian::Big); + else if (magic == le u16(0o070707)) + std::core::set_endian(std::mem::Endian::Little); + else + std::error("Invalid CPIO Magic!"); + + u16 dev; + u16 ino; + Mode mode; + u16 uid; + u16 gid; + u16 nlink; + u16 rdev; + Time mtime; + u16 namesize; + SwappedU32 filesize; + }; + + struct Cpio { + CpioHeader header; + char pathname[header.namesize % 2 == 0 ? header.namesize : header.namesize + 1]; + u8 data[header.filesize % 2 == 0 ? header.filesize : header.filesize + 1]; + + if (pathname == "TRAILER!!!\x00\x00") + break; + }; + +} + +old_binary::Cpio cpio[while(true)] @ 0x00; diff --git a/patterns/dds.hexpat b/patterns/dds.hexpat index 1ba462db..4552a5d8 100644 --- a/patterns/dds.hexpat +++ b/patterns/dds.hexpat @@ -1,3 +1,5 @@ +#pragma description DirectDraw Surface + #pragma MIME image/vnd-ms.dds #pragma endian little diff --git a/patterns/dex.hexpat b/patterns/dex.hexpat index 2458225e..ba8d340b 100644 --- a/patterns/dex.hexpat +++ b/patterns/dex.hexpat @@ -1,3 +1,5 @@ +#pragma description Dalvik EXecutable Format + #include struct header_item { diff --git a/patterns/dmg.hexpat b/patterns/dmg.hexpat index bd536d43..ac1a58f1 100644 --- a/patterns/dmg.hexpat +++ b/patterns/dmg.hexpat @@ -1,3 +1,5 @@ +#pragma description Apple Disk Image Trailer (DMG) + #pragma endian big #include diff --git a/patterns/dsstore.hexpat b/patterns/dsstore.hexpat index 0ff36c50..dde71934 100644 --- a/patterns/dsstore.hexpat +++ b/patterns/dsstore.hexpat @@ -1,3 +1,5 @@ +#pragma description .DS_Store file format + // Apple macOS .DS_Store format #pragma endian big #include diff --git a/patterns/elf.hexpat b/patterns/elf.hexpat index 79a2f309..c7151334 100644 --- a/patterns/elf.hexpat +++ b/patterns/elf.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description ELF header in elf binaries + #pragma MIME application/x-executable #pragma MIME application/x-elf #pragma MIME application/x-coredump diff --git a/patterns/evtx.hexpat b/patterns/evtx.hexpat index 75b64676..aecb1906 100644 --- a/patterns/evtx.hexpat +++ b/patterns/evtx.hexpat @@ -1,3 +1,5 @@ +#pragma description MS Windows Vista Event Log + #pragma endian little struct Header { diff --git a/patterns/fdt.hexpat b/patterns/fdt.hexpat index 23245c09..4452dd64 100644 --- a/patterns/fdt.hexpat +++ b/patterns/fdt.hexpat @@ -1,122 +1,125 @@ -#pragma endian big - -#include -#include -#include - -#include -#include - -// These are used in order for the children to be able to find strings -u64 fdt_addr; -u64 str_offset; - - -struct FDTHeader { - type::Magic<"\xD0\x0D\xFE\xED"> magic; - u32 totalsize; - u32 off_dt_struct; - u32 off_dt_strings; - u32 off_mem_rsvmap; - u32 version; - u32 last_comp_version; - u32 boot_cpuid_phys; - u32 size_dt_strings; - u32 size_dt_struct; -}; - -struct AlignTo { - padding[Alignment- ((($ - 1) % Alignment) + 1)]; -} [[hidden]]; - -struct FDTReserveEntry { - u64 address; - type::Size size; - - if (address == 0x00 && size == 0x00) - break; -}; - -enum FDTToken : u32 { - FDT_BEGIN_NODE = 0x00000001, - FDT_END_NODE = 0x00000002, - FDT_PROP = 0x00000003, - FDT_NOP = 0x00000004, - FDT_END = 0x00000009 -}; - -union FDTPropValue { - u32 prop_array[len / sizeof(u32)]; - char string[len]; -}; - -struct FDTProp { - FDTToken tok[[hidden]]; - u32 len [[hidden]]; - u32 nameoff [[hidden]]; - if (len > 0) { - // if len is zero, value is absent and no need to include it - FDTPropValue value; - } - AlignTo<4>; - char name[] @ fdt_addr + str_offset + nameoff; - - std::core::set_display_name(this, name); - std::print(std::format("{:x} token {} len {} {}", - $, tok, len,nameoff)); - FDTToken token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); - if (token != FDTToken::FDT_PROP) { - break; - } -}; - -struct FDTNode { - FDTToken token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); - - if (token == FDTToken::FDT_BEGIN_NODE) { - FDTToken tok[[hidden]]; - char name[]; - AlignTo<4>; - std::core::set_display_name(this, name[0] ? name : "/"); - token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); - - if(token == FDTToken::FDT_PROP) { - FDTProp props[while(true)]; - } - - token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); - if(token == FDTToken::FDT_END_NODE) { - FDTToken[[hidden]]; - break; - } - - FDTNode children[while(true)][[inline]]; - } else if(token == FDTToken::FDT_NOP) { - // TODO this may break the pattern, I've so far not encountered it - } - - // ew duplication - token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); - if(token == FDTToken::FDT_END_NODE) { - FDTToken[[hidden]]; - break; - } -}; - -struct FDTStructureBlock { - FDTNode; -}; - - -struct FDT { - FDTHeader header; - std::assert(header.version == 17, "Unsupported format version"); - fdt_addr = addressof(this); - str_offset = header.off_dt_strings; - - FDTStructureBlock structureBlocks @ fdt_addr + header.off_dt_struct; - FDTReserveEntry reserveEntries[while(true)] @ fdt_addr + header.off_mem_rsvmap; -}; - -std::mem::MagicSearch<"\xD0\x0D\xFE\xED", FDT> fdt @ std::mem::base_address(); - +#pragma author WerWolv +#pragma description Flat Linux Device Tree blob + +#pragma endian big + +#include +#include +#include + +#include +#include + +// These are used in order for the children to be able to find strings +u64 fdt_addr; +u64 str_offset; + + +struct FDTHeader { + type::Magic<"\xD0\x0D\xFE\xED"> magic; + u32 totalsize; + u32 off_dt_struct; + u32 off_dt_strings; + u32 off_mem_rsvmap; + u32 version; + u32 last_comp_version; + u32 boot_cpuid_phys; + u32 size_dt_strings; + u32 size_dt_struct; +}; + +struct AlignTo { + padding[Alignment- ((($ - 1) % Alignment) + 1)]; +} [[hidden]]; + +struct FDTReserveEntry { + u64 address; + type::Size size; + + if (address == 0x00 && size == 0x00) + break; +}; + +enum FDTToken : u32 { + FDT_BEGIN_NODE = 0x00000001, + FDT_END_NODE = 0x00000002, + FDT_PROP = 0x00000003, + FDT_NOP = 0x00000004, + FDT_END = 0x00000009 +}; + +union FDTPropValue { + u32 prop_array[len / sizeof(u32)]; + char string[len]; +}; + +struct FDTProp { + FDTToken tok[[hidden]]; + u32 len [[hidden]]; + u32 nameoff [[hidden]]; + if (len > 0) { + // if len is zero, value is absent and no need to include it + FDTPropValue value; + } + AlignTo<4>; + char name[] @ fdt_addr + str_offset + nameoff; + + std::core::set_display_name(this, name); + std::print(std::format("{:x} token {} len {} {}", + $, tok, len,nameoff)); + FDTToken token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); + if (token != FDTToken::FDT_PROP) { + break; + } +}; + +struct FDTNode { + FDTToken token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); + + if (token == FDTToken::FDT_BEGIN_NODE) { + FDTToken tok[[hidden]]; + char name[]; + AlignTo<4>; + std::core::set_display_name(this, name[0] ? name : "/"); + token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); + + if(token == FDTToken::FDT_PROP) { + FDTProp props[while(true)]; + } + + token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); + if(token == FDTToken::FDT_END_NODE) { + FDTToken[[hidden]]; + break; + } + + FDTNode children[while(true)][[inline]]; + } else if(token == FDTToken::FDT_NOP) { + // TODO this may break the pattern, I've so far not encountered it + } + + // ew duplication + token = std::mem::read_unsigned($, 4, std::mem::Endian::Big); + if(token == FDTToken::FDT_END_NODE) { + FDTToken[[hidden]]; + break; + } +}; + +struct FDTStructureBlock { + FDTNode; +}; + + +struct FDT { + FDTHeader header; + std::assert(header.version == 17, "Unsupported format version"); + fdt_addr = addressof(this); + str_offset = header.off_dt_strings; + + FDTStructureBlock structureBlocks @ fdt_addr + header.off_dt_struct; + FDTReserveEntry reserveEntries[while(true)] @ fdt_addr + header.off_mem_rsvmap; +}; + +std::mem::MagicSearch<"\xD0\x0D\xFE\xED", FDT> fdt @ std::mem::base_address(); + diff --git a/patterns/flac.hexpat b/patterns/flac.hexpat index 5605ccd7..6fc7829e 100644 --- a/patterns/flac.hexpat +++ b/patterns/flac.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Free Lossless Audio Codec, FLAC Audio Format + #include #include #include diff --git a/patterns/fs.hexpat b/patterns/fs.hexpat index 85431ce7..e7217460 100644 --- a/patterns/fs.hexpat +++ b/patterns/fs.hexpat @@ -1,168 +1,171 @@ -#include - -struct DiskTimeStamp { - u8 seconds, minutes, hours; -}; - -enum DiskProtection : u16 { - None = 0x0000, - CopyProtected = 0x5A5A -}; - -bitfield CHS { - h : 8; - s : 6; - c : 10; -} [[format("chs_formatter")]]; - -fn chs_formatter(CHS chs) { - return std::format("({:X}, {:X}, {:X}) | 0x{:X}", chs.c, chs.h, chs.s, (chs.c * 16 + chs.h) * 63 + (chs.s - 1)); -}; - -enum PartitionStatus : u8 { - None = 0x00, - Active = 0x80 -}; - -enum PartitionType : u8 { - EmptyPartitionEntry = 0x00, - FAT32_CHS = 0x0B, - FAT32_LBA = 0x0C -}; - -namespace fat32 { - - u64 bytesPerCluster; - - struct FSInfo { - u32 leadSignature; - padding[480]; - u32 structSignature; - u32 freeClusterCount; - u32 nextFreeCluster; - padding[12]; - u32 trailSignature; - }; - - bitfield SequenceNumber { - padding : 1; - lastLogical : 1; - padding : 1; - number : 5; - } [[left_to_right]]; - - enum EntryStatus : u8 { - Regular = 0x00, - DotEntry = 0x2E, - DeletedEntry = 0xE5 - }; - - union EntryStatusOrSequenceNumber { - EntryStatus entryStatus; - SequenceNumber sequenceNumber; - }; - - bitfield Attributes { - readOnly : 1; - hidden : 1; - systemFile : 1; - volumeLabel : 1; - subdirectory : 1; - archive : 1; - padding : 2; - } [[right_to_left]]; - - struct DirEntry { - char fileName[8]; - char extension[3]; - Attributes attributes; - u8 reserved[10]; - u16 time, date; - u16 startingCluster; - u32 fileSize; - - u8 data[fileSize] @ startingCluster * bytesPerCluster; - }; - - struct VFATDirEntry { - EntryStatusOrSequenceNumber entryStatusOrSequenceNumber; - char16 name1[5]; - Attributes attributes; - u8 type; - u8 nameChecksum; - char16 name2[6]; - u16 startingCluster; - char16 name3[2]; - - if (entryStatusOrSequenceNumber.sequenceNumber.number > 1) - VFATDirEntry nextLogicalEntry; - else - DirEntry physicalEntry; - }; - - struct Partition { - u8 jmpCode[3]; - char oemName[8]; - u16 bytesPerSector; - u8 sectorsPerCluster; - u16 reservedAreaSize; - u8 numFats; - u16 rootEntryCount; - u16 numSectors; - u8 mediaType; - u16 fatSize; - u16 sectorsPerTrack; - u16 numHeads; - u32 numHiddenSectors; - u32 numFsSectors; - u32 numFatSectors; - u16 extFlags; - u16 fsVersion; - u32 rootCluster; - u16 fsInfoSector; - u16 backupBootSector; - padding[12]; - u8 driveNumber; - padding[1]; - u8 bootSignature; - u32 volumeID; - char volumeLabel[11]; - char fsType[8]; - u8 bootstrapCode[420]; - u16 signature; - - bytesPerCluster = (sectorsPerCluster * 1024) * bytesPerSector; - - FSInfo fsInfo @ addressof(this) + fsInfoSector * bytesPerSector; - VFATDirEntry rootDirEntry @ addressof(this) + rootCluster * bytesPerCluster; - }; - -} - -struct PartitionEntry { - PartitionStatus status; - CHS chsFirstSectorAddress; - PartitionType type; - CHS chsLastSectorAddress; - u32 lbaFirstSectorAddress; - u32 numSectors; - - if (type == PartitionType::EmptyPartitionEntry) - continue; - else if (type == PartitionType::FAT32_CHS || type == PartitionType::FAT32_LBA) - fat32::Partition partition @ lbaFirstSectorAddress * 512; -}; - -struct MasterBootRecord { - u8 bootstrapCodeArea1[218]; - padding[2]; - u8 originalPhysicalDrive; - DiskTimeStamp diskTimeStamp; - u8 bootstrapCodeArea2[216]; - u32 diskSignature; - DiskProtection diskProtection; - PartitionEntry partitionEntries[4]; - u16 bootSignature; -}; - +#pragma author WerWolv +#pragma description Drive File System + +#include + +struct DiskTimeStamp { + u8 seconds, minutes, hours; +}; + +enum DiskProtection : u16 { + None = 0x0000, + CopyProtected = 0x5A5A +}; + +bitfield CHS { + h : 8; + s : 6; + c : 10; +} [[format("chs_formatter")]]; + +fn chs_formatter(CHS chs) { + return std::format("({:X}, {:X}, {:X}) | 0x{:X}", chs.c, chs.h, chs.s, (chs.c * 16 + chs.h) * 63 + (chs.s - 1)); +}; + +enum PartitionStatus : u8 { + None = 0x00, + Active = 0x80 +}; + +enum PartitionType : u8 { + EmptyPartitionEntry = 0x00, + FAT32_CHS = 0x0B, + FAT32_LBA = 0x0C +}; + +namespace fat32 { + + u64 bytesPerCluster; + + struct FSInfo { + u32 leadSignature; + padding[480]; + u32 structSignature; + u32 freeClusterCount; + u32 nextFreeCluster; + padding[12]; + u32 trailSignature; + }; + + bitfield SequenceNumber { + padding : 1; + lastLogical : 1; + padding : 1; + number : 5; + } [[left_to_right]]; + + enum EntryStatus : u8 { + Regular = 0x00, + DotEntry = 0x2E, + DeletedEntry = 0xE5 + }; + + union EntryStatusOrSequenceNumber { + EntryStatus entryStatus; + SequenceNumber sequenceNumber; + }; + + bitfield Attributes { + readOnly : 1; + hidden : 1; + systemFile : 1; + volumeLabel : 1; + subdirectory : 1; + archive : 1; + padding : 2; + } [[right_to_left]]; + + struct DirEntry { + char fileName[8]; + char extension[3]; + Attributes attributes; + u8 reserved[10]; + u16 time, date; + u16 startingCluster; + u32 fileSize; + + u8 data[fileSize] @ startingCluster * bytesPerCluster; + }; + + struct VFATDirEntry { + EntryStatusOrSequenceNumber entryStatusOrSequenceNumber; + char16 name1[5]; + Attributes attributes; + u8 type; + u8 nameChecksum; + char16 name2[6]; + u16 startingCluster; + char16 name3[2]; + + if (entryStatusOrSequenceNumber.sequenceNumber.number > 1) + VFATDirEntry nextLogicalEntry; + else + DirEntry physicalEntry; + }; + + struct Partition { + u8 jmpCode[3]; + char oemName[8]; + u16 bytesPerSector; + u8 sectorsPerCluster; + u16 reservedAreaSize; + u8 numFats; + u16 rootEntryCount; + u16 numSectors; + u8 mediaType; + u16 fatSize; + u16 sectorsPerTrack; + u16 numHeads; + u32 numHiddenSectors; + u32 numFsSectors; + u32 numFatSectors; + u16 extFlags; + u16 fsVersion; + u32 rootCluster; + u16 fsInfoSector; + u16 backupBootSector; + padding[12]; + u8 driveNumber; + padding[1]; + u8 bootSignature; + u32 volumeID; + char volumeLabel[11]; + char fsType[8]; + u8 bootstrapCode[420]; + u16 signature; + + bytesPerCluster = (sectorsPerCluster * 1024) * bytesPerSector; + + FSInfo fsInfo @ addressof(this) + fsInfoSector * bytesPerSector; + VFATDirEntry rootDirEntry @ addressof(this) + rootCluster * bytesPerCluster; + }; + +} + +struct PartitionEntry { + PartitionStatus status; + CHS chsFirstSectorAddress; + PartitionType type; + CHS chsLastSectorAddress; + u32 lbaFirstSectorAddress; + u32 numSectors; + + if (type == PartitionType::EmptyPartitionEntry) + continue; + else if (type == PartitionType::FAT32_CHS || type == PartitionType::FAT32_LBA) + fat32::Partition partition @ lbaFirstSectorAddress * 512; +}; + +struct MasterBootRecord { + u8 bootstrapCodeArea1[218]; + padding[2]; + u8 originalPhysicalDrive; + DiskTimeStamp diskTimeStamp; + u8 bootstrapCodeArea2[216]; + u32 diskSignature; + DiskProtection diskProtection; + PartitionEntry partitionEntries[4]; + u16 bootSignature; +}; + MasterBootRecord mbr @ 0x00; \ No newline at end of file diff --git a/patterns/gb.hexpat b/patterns/gb.hexpat index 96689294..5868bdac 100644 --- a/patterns/gb.hexpat +++ b/patterns/gb.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Gameboy ROM + #include #include #include diff --git a/patterns/gif.hexpat b/patterns/gif.hexpat index 27fd4f03..92fce2cd 100644 --- a/patterns/gif.hexpat +++ b/patterns/gif.hexpat @@ -1,3 +1,5 @@ +#pragma description GIF image files + #pragma MIME image/gif // Extension Labels diff --git a/patterns/gzip.hexpat b/patterns/gzip.hexpat index 569755e5..74a4a12b 100644 --- a/patterns/gzip.hexpat +++ b/patterns/gzip.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description GZip compressed data format + #pragma MIME application/gzip #include diff --git a/patterns/ico.hexpat b/patterns/ico.hexpat index bdd27d4a..67954786 100644 --- a/patterns/ico.hexpat +++ b/patterns/ico.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Icon (.ico) or Cursor (.cur) files + #pragma endian little #include diff --git a/patterns/id3.hexpat b/patterns/id3.hexpat index 41293959..0e6755f6 100644 --- a/patterns/id3.hexpat +++ b/patterns/id3.hexpat @@ -1,3 +1,5 @@ +#pragma description ID3 tags in MP3 files + #pragma MIME audio/mpeg #include diff --git a/patterns/intel_hex.hexpat b/patterns/intel_hex.hexpat index 5ee03843..bf2ce881 100644 --- a/patterns/intel_hex.hexpat +++ b/patterns/intel_hex.hexpat @@ -1,3 +1,5 @@ +#pragma description [Intel hexadecimal object file format definition]("https://en.wikipedia.org/wiki/Intel_HEX") + /* If you have no delimiters between data records then remove * the null_bytes field in the data_packet struct. * Set the array at the bottom to the highest index + 1 in the Pattern Data view diff --git a/patterns/ip.hexpat b/patterns/ip.hexpat index 49277dd7..a38aff57 100644 --- a/patterns/ip.hexpat +++ b/patterns/ip.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Ethernet II Frames (IP Packets) + #pragma endian big #include diff --git a/patterns/ips.hexpat b/patterns/ips.hexpat index bea7c465..a361408b 100644 --- a/patterns/ips.hexpat +++ b/patterns/ips.hexpat @@ -1,3 +1,5 @@ +#pragma description IPS (International Patching System) files + #include #include diff --git a/patterns/iso.hexpat b/patterns/iso.hexpat index c38bcb5b..34f1b740 100644 --- a/patterns/iso.hexpat +++ b/patterns/iso.hexpat @@ -1,3 +1,5 @@ +#pragma description ISO 9660 file system + #pragma endian little #include diff --git a/patterns/java_class.hexpat b/patterns/java_class.hexpat index 0cb78162..aede666f 100644 --- a/patterns/java_class.hexpat +++ b/patterns/java_class.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Java Class files + #pragma endian big #pragma pattern_limit 100000000 #pragma MIME application/x-java-applet diff --git a/patterns/jpeg.hexpat b/patterns/jpeg.hexpat index 6c96982d..cb08cedf 100644 --- a/patterns/jpeg.hexpat +++ b/patterns/jpeg.hexpat @@ -1,122 +1,125 @@ -#include -#pragma endian big - -#pragma MIME image/jpeg - -enum Marker : u8 { - TEM = 0x01, - SOF0 = 0xC0, - SOF1 = 0xC1, - SOF2 = 0xC2, - SOF3 = 0xC3, - DHT = 0xC4, - SOF5 = 0xC5, - SOF6 = 0xC6, - SOF7 = 0xC7, - SOI = 0xD8, - EOI = 0xD9, - SOS = 0xDA, - DQT = 0xDB, - DNL = 0xDC, - DRI = 0xDD, - DHP = 0xDE, - APP0 = 0xE0, - APP1 = 0xE1, - APP2 = 0xE2, - APP3 = 0xE3, - APP4 = 0xE4, - APP5 = 0xE5, - APP6 = 0xE6, - APP7 = 0xE7, - APP8 = 0xE8, - APP9 = 0xE9, - APP10 = 0xEA, - APP11 = 0xEB, - APP12 = 0xEC, - APP13 = 0xED, - APP14 = 0xEE, - APP15 = 0xEF, - COM = 0xFE -}; - -enum DensityUnit : u8 { - NoUnit = 0x00, - PixelsPerInch = 0x01, - PixelsPerCm = 0x02 -}; - -struct Pixel { - u8 r, g, b; -} [[sealed, transform("transform_pixel")]]; - -fn transform_pixel(Pixel pixel) { - return (0xFF << 24) | (pixel.b << 16) | (pixel.g << 8) | (pixel.r << 0); -}; - - -struct APP0 { - char magic[5]; - u8 versionMajor, versionMinor; - DensityUnit densityUnit; - u16 densityX, densityY; - u8 thumbnailX, thumbnailY; - Pixel thumbnail[thumbnailX * thumbnailY] [[sealed]]; -}; - -enum ComponentId : u8 { - Y = 1, - CB = 2, - CR = 3, - I = 4, - Q = 5 -}; - -struct SOF0Component { - ComponentId componentId; - u8 samplingFactors; - u8 quantizationTableId; -}; - -struct SOF0 { - u8 bitsPerSample; - u16 imageHeight, imageWidth; - u8 numComponents; - SOF0Component components[numComponents]; -}; - -struct SOSComponent { - ComponentId componentId; - u8 huffmanTable; -}; - -struct SOS { - u8 numComponents; - SOSComponent components[numComponents]; - u8 startSpectralSelection; - u8 endSpectral; - u8 apprBitPos; - - u8 image_data[while(!std::mem::eof())] [[sealed]]; -}; - -struct Segment { - u8 magic; - Marker marker; - - if (marker == Marker::SOI || marker == Marker::EOI) { - - } else { - u16 length; - if (marker == Marker::APP0) { - APP0 data; - } else if (marker == Marker::SOF0) { - SOF0 data; - } else if (marker == Marker::SOS) { - SOS data; - } else { - u8 data[length - sizeof(length)] [[sealed]]; - } - } -}; - +#pragma author WerWolv +#pragma description JPEG Image Format + +#include +#pragma endian big + +#pragma MIME image/jpeg + +enum Marker : u8 { + TEM = 0x01, + SOF0 = 0xC0, + SOF1 = 0xC1, + SOF2 = 0xC2, + SOF3 = 0xC3, + DHT = 0xC4, + SOF5 = 0xC5, + SOF6 = 0xC6, + SOF7 = 0xC7, + SOI = 0xD8, + EOI = 0xD9, + SOS = 0xDA, + DQT = 0xDB, + DNL = 0xDC, + DRI = 0xDD, + DHP = 0xDE, + APP0 = 0xE0, + APP1 = 0xE1, + APP2 = 0xE2, + APP3 = 0xE3, + APP4 = 0xE4, + APP5 = 0xE5, + APP6 = 0xE6, + APP7 = 0xE7, + APP8 = 0xE8, + APP9 = 0xE9, + APP10 = 0xEA, + APP11 = 0xEB, + APP12 = 0xEC, + APP13 = 0xED, + APP14 = 0xEE, + APP15 = 0xEF, + COM = 0xFE +}; + +enum DensityUnit : u8 { + NoUnit = 0x00, + PixelsPerInch = 0x01, + PixelsPerCm = 0x02 +}; + +struct Pixel { + u8 r, g, b; +} [[sealed, transform("transform_pixel")]]; + +fn transform_pixel(Pixel pixel) { + return (0xFF << 24) | (pixel.b << 16) | (pixel.g << 8) | (pixel.r << 0); +}; + + +struct APP0 { + char magic[5]; + u8 versionMajor, versionMinor; + DensityUnit densityUnit; + u16 densityX, densityY; + u8 thumbnailX, thumbnailY; + Pixel thumbnail[thumbnailX * thumbnailY] [[sealed]]; +}; + +enum ComponentId : u8 { + Y = 1, + CB = 2, + CR = 3, + I = 4, + Q = 5 +}; + +struct SOF0Component { + ComponentId componentId; + u8 samplingFactors; + u8 quantizationTableId; +}; + +struct SOF0 { + u8 bitsPerSample; + u16 imageHeight, imageWidth; + u8 numComponents; + SOF0Component components[numComponents]; +}; + +struct SOSComponent { + ComponentId componentId; + u8 huffmanTable; +}; + +struct SOS { + u8 numComponents; + SOSComponent components[numComponents]; + u8 startSpectralSelection; + u8 endSpectral; + u8 apprBitPos; + + u8 image_data[while(!std::mem::eof())] [[sealed]]; +}; + +struct Segment { + u8 magic; + Marker marker; + + if (marker == Marker::SOI || marker == Marker::EOI) { + + } else { + u16 length; + if (marker == Marker::APP0) { + APP0 data; + } else if (marker == Marker::SOF0) { + SOF0 data; + } else if (marker == Marker::SOS) { + SOS data; + } else { + u8 data[length - sizeof(length)] [[sealed]]; + } + } +}; + Segment segments[while(!std::mem::eof())] @ 0x00 [[hex::visualize("image", this)]]; \ No newline at end of file diff --git a/patterns/lnk.hexpat b/patterns/lnk.hexpat index a556d449..54a1d5eb 100644 --- a/patterns/lnk.hexpat +++ b/patterns/lnk.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Windows Shell Link file format + #pragma MIME application/x-ms-shortcut #include diff --git a/patterns/lua54.hexpat b/patterns/lua54.hexpat index b7e7826c..46208a41 100644 --- a/patterns/lua54.hexpat +++ b/patterns/lua54.hexpat @@ -1,3 +1,5 @@ +#pragma description Lua 5.4 bytecode + #include #include diff --git a/patterns/macho.hexpat b/patterns/macho.hexpat index 785ead87..d01e7e08 100644 --- a/patterns/macho.hexpat +++ b/patterns/macho.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Mach-O executable + #pragma MIME application/x-mach-binary #include diff --git a/patterns/max_v104.hexpat b/patterns/max_v104.hexpat index de15b055..f5f8a1ad 100644 --- a/patterns/max_v104.hexpat +++ b/patterns/max_v104.hexpat @@ -1,3 +1,5 @@ +#pragma description Mechanized Assault and Exploration v1.04 (strategy game) save file format + #include #include diff --git a/patterns/midi.hexpat b/patterns/midi.hexpat index d6547638..1711add7 100644 --- a/patterns/midi.hexpat +++ b/patterns/midi.hexpat @@ -1,3 +1,5 @@ +#pragma description MIDI header, event fields provided + #include #pragma MIME audio/midi diff --git a/patterns/minidump.hexpat b/patterns/minidump.hexpat index 9535b0a2..584ba4ea 100644 --- a/patterns/minidump.hexpat +++ b/patterns/minidump.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Windows MiniDump files + #pragma MIME application/x-dmp #include diff --git a/patterns/mp4.hexpat b/patterns/mp4.hexpat index 435f8eb4..26417aa2 100644 --- a/patterns/mp4.hexpat +++ b/patterns/mp4.hexpat @@ -1,3 +1,5 @@ +#pragma description MPEG-4 Part 14 digital multimedia container format + #pragma endian big #pragma MIME audio/mp4 diff --git a/patterns/msgpack.hexpat b/patterns/msgpack.hexpat index cda1c8d4..37ac3f19 100644 --- a/patterns/msgpack.hexpat +++ b/patterns/msgpack.hexpat @@ -1,154 +1,157 @@ -#pragma MIME application/x-msgpack - -enum Type : u8 { - PositiveFixInt = 0x00 ... 0x7F, - FixMap = 0x80 ... 0x8F, - FixArray = 0x90 ... 0x9F, - FixStr = 0xA0 ... 0xBF, - Nil = 0xC0, - Unused = 0xC1, - False = 0xC2, - True = 0xC3, - Bin8 = 0xC4, - Bin16 = 0xC5, - Bin32 = 0xC6, - Ext8 = 0xC7, - Ext16 = 0xC8, - Ext32 = 0xC9, - Float32 = 0xCA, - Float64 = 0xCB, - Uint8 = 0xCC, - Uint16 = 0xCD, - Uint32 = 0xCE, - Uint64 = 0xCF, - Int8 = 0xD0, - Int16 = 0xD1, - Int32 = 0xD2, - Int64 = 0xD3, - FixExt1 = 0xD4, - FixExt2 = 0xD5, - FixExt4 = 0xD6, - FixExt8 = 0xD7, - FixExt16 = 0xD8, - Str8 = 0xD9, - Str16 = 0xDA, - Str32 = 0xDB, - Array16 = 0xDC, - Array32 = 0xDD, - Map16 = 0xDE, - Map32 = 0xDF, - NegativeFixInt = 0xE0 ... 0xFF -}; - -fn format_positive_fixint(u8 value) { - return value & 0b0111'1111; -}; - -fn format_negative_fixint(u8 value) { - return -(value & 0b0001'1111); -}; - -using MessagePack; - -struct MapEntry { - MessagePack key, value; -}; - -struct MessagePack { - Type type; - - if (u8(type) <= 0x7F) { - $ -= 1; - u8 value [[format("format_positive_fixint")]]; - } else if (u8(type) >= Type::NegativeFixInt) { - $ -= 1; - u8 value [[format("format_negative_fixint")]]; - } else if (type == Type::Uint8) - be u8 value; - else if (type == Type::Uint16) - be u16 value; - else if (type == Type::Uint32) - be u32 value; - else if (type == Type::Uint64) - be u64 value; - else if (type == Type::Int8) - be s8 value; - else if (type == Type::Int16) - be s16 value; - else if (type == Type::Int32) - be s32 value; - else if (type == Type::Int64) - be s64 value; - else if (type == Type::Float32) - be float value; - else if (type == Type::Float64) - be double value; - else if ((u8(type) & 0b1110'0000) == Type::FixStr) - char value[u8(type) & 0b0001'1111]; - else if (type == Type::Str8) { - be u8 length; - char value[length]; - } else if (type == Type::Str16) { - be u16 length; - char value[length]; - } else if (type == Type::Str32) { - be u32 length; - char value[length]; - } else if (type == Type::Bin8) { - be u8 length; - u8 value[length]; - } else if (type == Type::Bin16) { - be u16 length; - u8 value[length]; - } else if (type == Type::Bin32) { - be u32 length; - u8 value[length]; - } else if ((u8(type) & 0b1111'0000) == Type::FixArray) - MessagePack value[u8(type) & 0b0000'1111]; - else if (type == Type::Array16) { - be u16 length; - MessagePack value[length]; - } else if (type == Type::Array32) { - be u32 length; - MessagePack value[length]; - } else if ((u8(type) & 0b1111'0000) == Type::FixMap) - MapEntry value[u8(type) & 0b0000'1111]; - else if (type == Type::Map16) { - be u16 length; - MapEntry value[length]; - } else if (type == Type::Map32) { - be u32 length; - MapEntry value[length]; - } else if (type == Type::FixExt1) { - s8 type; - u8 data; - } else if (type == Type::FixExt2) { - s8 type; - u16 data; - } else if (type == Type::FixExt4) { - s8 type; - u32 data; - } else if (type == Type::FixExt8) { - s8 type; - u64 data; - } else if (type == Type::FixExt16) { - s8 type; - u128 data; - } else if (type == Type::Ext8) { - u8 length; - s8 type; - u8 data[length]; - } else if (type == Type::Ext16) { - u16 length; - s8 type; - u8 data[length]; - } else if (type == Type::Ext32) { - u32 length; - s8 type; - u8 data[length]; - } - - -}; - +#pragma author WerWolv +#pragma description MessagePack binary serialization format + +#pragma MIME application/x-msgpack + +enum Type : u8 { + PositiveFixInt = 0x00 ... 0x7F, + FixMap = 0x80 ... 0x8F, + FixArray = 0x90 ... 0x9F, + FixStr = 0xA0 ... 0xBF, + Nil = 0xC0, + Unused = 0xC1, + False = 0xC2, + True = 0xC3, + Bin8 = 0xC4, + Bin16 = 0xC5, + Bin32 = 0xC6, + Ext8 = 0xC7, + Ext16 = 0xC8, + Ext32 = 0xC9, + Float32 = 0xCA, + Float64 = 0xCB, + Uint8 = 0xCC, + Uint16 = 0xCD, + Uint32 = 0xCE, + Uint64 = 0xCF, + Int8 = 0xD0, + Int16 = 0xD1, + Int32 = 0xD2, + Int64 = 0xD3, + FixExt1 = 0xD4, + FixExt2 = 0xD5, + FixExt4 = 0xD6, + FixExt8 = 0xD7, + FixExt16 = 0xD8, + Str8 = 0xD9, + Str16 = 0xDA, + Str32 = 0xDB, + Array16 = 0xDC, + Array32 = 0xDD, + Map16 = 0xDE, + Map32 = 0xDF, + NegativeFixInt = 0xE0 ... 0xFF +}; + +fn format_positive_fixint(u8 value) { + return value & 0b0111'1111; +}; + +fn format_negative_fixint(u8 value) { + return -(value & 0b0001'1111); +}; + +using MessagePack; + +struct MapEntry { + MessagePack key, value; +}; + +struct MessagePack { + Type type; + + if (u8(type) <= 0x7F) { + $ -= 1; + u8 value [[format("format_positive_fixint")]]; + } else if (u8(type) >= Type::NegativeFixInt) { + $ -= 1; + u8 value [[format("format_negative_fixint")]]; + } else if (type == Type::Uint8) + be u8 value; + else if (type == Type::Uint16) + be u16 value; + else if (type == Type::Uint32) + be u32 value; + else if (type == Type::Uint64) + be u64 value; + else if (type == Type::Int8) + be s8 value; + else if (type == Type::Int16) + be s16 value; + else if (type == Type::Int32) + be s32 value; + else if (type == Type::Int64) + be s64 value; + else if (type == Type::Float32) + be float value; + else if (type == Type::Float64) + be double value; + else if ((u8(type) & 0b1110'0000) == Type::FixStr) + char value[u8(type) & 0b0001'1111]; + else if (type == Type::Str8) { + be u8 length; + char value[length]; + } else if (type == Type::Str16) { + be u16 length; + char value[length]; + } else if (type == Type::Str32) { + be u32 length; + char value[length]; + } else if (type == Type::Bin8) { + be u8 length; + u8 value[length]; + } else if (type == Type::Bin16) { + be u16 length; + u8 value[length]; + } else if (type == Type::Bin32) { + be u32 length; + u8 value[length]; + } else if ((u8(type) & 0b1111'0000) == Type::FixArray) + MessagePack value[u8(type) & 0b0000'1111]; + else if (type == Type::Array16) { + be u16 length; + MessagePack value[length]; + } else if (type == Type::Array32) { + be u32 length; + MessagePack value[length]; + } else if ((u8(type) & 0b1111'0000) == Type::FixMap) + MapEntry value[u8(type) & 0b0000'1111]; + else if (type == Type::Map16) { + be u16 length; + MapEntry value[length]; + } else if (type == Type::Map32) { + be u32 length; + MapEntry value[length]; + } else if (type == Type::FixExt1) { + s8 type; + u8 data; + } else if (type == Type::FixExt2) { + s8 type; + u16 data; + } else if (type == Type::FixExt4) { + s8 type; + u32 data; + } else if (type == Type::FixExt8) { + s8 type; + u64 data; + } else if (type == Type::FixExt16) { + s8 type; + u128 data; + } else if (type == Type::Ext8) { + u8 length; + s8 type; + u8 data[length]; + } else if (type == Type::Ext16) { + u16 length; + s8 type; + u8 data[length]; + } else if (type == Type::Ext32) { + u32 length; + s8 type; + u8 data[length]; + } + + +}; + MessagePack pack @ 0x00; \ No newline at end of file diff --git a/patterns/nacp.hexpat b/patterns/nacp.hexpat index e09b20f7..039ab832 100644 --- a/patterns/nacp.hexpat +++ b/patterns/nacp.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Nintendo Switch NACP files + #pragma endian little #include diff --git a/patterns/nbt.hexpat b/patterns/nbt.hexpat index 0190c4b5..ff1c2cf4 100644 --- a/patterns/nbt.hexpat +++ b/patterns/nbt.hexpat @@ -1,76 +1,79 @@ -#include - -#pragma endian big - -enum Tag : u8 { - End = 0, - Byte = 1, - Short = 2, - Int = 3, - Long = 4, - Float = 5, - Double = 6, - ByteArray = 7, - String = 8, - List = 9, - Compound = 10, - IntArray = 11, - LongArray = 12 -}; - -using Element; - -struct Value { - if (parent.tag == Tag::Byte) - s8 value; - else if (parent.tag == Tag::Short) - s16 value; - else if (parent.tag == Tag::Int) - s32 value; - else if (parent.tag == Tag::Long) - s64 value; - else if (parent.tag == Tag::Float) - float value; - else if (parent.tag == Tag::Double) - double value; - else if (parent.tag == Tag::ByteArray) { - s32 arrayLength; - s8 value[arrayLength] [[sealed]]; - } else if (parent.tag == Tag::String) { - u16 stringLength; - char value[stringLength]; - } else if (parent.tag == Tag::List) { - Tag tag; - s32 listLength; - Value values[listLength] [[static]]; - } else if (parent.tag == Tag::Compound) { - Element values[while(true)]; - } else if (parent.tag == Tag::IntArray){ - s32 arrayLength; - s32 value[arrayLength] [[sealed]]; - } else if (parent.tag == Tag::LongArray) { - s32 arrayLength; - s64 value[arrayLength] [[sealed]]; - } else { - std::error(std::format("Invalid tag {:02X}", TypeTag)); - } -} [[inline]]; - -struct Element { - Tag tag; - if (tag == Tag::End) - break; - else { - - u16 nameLength; - char name[nameLength]; - - Value value; - } -}; - -struct NBT { - Element element[while(true)] [[inline]]; -}; - -NBT nbt @ 0x00; +#pragma author WerWolv +#pragma description Minecraft NBT format + +#include + +#pragma endian big + +enum Tag : u8 { + End = 0, + Byte = 1, + Short = 2, + Int = 3, + Long = 4, + Float = 5, + Double = 6, + ByteArray = 7, + String = 8, + List = 9, + Compound = 10, + IntArray = 11, + LongArray = 12 +}; + +using Element; + +struct Value { + if (parent.tag == Tag::Byte) + s8 value; + else if (parent.tag == Tag::Short) + s16 value; + else if (parent.tag == Tag::Int) + s32 value; + else if (parent.tag == Tag::Long) + s64 value; + else if (parent.tag == Tag::Float) + float value; + else if (parent.tag == Tag::Double) + double value; + else if (parent.tag == Tag::ByteArray) { + s32 arrayLength; + s8 value[arrayLength] [[sealed]]; + } else if (parent.tag == Tag::String) { + u16 stringLength; + char value[stringLength]; + } else if (parent.tag == Tag::List) { + Tag tag; + s32 listLength; + Value values[listLength] [[static]]; + } else if (parent.tag == Tag::Compound) { + Element values[while(true)]; + } else if (parent.tag == Tag::IntArray){ + s32 arrayLength; + s32 value[arrayLength] [[sealed]]; + } else if (parent.tag == Tag::LongArray) { + s32 arrayLength; + s64 value[arrayLength] [[sealed]]; + } else { + std::error(std::format("Invalid tag {:02X}", TypeTag)); + } +} [[inline]]; + +struct Element { + Tag tag; + if (tag == Tag::End) + break; + else { + + u16 nameLength; + char name[nameLength]; + + Value value; + } +}; + +struct NBT { + Element element[while(true)] [[inline]]; +}; + +NBT nbt @ 0x00; diff --git a/patterns/ne.hexpat b/patterns/ne.hexpat index 6af270ec..62b1a7b8 100644 --- a/patterns/ne.hexpat +++ b/patterns/ne.hexpat @@ -1,3 +1,5 @@ +#pragma description NE header and Standard NE fields + #include struct DOSHeader { diff --git a/patterns/nro.hexpat b/patterns/nro.hexpat index 40218b2c..8917f329 100644 --- a/patterns/nro.hexpat +++ b/patterns/nro.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Nintendo Switch NRO files + #include #include diff --git a/patterns/ntag.hexpat b/patterns/ntag.hexpat index 7d06c9c6..3b20dcb9 100644 --- a/patterns/ntag.hexpat +++ b/patterns/ntag.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC + #include using BitfieldOrder = std::core::BitfieldOrder; diff --git a/patterns/ogg.hexpat b/patterns/ogg.hexpat index ee02550e..2917dcc2 100644 --- a/patterns/ogg.hexpat +++ b/patterns/ogg.hexpat @@ -1,29 +1,32 @@ -#pragma MIME audio/ogg - -#include -#include - -bitfield HeaderType { - Continuation : 1; - BeginOfStream : 1; - EndOfStream : 1; -}; - -struct SegmentData { - u8 data[parent.segmentTable[std::core::array_index()]]; -}; - -struct Ogg { - char capturePattern[4]; - u8 version; - HeaderType headerType; - u64 granulePosition; - u32 bitstreamSerialNumber; - u32 pageSequenceNumber; - u32 checksum; - u8 pageSegments; - u8 segmentTable[pageSegments]; - SegmentData data[pageSegments]; -}; - +#pragma author WerWolv +#pragma description OGG Audio format + +#pragma MIME audio/ogg + +#include +#include + +bitfield HeaderType { + Continuation : 1; + BeginOfStream : 1; + EndOfStream : 1; +}; + +struct SegmentData { + u8 data[parent.segmentTable[std::core::array_index()]]; +}; + +struct Ogg { + char capturePattern[4]; + u8 version; + HeaderType headerType; + u64 granulePosition; + u32 bitstreamSerialNumber; + u32 pageSequenceNumber; + u32 checksum; + u8 pageSegments; + u8 segmentTable[pageSegments]; + SegmentData data[pageSegments]; +}; + Ogg ogg[while(!std::mem::eof())] @ 0x00; \ No newline at end of file diff --git a/patterns/pcap.hexpat b/patterns/pcap.hexpat index 3c052b7a..945b81cf 100644 --- a/patterns/pcap.hexpat +++ b/patterns/pcap.hexpat @@ -1,3 +1,5 @@ +#pragma description pcap header and packets + #include #pragma MIME application/vnd.tcpdump.pcap diff --git a/patterns/pcx.hexpat b/patterns/pcx.hexpat index 583ec3a4..7a8fbce6 100644 --- a/patterns/pcx.hexpat +++ b/patterns/pcx.hexpat @@ -1,52 +1,55 @@ -#pragma MIME application/x-pcx - -#include - -enum Encoding : u8 { - NoEncoding = 0x00, - RunLengthEncoding = 0x01 -}; - -enum PaletteType : u16 { - MonochromeOrColorInformation = 0x01, - GrayscaleInformation = 0x02 -}; - -enum Version : u8 { - V2_5 = 0x00, - V2_8WithPalette = 0x02, - V2_8_WithoutPalette = 0x03, - PaintbrushForWindows = 0x04, - V3_0 = 0x05 -}; - -struct Header { - u8 magic; - Version version; - Encoding encoding; - u8 bitsPerPixel; - u16 xMin, yMin; - u16 xMax, yMax; - u16 hdpi, vdpi; -}; - -struct RGB8 { - u8 r, g, b; -} [[sealed, color(std::format("{:02X}{:02X}{:02X}", this.r, this.g, this.b))]]; - -struct Palette { - RGB8 color[16]; -}; - -struct PCX { - Header header; - Palette palette; - padding[1]; - u8 numPlanes; - u16 bytesPerLine; - PaletteType paletteType; - u16 hres, vres; - padding[54]; -}; - +#pragma author WerWolv +#pragma description PCX Image format + +#pragma MIME application/x-pcx + +#include + +enum Encoding : u8 { + NoEncoding = 0x00, + RunLengthEncoding = 0x01 +}; + +enum PaletteType : u16 { + MonochromeOrColorInformation = 0x01, + GrayscaleInformation = 0x02 +}; + +enum Version : u8 { + V2_5 = 0x00, + V2_8WithPalette = 0x02, + V2_8_WithoutPalette = 0x03, + PaintbrushForWindows = 0x04, + V3_0 = 0x05 +}; + +struct Header { + u8 magic; + Version version; + Encoding encoding; + u8 bitsPerPixel; + u16 xMin, yMin; + u16 xMax, yMax; + u16 hdpi, vdpi; +}; + +struct RGB8 { + u8 r, g, b; +} [[sealed, color(std::format("{:02X}{:02X}{:02X}", this.r, this.g, this.b))]]; + +struct Palette { + RGB8 color[16]; +}; + +struct PCX { + Header header; + Palette palette; + padding[1]; + u8 numPlanes; + u16 bytesPerLine; + PaletteType paletteType; + u16 hres, vres; + padding[54]; +}; + PCX pcx @ 0x00; \ No newline at end of file diff --git a/patterns/pe.hexpat b/patterns/pe.hexpat index dd9a086d..14c389c9 100644 --- a/patterns/pe.hexpat +++ b/patterns/pe.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description PE header, COFF header, Standard COFF fields and Windows Specific fields + #pragma MIME application/x-dosexec #pragma MIME application/x-msdownload diff --git a/patterns/pfs0.hexpat b/patterns/pfs0.hexpat index 7646ee86..2ff52b40 100644 --- a/patterns/pfs0.hexpat +++ b/patterns/pfs0.hexpat @@ -1,38 +1,41 @@ -#include -#include - -#include - -struct FileEntry { - u64 dataOffset; - type::Size dataSize; - u32 nameOffset; - padding[4]; -}; - -struct String { - char value[]; -}; - -struct Header { - type::Magic<"PFS0"> magic; - u32 numFiles; - type::Size stringTableSize; - padding[4]; - - FileEntry fileEntryTable[numFiles]; - String strings[numFiles]; -}; - -struct File { - char name[] @ addressof(parent.header.strings) + parent.header.fileEntryTable[std::core::array_index()].nameOffset; - u8 data[parent.header.fileEntryTable[std::core::array_index()].dataSize] @ parent.header.fileEntryTable[std::core::array_index()].dataOffset [[sealed]]; -}; - -struct PFS0 { - Header header; - - File files[header.numFiles]; -}; - +#pragma author WerWolv +#pragma description Nintendo Switch PFS0 archive (NSP files) + +#include +#include + +#include + +struct FileEntry { + u64 dataOffset; + type::Size dataSize; + u32 nameOffset; + padding[4]; +}; + +struct String { + char value[]; +}; + +struct Header { + type::Magic<"PFS0"> magic; + u32 numFiles; + type::Size stringTableSize; + padding[4]; + + FileEntry fileEntryTable[numFiles]; + String strings[numFiles]; +}; + +struct File { + char name[] @ addressof(parent.header.strings) + parent.header.fileEntryTable[std::core::array_index()].nameOffset; + u8 data[parent.header.fileEntryTable[std::core::array_index()].dataSize] @ parent.header.fileEntryTable[std::core::array_index()].dataOffset [[sealed]]; +}; + +struct PFS0 { + Header header; + + File files[header.numFiles]; +}; + PFS0 pfs0 @ 0x00; \ No newline at end of file diff --git a/patterns/pif.hexpat b/patterns/pif.hexpat index 324e291f..bf8e7604 100644 --- a/patterns/pif.hexpat +++ b/patterns/pif.hexpat @@ -1,3 +1,5 @@ +#pragma description PIF Image Format + /* PIF - Portable Image Format * * Basic decoder for the PIF file structure diff --git a/patterns/png.hexpat b/patterns/png.hexpat index fe5999cc..4e9c6274 100644 --- a/patterns/png.hexpat +++ b/patterns/png.hexpat @@ -1,3 +1,5 @@ +#pragma description PNG image files + #pragma MIME image/png #pragma endian big diff --git a/patterns/prodinfo.hexpat b/patterns/prodinfo.hexpat index df10dbb2..20c66320 100644 --- a/patterns/prodinfo.hexpat +++ b/patterns/prodinfo.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Nintendo Switch PRODINFO + enum Model : u16 { NX = 1 }; diff --git a/patterns/protobuf.hexpat b/patterns/protobuf.hexpat index b1292aeb..04b6f949 100644 --- a/patterns/protobuf.hexpat +++ b/patterns/protobuf.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Google Protobuf encoding + #include #include diff --git a/patterns/pyc.hexpat b/patterns/pyc.hexpat index e98037e9..1364f7f8 100644 --- a/patterns/pyc.hexpat +++ b/patterns/pyc.hexpat @@ -1,3 +1,5 @@ +#pragma description Python bytecode files + #include #include diff --git a/patterns/pyinstaller.hexpat b/patterns/pyinstaller.hexpat index 53bfb9a0..ced1801c 100644 --- a/patterns/pyinstaller.hexpat +++ b/patterns/pyinstaller.hexpat @@ -1,3 +1,5 @@ +#pragma description PyInstaller binray files + #pragma endian big #include diff --git a/patterns/qbcl.hexpat b/patterns/qbcl.hexpat index 04e8b303..e06c5575 100644 --- a/patterns/qbcl.hexpat +++ b/patterns/qbcl.hexpat @@ -1,3 +1,5 @@ +#pragma description Qubicle voxel scene project file + // Qubicle QBCL format struct String { diff --git a/patterns/qoi.hexpat b/patterns/qoi.hexpat index 377ba317..6bcd3d25 100644 --- a/patterns/qoi.hexpat +++ b/patterns/qoi.hexpat @@ -1,3 +1,5 @@ +#pragma description QOI image files + #pragma MIME image/qoi #pragma endian big diff --git a/patterns/selinux.hexpat b/patterns/selinux.hexpat index 6372a9f2..09068274 100644 --- a/patterns/selinux.hexpat +++ b/patterns/selinux.hexpat @@ -1,3 +1,5 @@ +#pragma description SE Linux modules + #include #pragma pattern_limit 13107200 #pragma endian little diff --git a/patterns/selinuxpp.hexpat b/patterns/selinuxpp.hexpat index ad08786f..afab6ac7 100644 --- a/patterns/selinuxpp.hexpat +++ b/patterns/selinuxpp.hexpat @@ -1,3 +1,5 @@ +#pragma description SE Linux package + // SE Linux Policy Package // Extension: PP // https://github.com/SELinuxProject/selinux/blob/master/libsepol/src/module.c diff --git a/patterns/sit5.hexpat b/patterns/sit5.hexpat index 5c1b7e2e..7b334358 100644 --- a/patterns/sit5.hexpat +++ b/patterns/sit5.hexpat @@ -1,115 +1,118 @@ -// Based on https://github.com/mietek/theunarchiver/wiki/StuffIt5Format and https://github.com/ParksProjets/Maconv/blob/master/docs/stuffit/Stuffit_v5.md - -#pragma endian big -#pragma MIME application/x-stuffit - -#include -#include - -namespace v5 { - - bitfield Flags1 { - padding : 1; - folder : 1; - encrypted : 1; - padding : 5; - }; - - bitfield Flags2 { - padding : 7; - resource_fork : 1; - padding : 8; - }; - - using MacOSHFSPlusDate = u32 [[format("v5::format_macos_date")]]; - - fn format_macos_date(MacOSHFSPlusDate date) { - return std::time::format(std::time::to_utc(date - 2082844800)); - }; - - struct Header { - char magic[0x50]; - u32 unknown1; - u32 archiveSize; - u32 entriesOffset; - u32 unknown2; - }; - - struct EntryHeader { - u32 magic; - u8 version; - u8 unknown1; - u16 headerSize; - u8 unknown2; - Flags1 flags; - MacOSHFSPlusDate creationDate, modificationDate; - u32 prevEntryOffset, nextEntryOffset, parentEntryOffset; - u16 nameSize; - u16 headerChecksum; - - u32 dataForkUncompressedLength, dataForkCompressedLength; - u16 dataForkChecksum; - u16 unknown3; - }; - - enum CompressionMethod : u8 { - None = 0x00, // No compression - Rle90 = 0x01, // Run length encoding - Compress = 0x02, // Compress LZW algorithm, 14 bit max code length, block mode - StuffIt3 = 0x03, // Simple Huffman encoding for individual bytes - StuffIt5 = 0x05, // LZAH - StuffIt8 = 0x08, // Miller-Wegman - StuffIt13 = 0x0D, // LZSS and Huffman - Stuffit14 = 0x0E, // Unknown - StuffItArsenic = 0x0F // BWT and arithmetic coding - }; - - struct Entry { - EntryHeader header; - if (header.flags.folder) { - u16 numFiles; - - if (header.dataForkUncompressedLength) - std::print("Folder entry {} is special!", std::core::array_index()); - } else { - CompressionMethod compressionMethod; - } - - u8 passwordDataLength; - u8 passwordInformation[passwordDataLength]; - char fileName[header.nameSize]; - u16 commentSize; - u16 unknown2; - char comment[commentSize]; - - if (!header.flags.folder) { - Flags2 flags; - u16 unknown3; - char fileType[4]; - u32 fileCreator; - u16 macOSFinderFlags; - u32 unknown4; - u32 unknown5; - u8 unknown6[6]; - - if (header.version == 1) - u32 unknown7; - - u8 compressedData[header.dataForkCompressedLength] [[sealed]]; - - if (header.nextEntryOffset == 0x00) - break; - else - $ = header.nextEntryOffset; - } - }; - - struct StuffIt { - Header header; - - Entry entries[while(true)] @ header.entriesOffset; - }; - -} - +#pragma author WerWolv +#pragma description StuffIt V5 archive + +// Based on https://github.com/mietek/theunarchiver/wiki/StuffIt5Format and https://github.com/ParksProjets/Maconv/blob/master/docs/stuffit/Stuffit_v5.md + +#pragma endian big +#pragma MIME application/x-stuffit + +#include +#include + +namespace v5 { + + bitfield Flags1 { + padding : 1; + folder : 1; + encrypted : 1; + padding : 5; + }; + + bitfield Flags2 { + padding : 7; + resource_fork : 1; + padding : 8; + }; + + using MacOSHFSPlusDate = u32 [[format("v5::format_macos_date")]]; + + fn format_macos_date(MacOSHFSPlusDate date) { + return std::time::format(std::time::to_utc(date - 2082844800)); + }; + + struct Header { + char magic[0x50]; + u32 unknown1; + u32 archiveSize; + u32 entriesOffset; + u32 unknown2; + }; + + struct EntryHeader { + u32 magic; + u8 version; + u8 unknown1; + u16 headerSize; + u8 unknown2; + Flags1 flags; + MacOSHFSPlusDate creationDate, modificationDate; + u32 prevEntryOffset, nextEntryOffset, parentEntryOffset; + u16 nameSize; + u16 headerChecksum; + + u32 dataForkUncompressedLength, dataForkCompressedLength; + u16 dataForkChecksum; + u16 unknown3; + }; + + enum CompressionMethod : u8 { + None = 0x00, // No compression + Rle90 = 0x01, // Run length encoding + Compress = 0x02, // Compress LZW algorithm, 14 bit max code length, block mode + StuffIt3 = 0x03, // Simple Huffman encoding for individual bytes + StuffIt5 = 0x05, // LZAH + StuffIt8 = 0x08, // Miller-Wegman + StuffIt13 = 0x0D, // LZSS and Huffman + Stuffit14 = 0x0E, // Unknown + StuffItArsenic = 0x0F // BWT and arithmetic coding + }; + + struct Entry { + EntryHeader header; + if (header.flags.folder) { + u16 numFiles; + + if (header.dataForkUncompressedLength) + std::print("Folder entry {} is special!", std::core::array_index()); + } else { + CompressionMethod compressionMethod; + } + + u8 passwordDataLength; + u8 passwordInformation[passwordDataLength]; + char fileName[header.nameSize]; + u16 commentSize; + u16 unknown2; + char comment[commentSize]; + + if (!header.flags.folder) { + Flags2 flags; + u16 unknown3; + char fileType[4]; + u32 fileCreator; + u16 macOSFinderFlags; + u32 unknown4; + u32 unknown5; + u8 unknown6[6]; + + if (header.version == 1) + u32 unknown7; + + u8 compressedData[header.dataForkCompressedLength] [[sealed]]; + + if (header.nextEntryOffset == 0x00) + break; + else + $ = header.nextEntryOffset; + } + }; + + struct StuffIt { + Header header; + + Entry entries[while(true)] @ header.entriesOffset; + }; + +} + v5::StuffIt stuffIt @ 0x00; \ No newline at end of file diff --git a/patterns/spirv.hexpat b/patterns/spirv.hexpat index 909ecdc4..0120cbfb 100644 --- a/patterns/spirv.hexpat +++ b/patterns/spirv.hexpat @@ -1,3 +1,5 @@ +#pragma description SPIR-V header and instructions + #include enum GeneratorID : u16 { diff --git a/patterns/stl.hexpat b/patterns/stl.hexpat index bbc02b95..be85c0df 100644 --- a/patterns/stl.hexpat +++ b/patterns/stl.hexpat @@ -1,51 +1,54 @@ -#pragma MIME model/stl -#pragma MIME model/x.stl-binary -#pragma MIME model/x.stl-ascii -#pragma MIME application/sla - -#include -#include -#include - -struct Vector3f { - float x, y, z; -} [[static, format("format_vector3f")]]; - -fn format_vector3f(Vector3f vec) { - return std::format("[ {}, {}, {} ]", vec.x, vec.y, vec.z); -}; - -struct Triangle { - Vector3f normal; - Vector3f points[3]; - u16 flags; -} [[static]]; - -struct BinarySTLHeader { - char caption[while($[$] != 0x00 && $ - addressof(this) < 80)]; - padding[80 - sizeof(caption)]; - u32 triangleCount; -}; - -struct STL { - if (std::mem::read_string(0, 6) == "solid ") - std::warning("ASCII STL file!"); - else { - BinarySTLHeader header; - Triangle triangles[header.triangleCount]; - } -}; - -STL stl @ 0x00; - -/* Visualize the 3D Model */ - -struct Vertex { - Vector3f points[3] @ addressof(stl.triangles[std::core::array_index()].points); -}; - -struct Model { - Vertex vertices[stl.header.triangleCount]; -} [[highlight_hidden, sealed, hex::visualize("3d", vertices, null)]]; - -Model model @ 0x00; +#pragma author WerWolv +#pragma description STL 3D Model format + +#pragma MIME model/stl +#pragma MIME model/x.stl-binary +#pragma MIME model/x.stl-ascii +#pragma MIME application/sla + +#include +#include +#include + +struct Vector3f { + float x, y, z; +} [[static, format("format_vector3f")]]; + +fn format_vector3f(Vector3f vec) { + return std::format("[ {}, {}, {} ]", vec.x, vec.y, vec.z); +}; + +struct Triangle { + Vector3f normal; + Vector3f points[3]; + u16 flags; +} [[static]]; + +struct BinarySTLHeader { + char caption[while($[$] != 0x00 && $ - addressof(this) < 80)]; + padding[80 - sizeof(caption)]; + u32 triangleCount; +}; + +struct STL { + if (std::mem::read_string(0, 6) == "solid ") + std::warning("ASCII STL file!"); + else { + BinarySTLHeader header; + Triangle triangles[header.triangleCount]; + } +}; + +STL stl @ 0x00; + +/* Visualize the 3D Model */ + +struct Vertex { + Vector3f points[3] @ addressof(stl.triangles[std::core::array_index()].points); +}; + +struct Model { + Vertex vertices[stl.header.triangleCount]; +} [[highlight_hidden, sealed, hex::visualize("3d", vertices, null)]]; + +Model model @ 0x00; diff --git a/patterns/tar.hexpat b/patterns/tar.hexpat index 358f067c..70ad5d78 100644 --- a/patterns/tar.hexpat +++ b/patterns/tar.hexpat @@ -1,3 +1,5 @@ +#pragma description Tar file format + #pragma MIME application/tar #pragma MIME application/x-tar diff --git a/patterns/tga.hexpat b/patterns/tga.hexpat index db111f2c..bee13254 100644 --- a/patterns/tga.hexpat +++ b/patterns/tga.hexpat @@ -1,3 +1,5 @@ +#pragma description Truevision TGA/TARGA image + #pragma MIME image/tga #pragma endian little diff --git a/patterns/tiff.hexpat b/patterns/tiff.hexpat index ffc59264..8f44f313 100644 --- a/patterns/tiff.hexpat +++ b/patterns/tiff.hexpat @@ -1,3 +1,5 @@ +#pragma description Tag Image File Format + #pragma MIME image/tiff #pragma eval_depth 100 diff --git a/patterns/ubiquiti.hexpat b/patterns/ubiquiti.hexpat index 7b5711b6..bed493a4 100644 --- a/patterns/ubiquiti.hexpat +++ b/patterns/ubiquiti.hexpat @@ -1,3 +1,5 @@ +#pragma description Ubiquiti Firmware (update) image + #pragma endian big #include diff --git a/patterns/uefi.hexpat b/patterns/uefi.hexpat index 5d1a47af..f8fe0ead 100644 --- a/patterns/uefi.hexpat +++ b/patterns/uefi.hexpat @@ -1,3 +1,5 @@ +#pragma description UEFI structs for parsing efivars + #pragma MIME data #define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 diff --git a/patterns/uf2.hexpat b/patterns/uf2.hexpat index 6ce16d8d..fe321b90 100644 --- a/patterns/uf2.hexpat +++ b/patterns/uf2.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description [USB Flashing Format](https://github.com/microsoft/uf2) + #include #include diff --git a/patterns/vdf.hexpat b/patterns/vdf.hexpat index 1c0b4425..332eed24 100644 --- a/patterns/vdf.hexpat +++ b/patterns/vdf.hexpat @@ -1,3 +1,6 @@ +#pragma author WerWolv +#pragma description Binary Value Data Format (.vdf) files + #pragma eval_depth 0x10000 #include diff --git a/patterns/vhdx.hexpat b/patterns/vhdx.hexpat index 12c6f9e4..9dbf6893 100644 --- a/patterns/vhdx.hexpat +++ b/patterns/vhdx.hexpat @@ -1,193 +1,196 @@ -#include -#include -#include - -#include -#include - -struct FileTypeIdentifier { - char signature[8]; - char16 creator[256]; - padding[0x1'0000 - sizeof(signature) - sizeof(creator)]; -}; - -struct DataSector { - u32 sequenceHigh; - u8 data[4084]; - u32 sequenceLow; -} [[static]]; - -struct ZeroDescriptor { - padding[4]; - u64 zeroLength; - DataSector *dataSector : u64; - u64 sequenceNumber; -} [[static]]; - -struct DataDescriptor { - u32 trailingBytes; - u64 leadingBytes; - DataSector *dataSector : u64; - u64 sequenceNumber; -} [[static]]; - -struct LogDescriptor { - char signature[4]; - - if (signature == "zero") - ZeroDescriptor descriptor [[inline]]; - else if (signature == "desc") - DataDescriptor descriptor [[inline]]; -}; - -struct LogEntry { - char signature[4]; - u32 checksum; - type::Size32 entryLength; - u32 tail; - u64 sequenceNumber; - u32 descriptorCount; - padding[4]; - type::GUID logGuid; - u64 flushedFileOffset; - u64 lastFileOffset; -} [[static]]; - -bitfield BAT { - State : 3; - padding : 17; - FileOffsetMB : 44; -} [[right_to_left]]; - -bitfield MetadataEntryFlags { - IsUser : 1; - IsVirtualDisk : 1; - IsRequired : 1; - padding : 29; -}; - -bitfield FileParameterFlags { - LeaveBlockAllocated : 1; - HasParent : 1; - padding : 30; -}; - -struct MetadataFileParameters { - type::Size32 blockSize; - FileParameterFlags flags; -}; - -struct MetadataVirtualDiskSize { - type::Size64 virtualDiskSize; -}; - -struct MetadataVirtualDiskID { - type::GUID virtualDiskID; -}; - -struct MetadataLogicalSectorSize { - type::Size32 logicalSectorSize; -}; - -struct MetadataPhysicalSectorSize { - type::Size32 physicalSectorSize; -}; - -struct ParentLocatorEntry { - u32 keyOffset; - u32 valueOffset; - u16 keyLength; - u16 valueLength; - - char key[keyLength] @ addressof(parent) + keyOffset; - char value[valueLength] @ addressof(parent) + valueOffset; -}; - -struct MetadataParentLocator { - type::GUID locatorType; - padding[2]; - u16 keyValueCount; - ParentLocatorEntry entries[keyValueCount]; -}; - -fn metadata_relative(u128 offset) { - return addressof(parent.parent); -}; - -struct MetadataTableEntry { - type::GUID itemID; - - if (std::core::formatted_value(itemID) == "{CAA16737-FA36-4D43-B3B6-33F0AA44E76B}") - MetadataFileParameters *data : u32 [[pointer_base("metadata_relative")]]; - else if (std::core::formatted_value(itemID) == "{2FA54224-CD1B-4876-B211-5DBED83BF4B8}") - MetadataVirtualDiskSize *data : u32 [[pointer_base("metadata_relative")]]; - else if (std::core::formatted_value(itemID) == "{BECA12AB-B2E6-4523-93EF-C309E000C746}") - MetadataVirtualDiskID *data : u32 [[pointer_base("metadata_relative")]]; - else if (std::core::formatted_value(itemID) == "{8141BF1D-A96F-4709-BA47-F233A8FAAB5F}") - MetadataLogicalSectorSize *data : u32 [[pointer_base("metadata_relative")]]; - else if (std::core::formatted_value(itemID) == "{CDA348C7-445D-4471-9CC9-E9885251C556}") - MetadataPhysicalSectorSize *data : u32 [[pointer_base("metadata_relative")]]; - else if (std::core::formatted_value(itemID) == "{A8D35F2D-B30B-454D-ABF7-D3D84834AB0C}") - MetadataParentLocator *data : u32 [[pointer_base("metadata_relative")]]; - else - u32 dataOffset; - - type::Size32 length; - MetadataEntryFlags flags; - padding[4]; -}; - -struct MetadataRegion { - char signature[8]; - padding[2]; - u16 entryCount; - padding[20]; - MetadataTableEntry entries[entryCount]; -}; - -struct RegionTableEntry { - type::GUID guid; - - if (std::core::formatted_value(guid) == "{2DC27766-F623-4200-9D64-115E9BFD4A08}") - BAT *bat : u64; - else if (std::core::formatted_value(guid) == "{8B7CA206-4790-4B9A-B8FE-575F050F886E}") - MetadataRegion *metadata : u64; - else - u64 fileOffset; - - type::Size32 length; - u32 required; -}; - -struct RegionTable { - char signature[4]; - u32 checksum; - u32 entryCount; - padding[4]; - - RegionTableEntry entries[entryCount]; -}; - -struct Header { - char signature[4]; - u32 checksum; - u64 sequenceNumber; - type::GUID fileWriteGuid, dataWriteGuid, logGuid; - u16 logVersion; - u16 version; - type::Size32 logLength; - LogEntry *log : u64; - padding[4016]; -}; - -struct VHDX { - FileTypeIdentifier fileTypeIdentifier; - - Header header @ 0x1'0000; - Header headerBackup @ 0x2'0000; - - RegionTable regionTable @ 0x3'0000; - RegionTable regionTableBackup @ 0x4'0000; -}; - +#pragma author WerWolv +#pragma description Microsoft Hyper-V Virtual Hard Disk format + +#include +#include +#include + +#include +#include + +struct FileTypeIdentifier { + char signature[8]; + char16 creator[256]; + padding[0x1'0000 - sizeof(signature) - sizeof(creator)]; +}; + +struct DataSector { + u32 sequenceHigh; + u8 data[4084]; + u32 sequenceLow; +} [[static]]; + +struct ZeroDescriptor { + padding[4]; + u64 zeroLength; + DataSector *dataSector : u64; + u64 sequenceNumber; +} [[static]]; + +struct DataDescriptor { + u32 trailingBytes; + u64 leadingBytes; + DataSector *dataSector : u64; + u64 sequenceNumber; +} [[static]]; + +struct LogDescriptor { + char signature[4]; + + if (signature == "zero") + ZeroDescriptor descriptor [[inline]]; + else if (signature == "desc") + DataDescriptor descriptor [[inline]]; +}; + +struct LogEntry { + char signature[4]; + u32 checksum; + type::Size32 entryLength; + u32 tail; + u64 sequenceNumber; + u32 descriptorCount; + padding[4]; + type::GUID logGuid; + u64 flushedFileOffset; + u64 lastFileOffset; +} [[static]]; + +bitfield BAT { + State : 3; + padding : 17; + FileOffsetMB : 44; +} [[right_to_left]]; + +bitfield MetadataEntryFlags { + IsUser : 1; + IsVirtualDisk : 1; + IsRequired : 1; + padding : 29; +}; + +bitfield FileParameterFlags { + LeaveBlockAllocated : 1; + HasParent : 1; + padding : 30; +}; + +struct MetadataFileParameters { + type::Size32 blockSize; + FileParameterFlags flags; +}; + +struct MetadataVirtualDiskSize { + type::Size64 virtualDiskSize; +}; + +struct MetadataVirtualDiskID { + type::GUID virtualDiskID; +}; + +struct MetadataLogicalSectorSize { + type::Size32 logicalSectorSize; +}; + +struct MetadataPhysicalSectorSize { + type::Size32 physicalSectorSize; +}; + +struct ParentLocatorEntry { + u32 keyOffset; + u32 valueOffset; + u16 keyLength; + u16 valueLength; + + char key[keyLength] @ addressof(parent) + keyOffset; + char value[valueLength] @ addressof(parent) + valueOffset; +}; + +struct MetadataParentLocator { + type::GUID locatorType; + padding[2]; + u16 keyValueCount; + ParentLocatorEntry entries[keyValueCount]; +}; + +fn metadata_relative(u128 offset) { + return addressof(parent.parent); +}; + +struct MetadataTableEntry { + type::GUID itemID; + + if (std::core::formatted_value(itemID) == "{CAA16737-FA36-4D43-B3B6-33F0AA44E76B}") + MetadataFileParameters *data : u32 [[pointer_base("metadata_relative")]]; + else if (std::core::formatted_value(itemID) == "{2FA54224-CD1B-4876-B211-5DBED83BF4B8}") + MetadataVirtualDiskSize *data : u32 [[pointer_base("metadata_relative")]]; + else if (std::core::formatted_value(itemID) == "{BECA12AB-B2E6-4523-93EF-C309E000C746}") + MetadataVirtualDiskID *data : u32 [[pointer_base("metadata_relative")]]; + else if (std::core::formatted_value(itemID) == "{8141BF1D-A96F-4709-BA47-F233A8FAAB5F}") + MetadataLogicalSectorSize *data : u32 [[pointer_base("metadata_relative")]]; + else if (std::core::formatted_value(itemID) == "{CDA348C7-445D-4471-9CC9-E9885251C556}") + MetadataPhysicalSectorSize *data : u32 [[pointer_base("metadata_relative")]]; + else if (std::core::formatted_value(itemID) == "{A8D35F2D-B30B-454D-ABF7-D3D84834AB0C}") + MetadataParentLocator *data : u32 [[pointer_base("metadata_relative")]]; + else + u32 dataOffset; + + type::Size32 length; + MetadataEntryFlags flags; + padding[4]; +}; + +struct MetadataRegion { + char signature[8]; + padding[2]; + u16 entryCount; + padding[20]; + MetadataTableEntry entries[entryCount]; +}; + +struct RegionTableEntry { + type::GUID guid; + + if (std::core::formatted_value(guid) == "{2DC27766-F623-4200-9D64-115E9BFD4A08}") + BAT *bat : u64; + else if (std::core::formatted_value(guid) == "{8B7CA206-4790-4B9A-B8FE-575F050F886E}") + MetadataRegion *metadata : u64; + else + u64 fileOffset; + + type::Size32 length; + u32 required; +}; + +struct RegionTable { + char signature[4]; + u32 checksum; + u32 entryCount; + padding[4]; + + RegionTableEntry entries[entryCount]; +}; + +struct Header { + char signature[4]; + u32 checksum; + u64 sequenceNumber; + type::GUID fileWriteGuid, dataWriteGuid, logGuid; + u16 logVersion; + u16 version; + type::Size32 logLength; + LogEntry *log : u64; + padding[4016]; +}; + +struct VHDX { + FileTypeIdentifier fileTypeIdentifier; + + Header header @ 0x1'0000; + Header headerBackup @ 0x2'0000; + + RegionTable regionTable @ 0x3'0000; + RegionTable regionTableBackup @ 0x4'0000; +}; + VHDX vhdx @ 0x00; \ No newline at end of file diff --git a/patterns/wad.hexpat b/patterns/wad.hexpat index 6304f342..68a66131 100644 --- a/patterns/wad.hexpat +++ b/patterns/wad.hexpat @@ -1,24 +1,27 @@ -#include -#include - -enum WADType : char { - Internal = 'I', - Patch = 'P' -}; - -struct FileLump { - u32 filePos; - type::Size size; - char name[8]; - - u8 data[size] @ filePos [[sealed]]; -}; - -struct WAD { - WADType type; - type::Magic<"WAD"> identification; - u32 numLumps; - FileLump *infoTable[numLumps] : u32; -}; - +#pragma author WerWolv +#pragma description DOOM WAD Archive + +#include +#include + +enum WADType : char { + Internal = 'I', + Patch = 'P' +}; + +struct FileLump { + u32 filePos; + type::Size size; + char name[8]; + + u8 data[size] @ filePos [[sealed]]; +}; + +struct WAD { + WADType type; + type::Magic<"WAD"> identification; + u32 numLumps; + FileLump *infoTable[numLumps] : u32; +}; + WAD wad @ 0x00; \ No newline at end of file diff --git a/patterns/wav.hexpat b/patterns/wav.hexpat index 637d0566..a4552b32 100644 --- a/patterns/wav.hexpat +++ b/patterns/wav.hexpat @@ -1,3 +1,5 @@ +#pragma description RIFF header, WAVE header, PCM header + #pragma MIME audio/x-wav #pragma MIME audio/wav diff --git a/patterns/xbeh.hexpat b/patterns/xbeh.hexpat index 818d996c..65ad54a0 100644 --- a/patterns/xbeh.hexpat +++ b/patterns/xbeh.hexpat @@ -1,403 +1,406 @@ -#pragma MIME audio/x-xbox-executable - -#include -#include -#include - -#include -#include - - -bitfield AllowedMedia { - HardDisk : 1; - DVD_X2 : 1; - DVD_CD : 1; - CD : 1; - DVD_5_RO : 1; - DVD_9_RO : 1; - DVD_5_RW : 1; - DVD_9_RW : 1; - Dongle : 1; - MediaBoard : 1; - padding : 20; - NonSecureHardDisk : 1; - NonSecureMode : 1; -}; - -bitfield GameRegion { - NorthAmerica : 1; - Japan : 1; - RestOfTheWorld : 1; - padding : 28; - Manufacturing : 1; -}; - -struct Certificate { - type::Size certificateSize; - type::time32_t timeDate; - u32 titleId; - char16 titleName[0x50 / 2]; - u32 alternateTitleIds[16]; - AllowedMedia allowedMedia; - GameRegion gameRegion; - u32 gameRatings; - u128 lanKey; - u128 signatureKey; - u128 alternateSignatureKeys[16]; -}; - -bitfield InitializationFlags { - MountUtilityDrive : 1; - FormatUtilityDrive : 1; - Limit64Megabytes : 1; - DontSetuptHarddisk : 1; - padding : 28; -}; - -union EntryPoint { - u32 betaAddress [[format("format_beta_entrypoint")]]; - u32 debugAddress [[format("format_debug_entrypoint")]]; - u32 retailAddress [[format("format_retail_entrypoint")]]; - - if ((betaAddress ^ 0xE682F45B) - parent.baseAddress < std::mem::size()) - u8 beta @ (betaAddress ^ 0xE682F45B) - parent.baseAddress;; - if ((debugAddress ^ 0x94859D4B) - parent.baseAddress < std::mem::size()) - u8 debug @ (debugAddress ^ 0x94859D4B) - parent.baseAddress;; - if ((retailAddress ^ 0xA8FC57AB) - parent.baseAddress < std::mem::size()) - u8 retail @ (retailAddress ^ 0xA8FC57AB) - parent.baseAddress; -}; - -fn format_beta_entrypoint(u32 value) { - return std::format("0x{:08X}", value ^ 0xE682F45B); -}; - -fn format_debug_entrypoint(u32 value) { - return std::format("0x{:08X}", value ^ 0x94859D4B); -}; - -fn format_retail_entrypoint(u32 value) { - return std::format("0x{:08X}", value ^ 0xA8FC57AB); -}; - -#define KERNEL_BASE 0x8000'0000 -enum KernelImageFunction : u32 { - AvGetSavedDataAddress = 1 + KERNEL_BASE, - AvSendTVEncoderOption = 2 + KERNEL_BASE, - AvSetDisplayMode = 3 + KERNEL_BASE, - AvSetSavedDataAddress = 4 + KERNEL_BASE, - DbgBreakPoint = 5 + KERNEL_BASE, - DbgBreakPointWithStatus = 6 + KERNEL_BASE, - DbgLoadImageSymbols = 7 + KERNEL_BASE, - DbgPrint = 8 + KERNEL_BASE, - HalReadSMCTrayState = 9 + KERNEL_BASE, - DbgPrompt = 10 + KERNEL_BASE, - DbgUnLoadImageSymbols = 11 + KERNEL_BASE, - ExAcquireReadWriteLockExclusive = 12 + KERNEL_BASE, - ExAcquireReadWriteLockShared = 13 + KERNEL_BASE, - ExAllocatePool = 14 + KERNEL_BASE, - ExAllocatePoolWithTag = 15 + KERNEL_BASE, - ExEventObjectType = 16 + KERNEL_BASE, - ExFreePool = 17 + KERNEL_BASE, - ExInitializeReadWriteLock = 18 + KERNEL_BASE, - ExInterlockedAddLargeInteger = 19 + KERNEL_BASE, - ExInterlockedAddLargeStatistic = 20 + KERNEL_BASE, - ExInterlockedCompareExchange64 = 21 + KERNEL_BASE, - ExMutantObjectType = 22 + KERNEL_BASE, - ExQueryPoolBlockSize = 23 + KERNEL_BASE, - ExQueryNonVolatileSetting = 24 + KERNEL_BASE, - ExReadWriteRefurbInfo = 25 + KERNEL_BASE, - ExRaiseException = 26 + KERNEL_BASE, - ExRaiseStatus = 27 + KERNEL_BASE, - ExReleaseReadWriteLock = 28 + KERNEL_BASE, - ExSaveNonVolatileSetting = 29 + KERNEL_BASE, - ExSemaphoreObjectType = 30 + KERNEL_BASE, - ExTimerObjectType = 31 + KERNEL_BASE, - ExfInterlockedInsertHeadList = 32 + KERNEL_BASE, - ExfInterlockedInsertTailList = 33 + KERNEL_BASE, - ExfInterlockedRemoveHeadList = 34 + KERNEL_BASE, - FscGetCacheSize = 35 + KERNEL_BASE, - FscInvalidateIdleBlocks = 36 + KERNEL_BASE, - FscSetCacheSize = 37 + KERNEL_BASE, - HalClearSoftwareInterrupt = 38 + KERNEL_BASE, - HalDisableSystemInterrupt = 39 + KERNEL_BASE, - HalDiskCachePartitionCount = 40 + KERNEL_BASE, - HalDiskModelNumber = 41 + KERNEL_BASE, - HalDiskSerialNumber = 42 + KERNEL_BASE, - HalEnableSystemInterrupt = 43 + KERNEL_BASE, - HalGetInterruptVector = 44 + KERNEL_BASE, - HalReadSMBusValue = 45 + KERNEL_BASE, - HalReadWritePCISpace = 46 + KERNEL_BASE, - HalRegisterShutdownNotification = 47 + KERNEL_BASE, - HalRequestSoftwareInterrupt = 48 + KERNEL_BASE, - HalReturnToFirmware = 49 + KERNEL_BASE, - HalWriteSMBusValue = 50 + KERNEL_BASE, - InterlockedCompareExchange = 51 + KERNEL_BASE, - InterlockedDecrement = 52 + KERNEL_BASE, - InterlockedIncrement = 53 + KERNEL_BASE, - InterlockedExchange = 54 + KERNEL_BASE, - InterlockedExchangeAdd = 55 + KERNEL_BASE, - InterlockedFlushSList = 56 + KERNEL_BASE, - InterlockedPopEntrySList = 57 + KERNEL_BASE, - InterlockedPushEntrySList = 58 + KERNEL_BASE, - IoAllocateIrp = 59 + KERNEL_BASE, - IoBuildAsynchronousFsdRequest = 60 + KERNEL_BASE, - IoBuildDeviceIoControlRequest = 61 + KERNEL_BASE, - IoBuildSynchronousFsdRequest = 62 + KERNEL_BASE, - IoCheckShareAccess = 63 + KERNEL_BASE, - IoCompletionObjectType = 64 + KERNEL_BASE, - IoCreateDevice = 65 + KERNEL_BASE, - IoCreateFile = 66 + KERNEL_BASE, - IoCreateSymbolicLink = 67 + KERNEL_BASE, - IoDeleteDevice = 68 + KERNEL_BASE, - IoDeleteSymbolicLink = 69 + KERNEL_BASE, - IoDeviceObjectType = 70 + KERNEL_BASE, - IoFileObjectType = 71 + KERNEL_BASE, - IoFreeIrp = 72 + KERNEL_BASE, - IoInitializeIrp = 73 + KERNEL_BASE, - IoInvalidDeviceRequest = 74 + KERNEL_BASE, - IoQueryFileInformation = 75 + KERNEL_BASE, - IoQueryVolumeInformation = 76 + KERNEL_BASE, - IoQueueThreadIrp = 77 + KERNEL_BASE, - IoRemoveShareAccess = 78 + KERNEL_BASE, - IoSetIoCompletion = 79 + KERNEL_BASE, - IoSetShareAccess = 80 + KERNEL_BASE, - IoStartNextPacket = 81 + KERNEL_BASE, - IoStartNextPacketByKey = 82 + KERNEL_BASE, - IoStartPacket = 83 + KERNEL_BASE, - IoSynchronousDeviceIoControlRequest = 84 + KERNEL_BASE, - IoSynchronousFsdRequest = 85 + KERNEL_BASE, - IofCallDriver = 86 + KERNEL_BASE, - IofCompleteRequest = 87 + KERNEL_BASE, - KdDebuggerEnabled = 88 + KERNEL_BASE, - KdDebuggerNotPresent = 89 + KERNEL_BASE, - IoDismountVolume = 90 + KERNEL_BASE, - IoDismountVolumeByName = 91 + KERNEL_BASE, - KeAlertResumeThread = 92 + KERNEL_BASE, - KeAlertThread = 93 + KERNEL_BASE, - KeBoostPriorityThread = 94 + KERNEL_BASE, - KeBugCheck = 95 + KERNEL_BASE, - KeBugCheckEx = 96 + KERNEL_BASE, - KeCancelTimer = 97 + KERNEL_BASE, - KeConnectInterrupt = 98 + KERNEL_BASE, - KeDelayExecutionThread = 99 + KERNEL_BASE, - KeDisconnectInterrupt = 100 + KERNEL_BASE, - KeEnterCriticalRegion = 101 + KERNEL_BASE, - MmGlobalData = 102 + KERNEL_BASE, - KeGetCurrentIrql = 103 + KERNEL_BASE, - KeGetCurrentThread = 104 + KERNEL_BASE, - KeInitializeApc = 105 + KERNEL_BASE, - KeInitializeDeviceQueue = 106 + KERNEL_BASE, - KeInitializeDpc = 107 + KERNEL_BASE, - KeInitializeEvent = 108 + KERNEL_BASE, - KeInitializeInterrupt = 109 + KERNEL_BASE, - KeInitializeMutant = 110 + KERNEL_BASE, - KeInitializeQueue = 111 + KERNEL_BASE, - KeInitializeSemaphore = 112 + KERNEL_BASE, - KeInitializeTimerEx = 113 + KERNEL_BASE, - KeInsertByKeyDeviceQueue = 114 + KERNEL_BASE, - KeInsertDeviceQueue = 115 + KERNEL_BASE, - KeInsertHeadQueue = 116 + KERNEL_BASE, - KeInsertQueue = 117 + KERNEL_BASE, - KeInsertQueueApc = 118 + KERNEL_BASE, - KeInsertQueueDpc = 119 + KERNEL_BASE, - KeInterruptTime = 120 + KERNEL_BASE, - KeIsExecutingDpc = 121 + KERNEL_BASE, - KeLeaveCriticalRegion = 122 + KERNEL_BASE, - KePulseEvent = 123 + KERNEL_BASE, - KeQueryBasePriorityThread = 124 + KERNEL_BASE, - KeQueryInterruptTime = 125 + KERNEL_BASE, - KeQueryPerformanceCounter = 126 + KERNEL_BASE, - KeQueryPerformanceFrequency = 127 + KERNEL_BASE, - KeQuerySystemTime = 128 + KERNEL_BASE, - KeRaiseIrqlToDpcLevel = 129 + KERNEL_BASE, - KeRaiseIrqlToSynchLevel = 130 + KERNEL_BASE, - KeReleaseMutant = 131 + KERNEL_BASE, - KeReleaseSemaphore = 132 + KERNEL_BASE, - KeRemoveByKeyDeviceQueue = 133 + KERNEL_BASE, - KeRemoveDeviceQueue = 134 + KERNEL_BASE, - KeRemoveEntryDeviceQueue = 135 + KERNEL_BASE, - KeRemoveQueue = 136 + KERNEL_BASE, - KeRemoveQueueDpc = 137 + KERNEL_BASE, - KeResetEvent = 138 + KERNEL_BASE, - KeRestoreFloatingPointState = 139 + KERNEL_BASE, - KeResumeThread = 140 + KERNEL_BASE, - KeRundownQueue = 141 + KERNEL_BASE, - KeSaveFloatingPointState = 142 + KERNEL_BASE, - KeSetBasePriorityThread = 143 + KERNEL_BASE, - KeSetDisableBoostThread = 144 + KERNEL_BASE, - KeSetEvent = 145 + KERNEL_BASE, - KeSetEventBoostPriority = 146 + KERNEL_BASE, - KeSetPriorityProcess = 147 + KERNEL_BASE, - KeSetPriorityThread = 148 + KERNEL_BASE, - KeSetTimer = 149 + KERNEL_BASE, - KeSetTimerEx = 150 + KERNEL_BASE, - KeStallExecutionProcessor = 151 + KERNEL_BASE, - KeSuspendThread = 152 + KERNEL_BASE, - KeSynchronizeExecution = 153 + KERNEL_BASE, - KeSystemTime = 154 + KERNEL_BASE, - KeTestAlertThread = 155 + KERNEL_BASE, - KeTickCount = 156 + KERNEL_BASE, - KeTimeIncrement = 157 + KERNEL_BASE, - KeWaitForMultipleObjects = 158 + KERNEL_BASE, - KeWaitForSingleObject = 159 + KERNEL_BASE, - KfRaiseIrql = 160 + KERNEL_BASE, - KfLowerIrql = 161 + KERNEL_BASE, - KiBugCheckData = 162 + KERNEL_BASE, - KiUnlockDispatcherDatabase = 163 + KERNEL_BASE, - LaunchDataPage = 164 + KERNEL_BASE, - MmAllocateContiguousMemory = 165 + KERNEL_BASE, - MmAllocateContiguousMemoryEx = 166 + KERNEL_BASE, - MmAllocateSystemMemory = 167 + KERNEL_BASE, - MmClaimGpuInstanceMemory = 168 + KERNEL_BASE, - MmCreateKernelStack = 169 + KERNEL_BASE, - MmDeleteKernelStack = 170 + KERNEL_BASE, - MmFreeContiguousMemory = 171 + KERNEL_BASE, - MmFreeSystemMemory = 172 + KERNEL_BASE, - MmGetPhysicalAddress = 173 + KERNEL_BASE, - MmIsAddressValid = 174 + KERNEL_BASE, - MmLockUnlockBufferPages = 175 + KERNEL_BASE, - MmLockUnlockPhysicalPage = 176 + KERNEL_BASE, - MmMapIoSpace = 177 + KERNEL_BASE, - MmPersistContiguousMemory = 178 + KERNEL_BASE, - MmQueryAddressProtect = 179 + KERNEL_BASE, - MmQueryAllocationSize = 180 + KERNEL_BASE, - MmQueryStatistics = 181 + KERNEL_BASE, - MmSetAddressProtect = 182 + KERNEL_BASE, - MmUnmapIoSpace = 183 + KERNEL_BASE, - NtAllocateVirtualMemory = 184 + KERNEL_BASE, - NtCancelTimer = 185 + KERNEL_BASE, - NtClearEvent = 186 + KERNEL_BASE, - NtClose = 187 + KERNEL_BASE, - NtCreateDirectoryObject = 188 + KERNEL_BASE, - NtCreateEvent = 189 + KERNEL_BASE, - NtCreateFile = 190 + KERNEL_BASE, - NtCreateIoCompletion = 191 + KERNEL_BASE, - NtCreateMutant = 192 + KERNEL_BASE, - NtCreateSemaphore = 193 + KERNEL_BASE, - NtCreateTimer = 194 + KERNEL_BASE, - NtDeleteFile = 195 + KERNEL_BASE, - NtDeviceIoControlFile = 196 + KERNEL_BASE, - NtDuplicateObject = 197 + KERNEL_BASE, - NtFlushBuffersFile = 198 + KERNEL_BASE, - NtFreeVirtualMemory = 199 + KERNEL_BASE, - NtFsControlFile = 200 + KERNEL_BASE, - NtOpenDirectoryObject = 201 + KERNEL_BASE, - NtOpenFile = 202 + KERNEL_BASE, - NtOpenSymbolicLinkObject = 203 + KERNEL_BASE, - NtProtectVirtualMemory = 204 + KERNEL_BASE, - NtPulseEvent = 205 + KERNEL_BASE, - NtQueueApcThread = 206 + KERNEL_BASE, - NtQueryDirectoryFile = 207 + KERNEL_BASE -}; - -struct KernelImageThunk { - KernelImageFunction addresses[while(std::mem::read_unsigned($, 4) != 0x00)]; - padding[4]; -}; - -union KernelImageThunkAddress { - u32 debugAddress [[format("format_debug_kernel_image_thunk_address")]]; - u32 retailAddress [[format("format_retail_kernel_image_thunk_address")]]; - - if ((debugAddress ^ 0xEFB1F152) - parent.baseAddress < std::mem::size()) - KernelImageThunk debug @ (debugAddress ^ 0xEFB1F152) - parent.baseAddress;; - if ((retailAddress ^ 0x5B6D40B6) - parent.baseAddress < std::mem::size()) - KernelImageThunk retail @ (retailAddress ^ 0x5B6D40B6) - parent.baseAddress; -}; - -fn format_debug_kernel_image_thunk_address(u32 value) { - return std::format("0x{:08X}", value ^ 0xEFB1F152); -}; - -fn format_retail_kernel_image_thunk_address(u32 value) { - return std::format("0x{:08X}", value ^ 0x5B6D40B6); -}; - -struct TLS { - u32 rawDataStart, rawDataEnd; - u32 indexAddress; - u32 callbacksAddress; - type::Size zeroFillSize; - u32 characteristics; -}; - -fn relative_to_base(auto pointer) { - return -parent.baseAddress; -}; - -fn relative_to_base_section(auto pointer) { - return -parent.parent.baseAddress; -}; - -bitfield LibraryFlags { - QFEVersion : 13; - Approved : 2; - DebugBuild : 1; -}; - -struct LibraryVersion { - char libraryName[8]; - u16 major, minor, build; - LibraryFlags flags; -}; - -bitfield SectionFlags { - Writable : 1; - Preload : 1; - Executable : 1; - InsertedFile : 1; - HeadPageReadOnly : 1; - TailPageReadOnly : 1; - padding : 26; -}; - -struct SectionHeader { - SectionFlags sectionFlags; - u32 virtualAddress; - type::Size virtualSize; - u32 rawAddress; - type::Size rawSize; - char *sectionName[] : u32 [[pointer_base("relative_to_base_section")]]; - u32 *sectionNameRefrenceCount : u32 [[pointer_base("relative_to_base_section")]]; - u16 *headSharedPageReferenceCount : u32 [[pointer_base("relative_to_base_section")]]; - u16 *tailSharedPageReferenceCount : u32 [[pointer_base("relative_to_base_section")]]; - u8 sectionDigest[20]; - - u8 data[rawSize] @ rawAddress [[sealed]]; -}; - -struct XBEH { - type::Magic<"XBEH"> magic; - u8 signature[0x100] [[sealed]]; - u32 baseAddress; - type::Size headerSize, imageSize, imageHeaderSize; - type::time32_t timeDate; - Certificate *certificate : u32 [[pointer_base("relative_to_base")]]; - u32 numSections; - SectionHeader *sectionHeader[numSections] : u32 [[pointer_base("relative_to_base")]]; - InitializationFlags initializationFlags; - EntryPoint entrypoint; - TLS *tls : u32 [[pointer_base("relative_to_base")]]; - - type::Size stackSize; - u32 peHeapReserve, peHeapCommit, peBaseAddress; - type::Size peImageSize; - u32 peChecksum; - type::time32_t peTimeDate; - char *debugPathNameAddress[] : u32 [[pointer_base("relative_to_base")]]; - char *debugFileNameAddress[] : u32 [[pointer_base("relative_to_base")]]; - char16 *utf16DebugFileNameAddress[] : u32 [[pointer_base("relative_to_base")]]; - KernelImageThunkAddress kernelImageThunkAddress; - u32 nonKernelImportDirectoryAddress; - u32 numLibraryVersions; - LibraryVersion *libraryVersonTable[numLibraryVersions] : u32 [[pointer_base("relative_to_base")]]; - LibraryVersion *kernelLibraryVersion : u32 [[pointer_base("relative_to_base")]]; - LibraryVersion *xapiLibraryVersion : u32 [[pointer_base("relative_to_base")]]; - u32 logoBitMapAddress, logoBitmapSize; - u64 unknown1; - u32 unknown2; - - u8 logoBitmap[logoBitmapSize] @ logoBitMapAddress - baseAddress; -}; - +#pragma author WerWolv +#pragma description Xbox executable + +#pragma MIME audio/x-xbox-executable + +#include +#include +#include + +#include +#include + + +bitfield AllowedMedia { + HardDisk : 1; + DVD_X2 : 1; + DVD_CD : 1; + CD : 1; + DVD_5_RO : 1; + DVD_9_RO : 1; + DVD_5_RW : 1; + DVD_9_RW : 1; + Dongle : 1; + MediaBoard : 1; + padding : 20; + NonSecureHardDisk : 1; + NonSecureMode : 1; +}; + +bitfield GameRegion { + NorthAmerica : 1; + Japan : 1; + RestOfTheWorld : 1; + padding : 28; + Manufacturing : 1; +}; + +struct Certificate { + type::Size certificateSize; + type::time32_t timeDate; + u32 titleId; + char16 titleName[0x50 / 2]; + u32 alternateTitleIds[16]; + AllowedMedia allowedMedia; + GameRegion gameRegion; + u32 gameRatings; + u128 lanKey; + u128 signatureKey; + u128 alternateSignatureKeys[16]; +}; + +bitfield InitializationFlags { + MountUtilityDrive : 1; + FormatUtilityDrive : 1; + Limit64Megabytes : 1; + DontSetuptHarddisk : 1; + padding : 28; +}; + +union EntryPoint { + u32 betaAddress [[format("format_beta_entrypoint")]]; + u32 debugAddress [[format("format_debug_entrypoint")]]; + u32 retailAddress [[format("format_retail_entrypoint")]]; + + if ((betaAddress ^ 0xE682F45B) - parent.baseAddress < std::mem::size()) + u8 beta @ (betaAddress ^ 0xE682F45B) - parent.baseAddress;; + if ((debugAddress ^ 0x94859D4B) - parent.baseAddress < std::mem::size()) + u8 debug @ (debugAddress ^ 0x94859D4B) - parent.baseAddress;; + if ((retailAddress ^ 0xA8FC57AB) - parent.baseAddress < std::mem::size()) + u8 retail @ (retailAddress ^ 0xA8FC57AB) - parent.baseAddress; +}; + +fn format_beta_entrypoint(u32 value) { + return std::format("0x{:08X}", value ^ 0xE682F45B); +}; + +fn format_debug_entrypoint(u32 value) { + return std::format("0x{:08X}", value ^ 0x94859D4B); +}; + +fn format_retail_entrypoint(u32 value) { + return std::format("0x{:08X}", value ^ 0xA8FC57AB); +}; + +#define KERNEL_BASE 0x8000'0000 +enum KernelImageFunction : u32 { + AvGetSavedDataAddress = 1 + KERNEL_BASE, + AvSendTVEncoderOption = 2 + KERNEL_BASE, + AvSetDisplayMode = 3 + KERNEL_BASE, + AvSetSavedDataAddress = 4 + KERNEL_BASE, + DbgBreakPoint = 5 + KERNEL_BASE, + DbgBreakPointWithStatus = 6 + KERNEL_BASE, + DbgLoadImageSymbols = 7 + KERNEL_BASE, + DbgPrint = 8 + KERNEL_BASE, + HalReadSMCTrayState = 9 + KERNEL_BASE, + DbgPrompt = 10 + KERNEL_BASE, + DbgUnLoadImageSymbols = 11 + KERNEL_BASE, + ExAcquireReadWriteLockExclusive = 12 + KERNEL_BASE, + ExAcquireReadWriteLockShared = 13 + KERNEL_BASE, + ExAllocatePool = 14 + KERNEL_BASE, + ExAllocatePoolWithTag = 15 + KERNEL_BASE, + ExEventObjectType = 16 + KERNEL_BASE, + ExFreePool = 17 + KERNEL_BASE, + ExInitializeReadWriteLock = 18 + KERNEL_BASE, + ExInterlockedAddLargeInteger = 19 + KERNEL_BASE, + ExInterlockedAddLargeStatistic = 20 + KERNEL_BASE, + ExInterlockedCompareExchange64 = 21 + KERNEL_BASE, + ExMutantObjectType = 22 + KERNEL_BASE, + ExQueryPoolBlockSize = 23 + KERNEL_BASE, + ExQueryNonVolatileSetting = 24 + KERNEL_BASE, + ExReadWriteRefurbInfo = 25 + KERNEL_BASE, + ExRaiseException = 26 + KERNEL_BASE, + ExRaiseStatus = 27 + KERNEL_BASE, + ExReleaseReadWriteLock = 28 + KERNEL_BASE, + ExSaveNonVolatileSetting = 29 + KERNEL_BASE, + ExSemaphoreObjectType = 30 + KERNEL_BASE, + ExTimerObjectType = 31 + KERNEL_BASE, + ExfInterlockedInsertHeadList = 32 + KERNEL_BASE, + ExfInterlockedInsertTailList = 33 + KERNEL_BASE, + ExfInterlockedRemoveHeadList = 34 + KERNEL_BASE, + FscGetCacheSize = 35 + KERNEL_BASE, + FscInvalidateIdleBlocks = 36 + KERNEL_BASE, + FscSetCacheSize = 37 + KERNEL_BASE, + HalClearSoftwareInterrupt = 38 + KERNEL_BASE, + HalDisableSystemInterrupt = 39 + KERNEL_BASE, + HalDiskCachePartitionCount = 40 + KERNEL_BASE, + HalDiskModelNumber = 41 + KERNEL_BASE, + HalDiskSerialNumber = 42 + KERNEL_BASE, + HalEnableSystemInterrupt = 43 + KERNEL_BASE, + HalGetInterruptVector = 44 + KERNEL_BASE, + HalReadSMBusValue = 45 + KERNEL_BASE, + HalReadWritePCISpace = 46 + KERNEL_BASE, + HalRegisterShutdownNotification = 47 + KERNEL_BASE, + HalRequestSoftwareInterrupt = 48 + KERNEL_BASE, + HalReturnToFirmware = 49 + KERNEL_BASE, + HalWriteSMBusValue = 50 + KERNEL_BASE, + InterlockedCompareExchange = 51 + KERNEL_BASE, + InterlockedDecrement = 52 + KERNEL_BASE, + InterlockedIncrement = 53 + KERNEL_BASE, + InterlockedExchange = 54 + KERNEL_BASE, + InterlockedExchangeAdd = 55 + KERNEL_BASE, + InterlockedFlushSList = 56 + KERNEL_BASE, + InterlockedPopEntrySList = 57 + KERNEL_BASE, + InterlockedPushEntrySList = 58 + KERNEL_BASE, + IoAllocateIrp = 59 + KERNEL_BASE, + IoBuildAsynchronousFsdRequest = 60 + KERNEL_BASE, + IoBuildDeviceIoControlRequest = 61 + KERNEL_BASE, + IoBuildSynchronousFsdRequest = 62 + KERNEL_BASE, + IoCheckShareAccess = 63 + KERNEL_BASE, + IoCompletionObjectType = 64 + KERNEL_BASE, + IoCreateDevice = 65 + KERNEL_BASE, + IoCreateFile = 66 + KERNEL_BASE, + IoCreateSymbolicLink = 67 + KERNEL_BASE, + IoDeleteDevice = 68 + KERNEL_BASE, + IoDeleteSymbolicLink = 69 + KERNEL_BASE, + IoDeviceObjectType = 70 + KERNEL_BASE, + IoFileObjectType = 71 + KERNEL_BASE, + IoFreeIrp = 72 + KERNEL_BASE, + IoInitializeIrp = 73 + KERNEL_BASE, + IoInvalidDeviceRequest = 74 + KERNEL_BASE, + IoQueryFileInformation = 75 + KERNEL_BASE, + IoQueryVolumeInformation = 76 + KERNEL_BASE, + IoQueueThreadIrp = 77 + KERNEL_BASE, + IoRemoveShareAccess = 78 + KERNEL_BASE, + IoSetIoCompletion = 79 + KERNEL_BASE, + IoSetShareAccess = 80 + KERNEL_BASE, + IoStartNextPacket = 81 + KERNEL_BASE, + IoStartNextPacketByKey = 82 + KERNEL_BASE, + IoStartPacket = 83 + KERNEL_BASE, + IoSynchronousDeviceIoControlRequest = 84 + KERNEL_BASE, + IoSynchronousFsdRequest = 85 + KERNEL_BASE, + IofCallDriver = 86 + KERNEL_BASE, + IofCompleteRequest = 87 + KERNEL_BASE, + KdDebuggerEnabled = 88 + KERNEL_BASE, + KdDebuggerNotPresent = 89 + KERNEL_BASE, + IoDismountVolume = 90 + KERNEL_BASE, + IoDismountVolumeByName = 91 + KERNEL_BASE, + KeAlertResumeThread = 92 + KERNEL_BASE, + KeAlertThread = 93 + KERNEL_BASE, + KeBoostPriorityThread = 94 + KERNEL_BASE, + KeBugCheck = 95 + KERNEL_BASE, + KeBugCheckEx = 96 + KERNEL_BASE, + KeCancelTimer = 97 + KERNEL_BASE, + KeConnectInterrupt = 98 + KERNEL_BASE, + KeDelayExecutionThread = 99 + KERNEL_BASE, + KeDisconnectInterrupt = 100 + KERNEL_BASE, + KeEnterCriticalRegion = 101 + KERNEL_BASE, + MmGlobalData = 102 + KERNEL_BASE, + KeGetCurrentIrql = 103 + KERNEL_BASE, + KeGetCurrentThread = 104 + KERNEL_BASE, + KeInitializeApc = 105 + KERNEL_BASE, + KeInitializeDeviceQueue = 106 + KERNEL_BASE, + KeInitializeDpc = 107 + KERNEL_BASE, + KeInitializeEvent = 108 + KERNEL_BASE, + KeInitializeInterrupt = 109 + KERNEL_BASE, + KeInitializeMutant = 110 + KERNEL_BASE, + KeInitializeQueue = 111 + KERNEL_BASE, + KeInitializeSemaphore = 112 + KERNEL_BASE, + KeInitializeTimerEx = 113 + KERNEL_BASE, + KeInsertByKeyDeviceQueue = 114 + KERNEL_BASE, + KeInsertDeviceQueue = 115 + KERNEL_BASE, + KeInsertHeadQueue = 116 + KERNEL_BASE, + KeInsertQueue = 117 + KERNEL_BASE, + KeInsertQueueApc = 118 + KERNEL_BASE, + KeInsertQueueDpc = 119 + KERNEL_BASE, + KeInterruptTime = 120 + KERNEL_BASE, + KeIsExecutingDpc = 121 + KERNEL_BASE, + KeLeaveCriticalRegion = 122 + KERNEL_BASE, + KePulseEvent = 123 + KERNEL_BASE, + KeQueryBasePriorityThread = 124 + KERNEL_BASE, + KeQueryInterruptTime = 125 + KERNEL_BASE, + KeQueryPerformanceCounter = 126 + KERNEL_BASE, + KeQueryPerformanceFrequency = 127 + KERNEL_BASE, + KeQuerySystemTime = 128 + KERNEL_BASE, + KeRaiseIrqlToDpcLevel = 129 + KERNEL_BASE, + KeRaiseIrqlToSynchLevel = 130 + KERNEL_BASE, + KeReleaseMutant = 131 + KERNEL_BASE, + KeReleaseSemaphore = 132 + KERNEL_BASE, + KeRemoveByKeyDeviceQueue = 133 + KERNEL_BASE, + KeRemoveDeviceQueue = 134 + KERNEL_BASE, + KeRemoveEntryDeviceQueue = 135 + KERNEL_BASE, + KeRemoveQueue = 136 + KERNEL_BASE, + KeRemoveQueueDpc = 137 + KERNEL_BASE, + KeResetEvent = 138 + KERNEL_BASE, + KeRestoreFloatingPointState = 139 + KERNEL_BASE, + KeResumeThread = 140 + KERNEL_BASE, + KeRundownQueue = 141 + KERNEL_BASE, + KeSaveFloatingPointState = 142 + KERNEL_BASE, + KeSetBasePriorityThread = 143 + KERNEL_BASE, + KeSetDisableBoostThread = 144 + KERNEL_BASE, + KeSetEvent = 145 + KERNEL_BASE, + KeSetEventBoostPriority = 146 + KERNEL_BASE, + KeSetPriorityProcess = 147 + KERNEL_BASE, + KeSetPriorityThread = 148 + KERNEL_BASE, + KeSetTimer = 149 + KERNEL_BASE, + KeSetTimerEx = 150 + KERNEL_BASE, + KeStallExecutionProcessor = 151 + KERNEL_BASE, + KeSuspendThread = 152 + KERNEL_BASE, + KeSynchronizeExecution = 153 + KERNEL_BASE, + KeSystemTime = 154 + KERNEL_BASE, + KeTestAlertThread = 155 + KERNEL_BASE, + KeTickCount = 156 + KERNEL_BASE, + KeTimeIncrement = 157 + KERNEL_BASE, + KeWaitForMultipleObjects = 158 + KERNEL_BASE, + KeWaitForSingleObject = 159 + KERNEL_BASE, + KfRaiseIrql = 160 + KERNEL_BASE, + KfLowerIrql = 161 + KERNEL_BASE, + KiBugCheckData = 162 + KERNEL_BASE, + KiUnlockDispatcherDatabase = 163 + KERNEL_BASE, + LaunchDataPage = 164 + KERNEL_BASE, + MmAllocateContiguousMemory = 165 + KERNEL_BASE, + MmAllocateContiguousMemoryEx = 166 + KERNEL_BASE, + MmAllocateSystemMemory = 167 + KERNEL_BASE, + MmClaimGpuInstanceMemory = 168 + KERNEL_BASE, + MmCreateKernelStack = 169 + KERNEL_BASE, + MmDeleteKernelStack = 170 + KERNEL_BASE, + MmFreeContiguousMemory = 171 + KERNEL_BASE, + MmFreeSystemMemory = 172 + KERNEL_BASE, + MmGetPhysicalAddress = 173 + KERNEL_BASE, + MmIsAddressValid = 174 + KERNEL_BASE, + MmLockUnlockBufferPages = 175 + KERNEL_BASE, + MmLockUnlockPhysicalPage = 176 + KERNEL_BASE, + MmMapIoSpace = 177 + KERNEL_BASE, + MmPersistContiguousMemory = 178 + KERNEL_BASE, + MmQueryAddressProtect = 179 + KERNEL_BASE, + MmQueryAllocationSize = 180 + KERNEL_BASE, + MmQueryStatistics = 181 + KERNEL_BASE, + MmSetAddressProtect = 182 + KERNEL_BASE, + MmUnmapIoSpace = 183 + KERNEL_BASE, + NtAllocateVirtualMemory = 184 + KERNEL_BASE, + NtCancelTimer = 185 + KERNEL_BASE, + NtClearEvent = 186 + KERNEL_BASE, + NtClose = 187 + KERNEL_BASE, + NtCreateDirectoryObject = 188 + KERNEL_BASE, + NtCreateEvent = 189 + KERNEL_BASE, + NtCreateFile = 190 + KERNEL_BASE, + NtCreateIoCompletion = 191 + KERNEL_BASE, + NtCreateMutant = 192 + KERNEL_BASE, + NtCreateSemaphore = 193 + KERNEL_BASE, + NtCreateTimer = 194 + KERNEL_BASE, + NtDeleteFile = 195 + KERNEL_BASE, + NtDeviceIoControlFile = 196 + KERNEL_BASE, + NtDuplicateObject = 197 + KERNEL_BASE, + NtFlushBuffersFile = 198 + KERNEL_BASE, + NtFreeVirtualMemory = 199 + KERNEL_BASE, + NtFsControlFile = 200 + KERNEL_BASE, + NtOpenDirectoryObject = 201 + KERNEL_BASE, + NtOpenFile = 202 + KERNEL_BASE, + NtOpenSymbolicLinkObject = 203 + KERNEL_BASE, + NtProtectVirtualMemory = 204 + KERNEL_BASE, + NtPulseEvent = 205 + KERNEL_BASE, + NtQueueApcThread = 206 + KERNEL_BASE, + NtQueryDirectoryFile = 207 + KERNEL_BASE +}; + +struct KernelImageThunk { + KernelImageFunction addresses[while(std::mem::read_unsigned($, 4) != 0x00)]; + padding[4]; +}; + +union KernelImageThunkAddress { + u32 debugAddress [[format("format_debug_kernel_image_thunk_address")]]; + u32 retailAddress [[format("format_retail_kernel_image_thunk_address")]]; + + if ((debugAddress ^ 0xEFB1F152) - parent.baseAddress < std::mem::size()) + KernelImageThunk debug @ (debugAddress ^ 0xEFB1F152) - parent.baseAddress;; + if ((retailAddress ^ 0x5B6D40B6) - parent.baseAddress < std::mem::size()) + KernelImageThunk retail @ (retailAddress ^ 0x5B6D40B6) - parent.baseAddress; +}; + +fn format_debug_kernel_image_thunk_address(u32 value) { + return std::format("0x{:08X}", value ^ 0xEFB1F152); +}; + +fn format_retail_kernel_image_thunk_address(u32 value) { + return std::format("0x{:08X}", value ^ 0x5B6D40B6); +}; + +struct TLS { + u32 rawDataStart, rawDataEnd; + u32 indexAddress; + u32 callbacksAddress; + type::Size zeroFillSize; + u32 characteristics; +}; + +fn relative_to_base(auto pointer) { + return -parent.baseAddress; +}; + +fn relative_to_base_section(auto pointer) { + return -parent.parent.baseAddress; +}; + +bitfield LibraryFlags { + QFEVersion : 13; + Approved : 2; + DebugBuild : 1; +}; + +struct LibraryVersion { + char libraryName[8]; + u16 major, minor, build; + LibraryFlags flags; +}; + +bitfield SectionFlags { + Writable : 1; + Preload : 1; + Executable : 1; + InsertedFile : 1; + HeadPageReadOnly : 1; + TailPageReadOnly : 1; + padding : 26; +}; + +struct SectionHeader { + SectionFlags sectionFlags; + u32 virtualAddress; + type::Size virtualSize; + u32 rawAddress; + type::Size rawSize; + char *sectionName[] : u32 [[pointer_base("relative_to_base_section")]]; + u32 *sectionNameRefrenceCount : u32 [[pointer_base("relative_to_base_section")]]; + u16 *headSharedPageReferenceCount : u32 [[pointer_base("relative_to_base_section")]]; + u16 *tailSharedPageReferenceCount : u32 [[pointer_base("relative_to_base_section")]]; + u8 sectionDigest[20]; + + u8 data[rawSize] @ rawAddress [[sealed]]; +}; + +struct XBEH { + type::Magic<"XBEH"> magic; + u8 signature[0x100] [[sealed]]; + u32 baseAddress; + type::Size headerSize, imageSize, imageHeaderSize; + type::time32_t timeDate; + Certificate *certificate : u32 [[pointer_base("relative_to_base")]]; + u32 numSections; + SectionHeader *sectionHeader[numSections] : u32 [[pointer_base("relative_to_base")]]; + InitializationFlags initializationFlags; + EntryPoint entrypoint; + TLS *tls : u32 [[pointer_base("relative_to_base")]]; + + type::Size stackSize; + u32 peHeapReserve, peHeapCommit, peBaseAddress; + type::Size peImageSize; + u32 peChecksum; + type::time32_t peTimeDate; + char *debugPathNameAddress[] : u32 [[pointer_base("relative_to_base")]]; + char *debugFileNameAddress[] : u32 [[pointer_base("relative_to_base")]]; + char16 *utf16DebugFileNameAddress[] : u32 [[pointer_base("relative_to_base")]]; + KernelImageThunkAddress kernelImageThunkAddress; + u32 nonKernelImportDirectoryAddress; + u32 numLibraryVersions; + LibraryVersion *libraryVersonTable[numLibraryVersions] : u32 [[pointer_base("relative_to_base")]]; + LibraryVersion *kernelLibraryVersion : u32 [[pointer_base("relative_to_base")]]; + LibraryVersion *xapiLibraryVersion : u32 [[pointer_base("relative_to_base")]]; + u32 logoBitMapAddress, logoBitmapSize; + u64 unknown1; + u32 unknown2; + + u8 logoBitmap[logoBitmapSize] @ logoBitMapAddress - baseAddress; +}; + XBEH xbeh @ 0x00; \ No newline at end of file diff --git a/patterns/xci.hexpat b/patterns/xci.hexpat index 836d77ec..92d86f26 100644 --- a/patterns/xci.hexpat +++ b/patterns/xci.hexpat @@ -1,97 +1,100 @@ -#include - -#include -#include - -#define PAGE_SIZE 0x200 - -enum RomSize : u8 { - _1GB = 0xFA, - _2GB = 0xF8, - _4GB = 0xF0, - _8GB = 0xE0, - _16GB = 0xE1, - _32GB = 0xE2 -}; - -bitfield Index { - titleKeyDecIndex : 4; - kekIndex : 4; -}; - -bitfield Flags { - autoBoot : 1; - historyErase : 1; - repairTool : 1; - differentRegionCupToTerraDevice : 1; - differentRegionCupToGlobalDevice : 1; - padding : 2; - hasNewCardHeader : 1; -}; - -struct SelSec { - u16 t1, t2; -}; - -struct CardHeader { - u8 headerSignature[0x100]; - type::Magic<"HEAD"> magic; - u32 romAreaStartPageAddress; - u32 backupAreaStartPageAddress; - Index index [[inline]]; - RomSize romSize; - u8 cardHeaderVersion; - Flags flags; - u64 packageId; - u32 validDataEndAddress; - padding[4]; - u8 iv[0x10]; - u64 partitionFsHeaderAddress; - type::Size partitionFsHeaderSize; - u8 partitionFsHeaderHash[0x20]; - u8 initialDataHash[0x20]; - SelSec selSec; - u32 selT1Key; - u32 selKey; - u32 limArea; - - u8 cardHeaderEncryptedData[0x70]; -}; - -struct FileEntry { - u64 dataOffset; - type::Size dataSize; - u32 fileNameOffset; - type::Size hashedRegionSize; - padding[8]; - u8 hash[0x20]; -}; - -struct String { - char string[]; -}; - -struct File { - String fileName @ addressof(parent.stringTable) + parent.fileEntryTable[std::core::array_index()].fileNameOffset; - u8 data[parent.fileEntryTable[std::core::array_index()].dataSize] @ addressof(parent.stringTable) + sizeof(parent.stringTable) + parent.fileEntryTable[std::core::array_index()].dataOffset [[sealed]]; -}; - -struct PartitionFs { - type::Magic<"HFS0"> magic; - u32 fileCount; - type::Size stringTableSize; - padding[4]; - FileEntry fileEntryTable[fileCount]; - String stringTable[while($ < (addressof(fileEntryTable) + sizeof(fileEntryTable) + stringTableSize))]; - - File files[fileCount]; -}; - -struct XCI { - CardHeader header; - - PartitionFs x @ header.romAreaStartPageAddress * PAGE_SIZE; - -}; - +#pragma author WerWolv +#pragma description Nintendo Switch XCI cardridge ROM + +#include + +#include +#include + +#define PAGE_SIZE 0x200 + +enum RomSize : u8 { + _1GB = 0xFA, + _2GB = 0xF8, + _4GB = 0xF0, + _8GB = 0xE0, + _16GB = 0xE1, + _32GB = 0xE2 +}; + +bitfield Index { + titleKeyDecIndex : 4; + kekIndex : 4; +}; + +bitfield Flags { + autoBoot : 1; + historyErase : 1; + repairTool : 1; + differentRegionCupToTerraDevice : 1; + differentRegionCupToGlobalDevice : 1; + padding : 2; + hasNewCardHeader : 1; +}; + +struct SelSec { + u16 t1, t2; +}; + +struct CardHeader { + u8 headerSignature[0x100]; + type::Magic<"HEAD"> magic; + u32 romAreaStartPageAddress; + u32 backupAreaStartPageAddress; + Index index [[inline]]; + RomSize romSize; + u8 cardHeaderVersion; + Flags flags; + u64 packageId; + u32 validDataEndAddress; + padding[4]; + u8 iv[0x10]; + u64 partitionFsHeaderAddress; + type::Size partitionFsHeaderSize; + u8 partitionFsHeaderHash[0x20]; + u8 initialDataHash[0x20]; + SelSec selSec; + u32 selT1Key; + u32 selKey; + u32 limArea; + + u8 cardHeaderEncryptedData[0x70]; +}; + +struct FileEntry { + u64 dataOffset; + type::Size dataSize; + u32 fileNameOffset; + type::Size hashedRegionSize; + padding[8]; + u8 hash[0x20]; +}; + +struct String { + char string[]; +}; + +struct File { + String fileName @ addressof(parent.stringTable) + parent.fileEntryTable[std::core::array_index()].fileNameOffset; + u8 data[parent.fileEntryTable[std::core::array_index()].dataSize] @ addressof(parent.stringTable) + sizeof(parent.stringTable) + parent.fileEntryTable[std::core::array_index()].dataOffset [[sealed]]; +}; + +struct PartitionFs { + type::Magic<"HFS0"> magic; + u32 fileCount; + type::Size stringTableSize; + padding[4]; + FileEntry fileEntryTable[fileCount]; + String stringTable[while($ < (addressof(fileEntryTable) + sizeof(fileEntryTable) + stringTableSize))]; + + File files[fileCount]; +}; + +struct XCI { + CardHeader header; + + PartitionFs x @ header.romAreaStartPageAddress * PAGE_SIZE; + +}; + XCI xci @ 0x00; \ No newline at end of file diff --git a/patterns/xilinx_bit.hexpat b/patterns/xilinx_bit.hexpat index 7bff09db..6581386a 100644 --- a/patterns/xilinx_bit.hexpat +++ b/patterns/xilinx_bit.hexpat @@ -1,52 +1,55 @@ -#include -#include - -struct Flags { - be u16 length; - u8 value[length]; -}; - -struct TLV { - char tag[parent.keySize]; - be u16 length; - char value[length]; -}; - -struct Command { - be u32 value; -} [[static, sealed, format("format_command")]]; - -fn format_command(Command command) { - u32 x = command.value; - - if (x == 0x20000000) return "NOP"; - if (x == 0xAA995566) return "SYNC"; - if (x == 0x000000BB) return "Bus Width Sync"; - if (x == 0x11220044) return "Bus Width Detect"; - if (x == 0x30002001) return "Write to FAR"; - if (x == 0x28006000) return "Write to FDRO"; - if (x == 0x30000001) return "Write to CRC"; - if (x == 0x30018001) return "Write to IDCODE"; - if (x == 0x30004000) return "Write to FDRI"; - if (x == 0x30008001) return "Write to CMD"; - - if ((x & 0xF0000000) == 0x30000000) - return std::format("Write to Register {}", (x & 0x0003E000) >> 13); - - return std::format("0x{:08X}", x); -}; - -struct Commands { - char tag[parent.keySize]; - be u32 length; - Command commands[length / 4]; -}; - -struct Header { - Flags flags; - be u16 keySize; - TLV tlv[4]; - Commands data; -}; - +#pragma author WerWolv +#pragma description Xilinx FPGA Bitstreams + +#include +#include + +struct Flags { + be u16 length; + u8 value[length]; +}; + +struct TLV { + char tag[parent.keySize]; + be u16 length; + char value[length]; +}; + +struct Command { + be u32 value; +} [[static, sealed, format("format_command")]]; + +fn format_command(Command command) { + u32 x = command.value; + + if (x == 0x20000000) return "NOP"; + if (x == 0xAA995566) return "SYNC"; + if (x == 0x000000BB) return "Bus Width Sync"; + if (x == 0x11220044) return "Bus Width Detect"; + if (x == 0x30002001) return "Write to FAR"; + if (x == 0x28006000) return "Write to FDRO"; + if (x == 0x30000001) return "Write to CRC"; + if (x == 0x30018001) return "Write to IDCODE"; + if (x == 0x30004000) return "Write to FDRI"; + if (x == 0x30008001) return "Write to CMD"; + + if ((x & 0xF0000000) == 0x30000000) + return std::format("Write to Register {}", (x & 0x0003E000) >> 13); + + return std::format("0x{:08X}", x); +}; + +struct Commands { + char tag[parent.keySize]; + be u32 length; + Command commands[length / 4]; +}; + +struct Header { + Flags flags; + be u16 keySize; + TLV tlv[4]; + Commands data; +}; + Header header @ 0x00; \ No newline at end of file diff --git a/patterns/zip.hexpat b/patterns/zip.hexpat index 4c8afa34..7c06d655 100644 --- a/patterns/zip.hexpat +++ b/patterns/zip.hexpat @@ -1,3 +1,5 @@ +#pragma description End of Central Directory Header, Central Directory File Headers + #pragma MIME application/zip #include diff --git a/patterns/zlib.hexpat b/patterns/zlib.hexpat index d0c0bc5b..9a595f53 100644 --- a/patterns/zlib.hexpat +++ b/patterns/zlib.hexpat @@ -1,3 +1,5 @@ +#pragma description ZLIB compressed data format + #pragma MIME application/zlib #include diff --git a/patterns/zstd.hexpat b/patterns/zstd.hexpat index eb9abe57..f6bbb7cd 100644 --- a/patterns/zstd.hexpat +++ b/patterns/zstd.hexpat @@ -1,3 +1,5 @@ +#pragma description Zstandard compressed data format + // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md #pragma MIME application/zstd