#include "defs.h" /*->magic.h (u8,u15x)*/ #include "magic.h" /*MagicType*/ /* stricter 15-sample mod checking */ static i15x isMod15(const u8 *p0, i31x size) { i15x ordNum, patNum; i15x i; const u8 *p; if (size < 20+30*15+130+1024) return 0; /* check min length */ ordNum = p0[20+30*15]; if (!ordNum || ordNum >= 128) return 0; patNum = 0; p = p0 + 20+30*15+2; /* pattern table */ for (i = 0; i < ordNum; i++,p++) if (patNum < *p) patNum = *p; if (patNum >= 64) return 0; if (size < 20+30*15+130+1024+1024*patNum) return 0; /* sample length is not checked here */ return 1; } typedef struct { const u8 *str; i15x off; MagicType type; } MagicInfo; MagicInfo magicInfo[] = { {"SCRM", 0x2c, MAGIC_S3M}, {"M.K.", 0x438 /*20+30*31+130=1080*/, MAGIC_MOD}, {"M!K!", 0x438, MAGIC_MOD}, {"FLT4", 0x438, MAGIC_MOD}, /* FLT8's pattern is different */ {"#CHN", 0x438, MAGIC_MODX}, {"##CH", 0x438, MAGIC_MODX}, /* dope.mod */ {"MTM", 0, MAGIC_MTM}, /* check after above patterns fail. (A mod songname can be "MTMxxx") */ {0} }; #define isnum(x) ('0' <= (x) && (x) <= '9') i15x magic(const u8 *p, i31x size, MagicType *mtp, i15x *numChp) { MagicInfo *mip; i15x ch; for (mip = magicInfo; mip->str != 0; mip++) { const u8 *ss, *sp; if (mip->off + 16 >= size) continue; /* Magicinfo.str must < 16 */ sp = p + mip->off; ch = 0; for (ss = mip->str; *ss != 0; ss++,sp++) { if (*ss == '#') if (isnum(*sp)) { ch = ch*10 + *sp - '0'; continue; } else goto UNMATCH; if (*sp != *ss) goto UNMATCH; } *mtp = mip->type; *numChp = ch; return 0; UNMATCH:; } if (isMod15(p, size)) { *mtp = MAGIC_MOD15; return 0; } else return 1; }