/* Wanted Team's loadseg modules */ static void process_WTWT_mod(char *credits, size_t credits_len, unsigned char *buf, size_t len, char *lo, char *hi, int rel) { int offset, txt_offset, chunk; char tmpstr[256]; /* check for Magic ID */ offset = find_tag((uint8_t *) buf, 0, len, (uint8_t *) lo, 4); if (offset == -1) return; offset = find_tag((uint8_t *) buf, offset + 4, offset + 8, (uint8_t *) hi, 4); if (offset == -1) return; chunk = offset - 8; /* here's where our first chunk should be */ offset = offset + rel; /* offset to our info pointers */ if (chunk < len && offset < len) { txt_offset = read_be_u32(buf + offset) + chunk; if (txt_offset < len && txt_offset != chunk) { if (!string_checker(buf, txt_offset, len)) return; snprintf(tmpstr, sizeof tmpstr, "\nMODULENAME:\n %s\n", buf + txt_offset); strlcat(credits, tmpstr, credits_len); } txt_offset = read_be_u32(buf + offset + 4) + chunk; if (txt_offset < len && txt_offset != chunk) { if (!string_checker(buf, txt_offset, len)) return; snprintf(tmpstr, sizeof tmpstr, "\nAUTHORNAME:\n %s\n", buf + txt_offset); strlcat(credits, tmpstr, credits_len); } txt_offset = read_be_u32(buf + offset + 8) + chunk; if (txt_offset < len && txt_offset != chunk) { if (!string_checker(buf, txt_offset, len)) return; snprintf(tmpstr, sizeof tmpstr, "\nSPECIALINFO:\n %s", buf + txt_offset); strlcat(credits, tmpstr, credits_len); } } }
/* Get the info out of the digibooster module data*/ static void process_digi_mod(char *credits, size_t credits_len, uint8_t * buf, size_t len) { int i; char tmpstr[256]; if (len < (642 + 0x30 * 0x1e)) return; if (!string_checker(buf, 610, len)) return; snprintf(tmpstr, 0x2f, "\nSong title: %s \n", buf + 610); strlcat(credits, tmpstr, credits_len); snprintf(tmpstr, sizeof tmpstr, "max positions: %d\n", buf[47]); strlcat(credits, tmpstr, credits_len); snprintf(tmpstr, sizeof tmpstr, "\nINST - NAME SIZE VOL FINE LSTART LSIZE\n"); strlcat(credits, tmpstr, credits_len); if (len >= (642 + 0x1f * 0x1e)) { for (i = 0; i < 0x1f; i++) { if (!string_checker(buf, 642 + i * 0x1e, len)) break; snprintf(tmpstr, sizeof tmpstr, "[%2d] - ", i + 1); strlcat(credits, tmpstr, credits_len); snprintf(tmpstr, 30, "%-30s", buf + 642 + (i * 0x1e)); strlcat(credits, tmpstr, credits_len); snprintf(tmpstr, sizeof tmpstr, " %11d %2d %3d %11d %11d\n", read_be_u32(buf + 176 + i * 4), buf[548 + i], buf[579 + i], read_be_u32(buf + 300 + i * 4), read_be_u32(buf + 424 + i * 4)); strlcat(credits, tmpstr, credits_len); } } }
static int tronictest(unsigned char *buf, size_t bufsize) { size_t a = read_be_u16(&buf[0x02]) + read_be_u16(&buf[0x06]) + read_be_u16(&buf[0x0a]) + read_be_u16(&buf[0x0e]) + 0x10; if (((a + 2) >= bufsize) || (a & 1)) return 0; /* size & btst #0, d1; */ a = read_be_u16(&buf[a]) + a; if (((a + 8) >= bufsize) || (a & 1)) return 0; /*size & btst #0,d1 */ if (read_be_u32(&buf[a + 4]) != 0x5800b0) return 0; return 1; }
static int tfmxtest(unsigned char *buf, size_t bufsize, char *pre) { if (bufsize <= 0x208) return 0; if (strncmp((char *) buf, "TFHD", 4) == 0) { if (buf[0x8] == 0x01) { strcpy(pre, "TFHD1.5"); /* One File TFMX format by Alexis NASR */ return 1; } else if (buf[0x8] == 0x02) { strcpy(pre, "TFHDPro"); return 1; } else if (buf[0x8] == 0x03) { strcpy(pre, "TFHD7V"); return 1; } } if (strncasecmp((char *) buf, "TFMX", 4) == 0) { if (strncmp((char *) &buf[4], "-SONG", 5) == 0 || strncmp((char *) &buf[4], "_SONG ", 6) == 0 || strncasecmp((char *) &buf[4], "SONG", 4) == 0 || buf[4] == 0x20) { strcpy(pre, "MDAT"); /*default TFMX: TFMX Pro */ if (strncmp((char *) &buf[10], "by", 2) == 0 || strncmp((char *) &buf[16], " ", 2) == 0 || strncmp((char *) &buf[16], "(Empty)", 7) == 0 || /* Lethal Zone */ (buf[16] == 0x30 && buf[17] == 0x3d) || (buf[4] == 0x20)){ if (read_be_u32(&buf[464]) == 0x00000000) { uint16_t x = read_be_u16(&buf[14]); if ((x != 0x0e60) || /* z-out title */ (x == 0x0860 && bufsize > 4645 && read_be_u16(&buf[4644]) != 0x090c) || /* metal law */ (x == 0x0b20 && bufsize > 5121 && read_be_u16(&buf[5120]) != 0x8c26) || /* bug bomber */ (x == 0x0920 && bufsize > 3977 && read_be_u16(&buf[3876]) != 0x9305)) { /* metal preview */ strcpy(pre, "TFMX1.5"); /*TFMX 1.0 - 1.6 */ } } return 1; } else if (((buf[0x0e] == 0x08 && buf[0x0f] == 0xb0) && /* BMWi */ (buf[0x140] == 0x00 && buf[0x141] == 0x0b) && /*End tackstep 1st subsong */ (buf[0x1d2] == 0x02 && buf[0x1d3] == 0x00) && /*Trackstep datas */ (buf[0x200] == 0xff && buf[0x201] == 0x00 && /*First effect */ buf[0x202] == 0x00 && buf[0x203] == 0x00 && buf[0x204] == 0x01 && buf[0x205] == 0xf4 && buf[0x206] == 0xff && buf[0x207] == 0x00)) || ((buf[0x0e] == 0x0A && buf[0x0f] == 0xb0) && /* B.C Kid */ (buf[0x140] == 0x00 && buf[0x141] == 0x15) && /*End tackstep 1st subsong */ (buf[0x1d2] == 0x02 && buf[0x1d3] == 0x00) && /*Trackstep datas */ (buf[0x200] == 0xef && buf[0x201] == 0xfe && /*First effect */ buf[0x202] == 0x00 && buf[0x203] == 0x03 && buf[0x204] == 0x00 && buf[0x205] == 0x0d && buf[0x206] == 0x00 && buf[0x207] == 0x00))) { strcpy(pre, "TFMX7V"); /* "special cases TFMX 7V */ return 1; } else { int e, i, s, t; /* Trackstep datas offset */ s = read_be_u32(&buf[0x1d0]); if (s == 0x00000000) { /* unpacked */ s = 0x00000800; } for (i = 0; i < 0x3d; i += 2) { if (read_be_u16(&buf[0x140 + i]) != 0x0000) { /* subsong */ /* Start of subsongs Trackstep data :) */ t = read_be_u16(&buf[0x100 + i]) * 16 + s; /* End of subsongs Trackstep data :) */ e = read_be_u16(&buf[0x140 + i]) * 16 + s; if (e < bufsize) { for (; t < e && (t + 6) < bufsize; t += 2) { if (read_be_u16(&buf[t]) == 0xeffe && read_be_u32(&buf[t + 2]) == 0x0003ff00 && buf[t + 6] == 0x00) { strcpy(pre, "TFMX7V"); /*TFMX 7V */ return 1; } } } } } } } } return 0; }
/* Get the info out of custom song. FIX ME, clean this function. */ static void process_custom(char *credits, size_t credits_len, unsigned char *buf, size_t len) { char tmpstr[1024]; unsigned char *hunk; unsigned char *tag_table; int hunk_size; int table_size; int i; int offset; unsigned int x, y; unsigned char startpattern[4] = { 0x70, 0xff, 0x4e, 0x75 }; if (len < 4) return; if (read_be_u32(buf) != 0x000003f3) return; i = find_tag(buf, 0, len, startpattern, sizeof startpattern); if (i == -1 || (i + 12) >= len) return; if (strncmp((char *)buf + i + 4, "DELIRIUM", 8) != 0 && strncmp((char *)buf + i + 4, "EPPLAYER", 8) != 0) { return; } /* Hunk found */ hunk = buf + i; hunk_size = len - i; if (16 + i + 5 >= hunk_size) return; /* Check if $VER is available */ if (!memcmp(&hunk[16], "$VER:", 5)) { offset = 16 + 5; while (offset < hunk_size) { if (memcmp(&hunk[offset], " ", 1)) break; offset++; } if (offset >= hunk_size) return; if ((offset + strlen((char *)hunk + offset) + 1) > ((size_t) hunk_size)) return; snprintf(tmpstr, sizeof tmpstr, "\nVERSION:\n%s\n\n", hunk + offset); strlcat(credits, tmpstr, credits_len); } offset = read_be_u32(hunk + 12); if (offset < 0) { return; } tag_table = hunk + offset; if (tag_table >= &buf[len]) return; table_size = ((int)(&buf[len] - tag_table)) / 8; if (table_size <= 0) return; /* check all tags in this loop */ for (i = 0; i < table_size; i += 2) { x = read_be_u32(tag_table + 4 * i); y = read_be_u32(tag_table + 4 * (i + 1)); if (!x) break; switch (x) { case 0x8000445a: if (y >= ((unsigned int)hunk_size)) return; if ((y + strlen((char *)hunk + y) + 1) > ((size_t) hunk_size)) return; snprintf(tmpstr, sizeof tmpstr, "\nCREDITS:\n%s\n\n", hunk + y); strlcat(credits, tmpstr, credits_len); break; default: break; } } }