static int depack_fcm(xmp_file in, xmp_file out) { uint8 c1; uint8 ptable[128]; uint8 pat_pos; uint8 pat_max; int i; int size, ssize = 0; memset(ptable, 0, 128); read32b(in); /* bypass "FC-M" ID */ read16b(in); /* version number? */ read32b(in); /* bypass "NAME" chunk */ pw_move_data(out, in, 20); /* read and write title */ read32b(in); /* bypass "INST" chunk */ /* read and write sample descriptions */ for (i = 0; i < 31; i++) { pw_write_zero(out, 22); /*sample name */ write16b(out, size = read16b(in)); /* size */ ssize += size * 2; write8(out, read8(in)); /* finetune */ write8(out, read8(in)); /* volume */ write16b(out, read16b(in)); /* loop start */ size = read16b(in); /* loop size */ if (size == 0) size = 1; write16b(out, size); } read32b(in); /* bypass "LONG" chunk */ write8(out, pat_pos = read8(in)); /* pattern table lenght */ write8(out, read8(in)); /* NoiseTracker byte */ read32b(in); /* bypass "PATT" chunk */ /* read and write pattern list and get highest patt number */ for (pat_max = i = 0; i < pat_pos; i++) { write8(out, c1 = read8(in)); if (c1 > pat_max) pat_max = c1; } for (; i < 128; i++) write8(out, 0); write32b(out, PW_MOD_MAGIC); /* write ptk ID */ read32b(in); /* bypass "SONG" chunk */ for (i = 0; i <= pat_max; i++) /* pattern data */ pw_move_data(out, in, 1024); read32b(in); /* bypass "SAMP" chunk */ pw_move_data(out, in, ssize); /* sample data */ return 0; }
static int depack_mp(FILE *in, FILE *out) { uint8 c1; uint8 ptable[128]; uint8 max; int i; int size, ssize = 0; memset(ptable, 0, 128); pw_write_zero(out, 20); /* title */ if (read32b(in) != MAGIC_TRK1) /* TRK1 */ fseek(in, -4, SEEK_CUR); for (i = 0; i < 31; i++) { pw_write_zero(out, 22); /* sample name */ write16b(out, size = read16b(in)); /* size */ ssize += size * 2; write8(out, read8(in)); /* finetune */ write8(out, read8(in)); /* volume */ write16b(out, read16b(in)); /* loop start */ write16b(out, read16b(in)); /* loop size */ } write8(out, read8(in)); /* pattern table length */ write8(out, read8(in)); /* NoiseTracker restart byte */ for (max = i = 0; i < 128; i++) { write8(out, c1 = read8(in)); if (c1 > max) max = c1; } max++; write32b(out, PW_MOD_MAGIC); /* M.K. */ if (read32b(in) != 0) /* bypass unknown empty bytes */ fseek (in, -4, SEEK_CUR); pw_move_data(out, in, 1024 * max); /* pattern data */ pw_move_data(out, in, ssize); /* sample data */ return 0; }
static int depack_hrt(HIO_HANDLE *in, FILE *out) { uint8 buf[1024]; uint8 c1, c2, c3, c4; int len, npat; int ssize = 0; int i, j; memset(buf, 0, 950); hio_read(buf, 950, 1, in); /* read header */ for (i = 0; i < 31; i++) /* erase addresses */ *(uint32 *)(buf + 38 + 30 * i) = 0; fwrite(buf, 950, 1, out); /* write header */ for (i = 0; i < 31; i++) /* samples size */ ssize += readmem16b(buf + 42 + 30 * i) * 2; write8(out, len = hio_read8(in)); /* song length */ write8(out, hio_read8(in)); /* nst byte */ hio_read(buf, 1, 128, in); /* pattern list */ npat = 0; /* number of patterns */ for (i = 0; i < 128; i++) { if (buf[i] > npat) npat = buf[i]; } npat++; write32b(out, PW_MOD_MAGIC); /* write ptk ID */ /* pattern data */ hio_seek(in, 1084, SEEK_SET); for (i = 0; i < npat; i++) { for (j = 0; j < 256; j++) { buf[0] = hio_read8(in); buf[1] = hio_read8(in); buf[2] = hio_read8(in); buf[3] = hio_read8(in); buf[0] /= 2; c1 = buf[0] & 0xf0; if (buf[1] == 0) c2 = 0; else { c1 |= ptk_table[buf[1] / 2][0]; c2 = ptk_table[buf[1] / 2][1]; } c3 = ((buf[0] << 4) & 0xf0) | buf[2]; c4 = buf[3]; write8(out, c1); write8(out, c2); write8(out, c3); write8(out, c4); } } /* sample data */ pw_move_data(out, in, ssize); return 0; }
static int depack_pp21(HIO_HANDLE *in, FILE *out) { uint8 ptable[128]; int max = 0; uint8 trk[4][128]; int tptr[512][64]; uint8 numpat; uint8 *tab; uint8 buf[1024]; int i, j; int size; int ssize = 0; int tabsize = 0; /* Reference Table Size */ memset(ptable, 0, 128); memset(trk, 0, 4 * 128); memset(tptr, 0, 512 * 128); pw_write_zero(out, 20); /* title */ for (i = 0; i < 31; i++) { pw_write_zero(out, 22); /* sample name */ write16b(out, size = hio_read16b(in)); ssize += size * 2; write8(out, hio_read8(in)); /* finetune */ write8(out, hio_read8(in)); /* volume */ write16b(out, hio_read16b(in)); /* loop start */ write16b(out, hio_read16b(in)); /* loop size */ } write8(out, numpat = hio_read8(in)); /* number of patterns */ write8(out, hio_read8(in)); /* NoiseTracker restart byte */ max = 0; for (j = 0; j < 4; j++) { for (i = 0; i < 128; i++) { trk[j][i] = hio_read8(in); if (trk[j][i] > max) max = trk[j][i]; } } /* write pattern table without any optimizing ! */ for (i = 0; i < numpat; i++) write8(out, i); pw_write_zero(out, 128 - i); write32b(out, PW_MOD_MAGIC); /* M.K. */ /* PATTERN DATA code starts here */ /*printf ("Highest track number : %d\n", max); */ for (j = 0; j <= max; j++) { for (i = 0; i < 64; i++) tptr[j][i] = hio_read16b(in); } /* read "reference table" size */ tabsize = hio_read32b(in); /* read "reference Table" */ tab = (uint8 *)malloc(tabsize); hio_read(tab, tabsize, 1, in); for (i = 0; i < numpat; i++) { memset(buf, 0, 1024); for (j = 0; j < 64; j++) { uint8 *b = buf + j * 16; memcpy(b, tab + tptr[trk[0][i]][j] * 4, 4); memcpy(b + 4, tab + tptr[trk[1][i]][j] * 4, 4); memcpy(b + 8, tab + tptr[trk[2][i]][j] * 4, 4); memcpy(b + 12, tab + tptr[trk[3][i]][j] * 4, 4); } fwrite (buf, 1024, 1, out); } free (tab); /* Now, it's sample data ... though, VERY quickly handled :) */ pw_move_data(out, in, ssize); return 0; }
static int depack_pru2(HIO_HANDLE *in, FILE *out) { uint8 header[2048]; uint8 npat; uint8 ptable[128]; uint8 max = 0; uint8 v[4][4]; int size, ssize = 0; int i, j; memset(header, 0, 2048); memset(ptable, 0, 128); memset(v, 0, 16); pw_write_zero(out, 20); /* title */ hio_seek(in, 8, SEEK_SET); for (i = 0; i < 31; i++) { pw_write_zero(out, 22); /*sample name */ write16b(out, size = hio_read16b(in)); /* size */ ssize += size * 2; write8(out, hio_read8(in)); /* finetune */ write8(out, hio_read8(in)); /* volume */ write16b(out, hio_read16b(in)); /* loop start */ write16b(out, hio_read16b(in)); /* loop size */ } write8(out, npat = hio_read8(in)); /* number of patterns */ write8(out, hio_read8(in)); /* noisetracker byte */ for (i = 0; i < 128; i++) { uint8 x; write8(out, x = hio_read8(in)); max = (x > max) ? x : max; } write32b(out, PW_MOD_MAGIC); /* pattern data stuff */ hio_seek(in, 770, SEEK_SET); for (i = 0; i <= max; i++) { for (j = 0; j < 256; j++) { uint8 c[4]; memset(c, 0, 4); header[0] = hio_read8(in); if (header[0] == 0x80) { write32b(out, 0); } else if (header[0] == 0xc0) { fwrite(v[0], 4, 1, out); memcpy(c, v[0], 4); } else if (header[0] >= 74) { return -1; } else { header[1] = hio_read8(in); header[2] = hio_read8(in); c[0] = (header[1] & 0x80) >> 3; c[0] |= ptk_table[(header[0] >> 1)][0]; c[1] = ptk_table[(header[0] >> 1)][1]; c[2] = (header[1] & 0x70) << 1; c[2] |= (header[0] & 0x01) << 4; c[2] |= (header[1] & 0x0f); c[3] = header[2]; fwrite(c, 1, 4, out); } /* rol previous values */ memcpy(&v[0], &v[1], 4); memcpy(&v[1], &v[2], 4); memcpy(&v[2], &v[3], 4); memcpy(v[3], c, 4); } } /* sample data */ pw_move_data(out, in, ssize); return 0; }
static int depack_ksm (xmp_file in, xmp_file out) { uint8 tmp[1024]; uint8 c1, c5; uint8 plist[128]; uint8 trknum[128][4]; uint8 real_tnum[128][4]; uint8 tdata[4][192]; uint8 Max; uint8 PatPos; uint8 Status = ON; int ssize = 0; int i, j, k; memset(plist, 0, 128); memset(trknum, 0, 128 * 4); memset(real_tnum, 0, 128 * 4); /* title */ xmp_fseek(in, 2, SEEK_SET); pw_move_data(out, in, 13); pw_write_zero(out, 7); /* read and write whole header */ /*printf ( "Converting sample headers ... " ); */ xmp_fseek(in, 32, SEEK_SET); for (i = 0; i < 15; i++) { pw_write_zero(out, 22); /* write name */ xmp_fseek(in, 20, SEEK_CUR); /* 16 unknown/4 addr bytes */ write16b(out, (k = read16b(in)) / 2); /* size */ ssize += k; write8(out, 0); /* finetune */ write8(out, read8(in)); /* volume */ read8(in); /* bypass 1 unknown byte */ write16b(out, (j = read16b(in)) / 2); /* loop start */ j = k - j; write16b(out, j != k ? j / 2 : 1); /* loop size */ xmp_fseek(in, 6, SEEK_CUR); /* bypass 6 unknown bytes */ } memset(tmp, 0, 30); tmp[29] = 0x01; for (i = 0; i < 16; i++) xmp_fwrite(tmp, 30, 1, out); /* pattern list */ xmp_fseek (in, 512, 0); for (Max = PatPos = 0; PatPos < 128; PatPos++) { xmp_fread(&trknum[PatPos][0], 1, 1, in); xmp_fread(&trknum[PatPos][1], 1, 1, in); xmp_fread(&trknum[PatPos][2], 1, 1, in); xmp_fread(&trknum[PatPos][3], 1, 1, in); if (trknum[PatPos][0] == 0xFF) break; if (trknum[PatPos][0] > Max) Max = trknum[PatPos][0]; if (trknum[PatPos][1] > Max) Max = trknum[PatPos][1]; if (trknum[PatPos][2] > Max) Max = trknum[PatPos][2]; if (trknum[PatPos][3] > Max) Max = trknum[PatPos][3]; } write8(out, PatPos); /* write patpos */ write8(out, 0x7f); /* ntk byte */ /* sort tracks numbers */ c5 = 0x00; for (i = 0; i < PatPos; i++) { if (i == 0) { plist[0] = c5; c5 += 0x01; continue; } for (j = 0; j < i; j++) { Status = ON; for (k = 0; k < 4; k++) { if (trknum[j][k] != trknum[i][k]) { Status = OFF; break; } } if (Status == ON) { plist[i] = plist[j]; break; } } if (Status == OFF) { plist[i] = c5; c5 += 0x01; } Status = ON; } /* c5 is the Max pattern number */ /* create real list of tracks numbers for really existing patterns */ c1 = 0x00; for (i = 0; i < PatPos; i++) { if (i == 0) { real_tnum[c1][0] = trknum[i][0]; real_tnum[c1][1] = trknum[i][1]; real_tnum[c1][2] = trknum[i][2]; real_tnum[c1][3] = trknum[i][3]; c1 += 0x01; continue; } for (j = 0; j < i; j++) { Status = ON; if (plist[i] == plist[j]) { Status = OFF; break; } } if (Status == OFF) continue; real_tnum[c1][0] = trknum[i][0]; real_tnum[c1][1] = trknum[i][1]; real_tnum[c1][2] = trknum[i][2]; real_tnum[c1][3] = trknum[i][3]; c1 += 0x01; Status = ON; } xmp_fwrite(plist, 128, 1, out); /* write pattern list */ write32b(out, PW_MOD_MAGIC); /* write ID */ /* pattern data */ for (i = 0; i < c5; i++) { memset(tmp, 0, 1024); memset(tdata, 0, 192 * 4); xmp_fseek(in, 1536 + 192 * real_tnum[i][0], SEEK_SET); xmp_fread(tdata[0], 192, 1, in); xmp_fseek(in, 1536 + 192 * real_tnum[i][1], SEEK_SET); xmp_fread(tdata[1], 192, 1, in); xmp_fseek(in, 1536 + 192 * real_tnum[i][2], SEEK_SET); xmp_fread(tdata[2], 192, 1, in); xmp_fseek(in, 1536 + 192 * real_tnum[i][3], SEEK_SET); xmp_fread(tdata[3], 192, 1, in); for (j = 0; j < 64; j++) { int x = j * 16; tmp[x] = ptk_table[tdata[0][j * 3]][0]; tmp[x + 1] = ptk_table[tdata[0][j * 3]][1]; if ((tdata[0][j * 3 + 1] & 0x0f) == 0x0d) tdata[0][j * 3 + 1] -= 0x03; tmp[x + 2] = tdata[0][j * 3 + 1]; tmp[x + 3] = tdata[0][j * 3 + 2]; tmp[x + 4] = ptk_table[tdata[1][j * 3]][0]; tmp[x + 5] = ptk_table[tdata[1][j * 3]][1]; if ((tdata[1][j * 3 + 1] & 0x0f) == 0x0d) tdata[1][j * 3 + 1] -= 0x03; tmp[x + 6] = tdata[1][j * 3 + 1]; tmp[x + 7] = tdata[1][j * 3 + 2]; tmp[x + 8] = ptk_table[tdata[2][j * 3]][0]; tmp[x + 9] = ptk_table[tdata[2][j * 3]][1]; if ((tdata[2][j * 3 + 1] & 0x0f) == 0x0d) tdata[2][j * 3 + 1] -= 0x03; tmp[x + 10] = tdata[2][j * 3 + 1]; tmp[x + 11] = tdata[2][j * 3 + 2]; tmp[x + 12] = ptk_table[tdata[3][j * 3]][0]; tmp[x + 13] = ptk_table[tdata[3][j * 3]][1]; if ((tdata[3][j * 3 + 1] & 0x0f) == 0x0d) tdata[3][j * 3 + 1] -= 0x03; tmp[x + 14] = tdata[3][j * 3 + 1]; tmp[x + 15] = tdata[3][j * 3 + 2]; } xmp_fwrite(tmp, 1024, 1, out); } /* sample data */ xmp_fseek(in, 1536 + (192 * (Max + 1)), SEEK_SET); pw_move_data(out, in, ssize); return 0; }
static int depack_tdd(HIO_HANDLE *in, FILE *out) { uint8 *tmp; uint8 pat[1024]; uint8 pmax; int i, j, k; int size, ssize = 0; int saddr[31]; int ssizes[31]; memset(saddr, 0, 31 * 4); memset(ssizes, 0, 31 * 4); /* write ptk header */ pw_write_zero(out, 1080); /* read/write pattern list + size and ntk byte */ tmp = (uint8 *)malloc(130); memset(tmp, 0, 130); fseek(out, 950, 0); hio_read(tmp, 130, 1, in); fwrite(tmp, 130, 1, out); for (pmax = i = 0; i < 128; i++) { if (tmp[i + 2] > pmax) { pmax = tmp[i + 2]; } } free(tmp); /* sample descriptions */ for (i = 0; i < 31; i++) { fseek(out, 42 + (i * 30), SEEK_SET); /* sample address */ saddr[i] = hio_read32b(in); /* read/write size */ write16b(out, size = hio_read16b(in)); ssize += size; ssizes[i] = size; write8(out, hio_read8(in)); /* read/write finetune */ write8(out, hio_read8(in)); /* read/write volume */ /* read/write loop start */ write16b(out, (hio_read32b(in) - saddr[i]) / 2); write16b(out, hio_read16b(in)); /* read/write replen */ } /* bypass Samples datas */ hio_seek(in, ssize, SEEK_CUR); /* write ptk's ID string */ fseek(out, 0, SEEK_END); write32b(out, PW_MOD_MAGIC); /* read/write pattern data */ tmp = (uint8 *)malloc(1024); for (i = 0; i <= pmax; i++) { memset(tmp, 0, 1024); memset(pat, 0, 1024); hio_read(tmp, 1024, 1, in); for (j = 0; j < 64; j++) { for (k = 0; k < 4; k++) { int x = j * 16 + k * 4; /* fx arg */ pat[x + 3] = tmp[x + 3]; /* fx */ pat[x + 2] = tmp[x + 2] & 0x0f; /* smp */ pat[x] = tmp[x] & 0xf0; pat[x + 2] |= (tmp[x] << 4) & 0xf0; /* note */ pat[x] |= ptk_table[tmp[x + 1] / 2][0]; pat[x + 1] = ptk_table[tmp[x + 1] / 2][1]; } } fwrite(pat, 1024, 1, out); } free(tmp); /* Sample data */ for (i = 0; i < 31; i++) { if (ssizes[i] == 0) continue; hio_seek(in, saddr[i], SEEK_SET); pw_move_data(out, in, ssizes[i]); } return 0; }
static int depack_eu(FILE *in, FILE *out) { uint8 tmp[1080]; uint8 c1; int npat, smp_addr; int ssize = 0; int trk_addr[128][4]; int i, j, k; /* read header ... same as ptk */ fread(tmp, 1080, 1, in); fwrite(tmp, 1080, 1, out); /* now, let's sort out that a bit :) */ /* first, the whole sample size */ for (i = 0; i < 31; i++) ssize += 2 * readmem16b(tmp + i * 30 + 42); /* now, the pattern list .. and the max */ for (npat = i = 0; i < 128; i++) { if (tmp[952 + i] > npat) npat = tmp[952 + i]; } npat++; write32b(out, PW_MOD_MAGIC); /* write ptk ID */ smp_addr = read32b(in); /* read sample data address */ /* read tracks addresses */ for (i = 0; i < npat; i++) { for (j = 0; j < 4; j++) trk_addr[i][j] = read16b(in); } /* the track data now ... */ for (i = 0; i < npat; i++) { memset(tmp, 0, 1024); for (j = 0; j < 4; j++) { fseek(in, trk_addr[i][j], SEEK_SET); for (k = 0; k < 64; k++) { uint8 *x = &tmp[k * 16 + j * 4]; c1 = read8(in); if ((c1 & 0xc0) == 0x00) { *x++ = c1; *x++ = read8(in); *x++ = read8(in); *x++ = read8(in); continue; } if ((c1 & 0xc0) == 0xc0) { k += (c1 & 0x3f); continue; } if ((c1 & 0xc0) == 0x40) { x += 2; *x++ = c1 & 0x0f; *x++ = read8(in); continue; } if ((c1 & 0xc0) == 0x80) { *x++ = read8(in); *x++ = read8(in); *x++ = (c1 << 4) & 0xf0; continue; } } } fwrite(tmp, 1024, 1, out); } fseek(in, smp_addr, SEEK_SET); pw_move_data(out, in, ssize); return 0; }
static int depack_skyt(HIO_HANDLE *in, FILE *out) { uint8 c1, c2, c3, c4; uint8 ptable[128]; uint8 pat_pos; uint8 pat[1024]; int i = 0, j = 0, k = 0; int trkval[128][4]; int trk_addr; int size, ssize = 0; memset(ptable, 0, 128); memset(trkval, 0, 128 * 4); pw_write_zero(out, 20); /* write title */ /* read and write sample descriptions */ for (i = 0; i < 31; i++) { pw_write_zero(out, 22); /*sample name */ write16b(out, size = hio_read16b(in)); /* sample size */ ssize += size * 2; write8(out, hio_read8(in)); /* finetune */ write8(out, hio_read8(in)); /* volume */ write16b(out, hio_read16b(in)); /* loop start */ write16b(out, hio_read16b(in)); /* loop size */ } hio_read32b(in); /* bypass 8 empty bytes */ hio_read32b(in); hio_read32b(in); /* bypass "SKYT" ID */ pat_pos = hio_read8(in) + 1; /* pattern table lenght */ if (pat_pos >= 128) { return -1; } write8(out, pat_pos); write8(out, 0x7f); /* write NoiseTracker byte */ /* read track numbers ... and deduce pattern list */ for (i = 0; i < pat_pos; i++) { for (j = 0; j < 4; j++) { trkval[i][j] = hio_read16b(in); } } /* write pseudo pattern list */ for (i = 0; i < 128; i++) { write8(out, i < pat_pos ? i : 0); } write32b(out, PW_MOD_MAGIC); /* write ptk's ID */ hio_read8(in); /* bypass $00 unknown byte */ /* get track address */ trk_addr = hio_tell(in); /* track data */ for (i = 0; i < pat_pos; i++) { memset(pat, 0, 1024); for (j = 0; j < 4; j++) { hio_seek(in, trk_addr + ((trkval[i][j] - 1)<<8), SEEK_SET); for (k = 0; k < 64; k++) { int x = k * 16 + j * 4; c1 = hio_read8(in); c2 = hio_read8(in); c3 = hio_read8(in); c4 = hio_read8(in); pat[x] = (c2 & 0xf0) | ptk_table[c1][0]; pat[x + 1] = ptk_table[c1][1]; pat[x + 2] = ((c2 << 4) & 0xf0) | c3; pat[x + 3] = c4; } } fwrite(pat, 1024, 1, out); } /* sample data */ pw_move_data(out, in, ssize); return 0; }
static int depack_fuzz(FILE *in, FILE *out) { uint8 c1; uint8 data[1024]; uint8 ord[128]; uint8 tidx[128][16]; uint8 tidx_real[128][4]; uint8 track[4][256]; uint8 status = 1; int len, ntrk, npat; int size, ssize = 0; int lps, lsz; int i, j, k, l; memset(tidx, 0, 128 * 16); memset(tidx_real, 0, 128 * 4); memset(ord, 0, 128); read32b(in); /* bypass ID */ read16b(in); /* bypass 2 unknown bytes */ pw_write_zero(out, 20); /* write title */ for (i = 0; i < 31; i++) { pw_move_data(out, in, 22); /*sample name */ fseek(in, 38, SEEK_CUR); write16b(out, size = read16b(in)); ssize += size * 2; lps = read16b(in); /* loop start */ lsz = read16b(in); /* loop size */ write8(out, read8(in)); /* finetune */ write8(out, read8(in)); /* volume */ write16b(out, lps); write16b(out, lsz > 0 ? lsz : 1); } write8(out, len = read8(in)); /* size of pattern list */ ntrk = read8(in); /* read the number of tracks */ write8(out, 0x7f); /* write noisetracker byte */ /* place file pointer at track number list address */ fseek(in, 2118, SEEK_SET); /* read tracks numbers */ for (i = 0; i < 4; i++) { for (j = 0; j < len; j++) fread(&tidx[j][i * 4], 1, 4, in); } /* sort tracks numbers */ npat = 0; for (i = 0; i < len; i++) { if (i == 0) { ord[0] = npat++; continue; } for (j = 0; j < i; j++) { status = 1; for (k = 0; k < 4; k++) { if (tidx[j][k * 4] != tidx[i][k * 4]) { status = 0; break; } } if (status == 1) { ord[i] = ord[j]; break; } } if (status == 0) ord[i] = npat++; status = 1; } /* create a list of tracks numbers for the really existing patterns */ c1 = 0x00; for (i = 0; i < len; i++) { if (i == 0) { tidx_real[c1][0] = tidx[i][0]; tidx_real[c1][1] = tidx[i][4]; tidx_real[c1][2] = tidx[i][8]; tidx_real[c1][3] = tidx[i][12]; c1++; continue; } for (j = 0; j < i; j++) { status = 1; if (ord[i] == ord[j]) { status = 0; break; } } if (status == 0) continue; tidx_real[c1][0] = tidx[i][0]; tidx_real[c1][1] = tidx[i][4]; tidx_real[c1][2] = tidx[i][8]; tidx_real[c1][3] = tidx[i][12]; c1++; status = 1; } fwrite(ord, 128, 1, out); /* write pattern list */ write32b(out, PW_MOD_MAGIC); /* write ID */ /* pattern data */ l = 2118 + len * 16; for (i = 0; i < npat; i++) { memset(data, 0, 1024); memset(track, 0, 4 << 8); fseek(in, l + (tidx_real[i][0] << 8), SEEK_SET); fread(track[0], 256, 1, in); fseek(in, l + (tidx_real[i][1] << 8), SEEK_SET); fread(track[1], 256, 1, in); fseek(in, l + (tidx_real[i][2] << 8), SEEK_SET); fread(track[2], 256, 1, in); fseek(in, l + (tidx_real[i][3] << 8), SEEK_SET); fread(track[3], 256, 1, in); for (j = 0; j < 64; j++) { memcpy(&data[j * 16 ], &track[0][j * 4], 4); memcpy(&data[j * 16 + 4 ], &track[1][j * 4], 4); memcpy(&data[j * 16 + 8 ], &track[2][j * 4], 4); memcpy(&data[j * 16 + 12], &track[3][j * 4], 4); data[j * 16 + 15] = track[3][j * 4 + 3]; } fwrite(data, 1024, 1, out); } /* sample data */ /* bypass the "SEnd" unidentified ID */ fseek(in, l + (ntrk << 8) + 4, SEEK_SET); pw_move_data(out, in, ssize); return 0; }
static int depack_pha(HIO_HANDLE *in, FILE *out) { uint8 c1, c2; uint8 pnum[128]; uint8 pnum1[128]; uint8 nop; uint8 *pdata; uint8 *pat; uint8 onote[4][4]; uint8 note, ins, fxt, fxp; uint8 npat = 0x00; int paddr[128]; int i, j, k; int paddr1[128]; int paddr2[128]; int tmp_ptr, tmp; int pat_addr; int psize; int size, ssize = 0; int smp_addr; short ocpt[4]; memset(paddr, 0, 128 * 4); memset(paddr1, 0, 128 * 4); memset(paddr2, 0, 128 * 4); memset(pnum, 0, 128); memset(pnum1, 0, 128); memset(onote, 0, 4 * 4); memset(ocpt, 0, 4 * 2); pw_write_zero(out, 20); /* title */ for (i = 0; i < 31; i++) { int vol, fin, lps, lsz; pw_write_zero(out, 22); /* sample name */ write16b(out, size = hio_read16b(in)); /* size */ ssize += size * 2; hio_read8(in); /* ??? */ vol = hio_read8(in); /* volume */ lps = hio_read16b(in); /* loop start */ lsz = hio_read16b(in); /* loop size */ hio_read32b(in); /* sample address */ hio_read8(in); /* ??? */ fin = hio_read8(in); /* finetune - 11 */ if (fin != 0) { fin += 11; } write8(out, fin); write8(out, vol); write16b(out, lps); write16b(out, lsz); } hio_seek(in, 14, SEEK_CUR); /* bypass unknown 14 bytes */ for (i = 0; i < 128; i++) paddr[i] = hio_read32b(in); /* ordering of patterns addresses */ tmp_ptr = 0; for (i = 0; i < 128; i++) { if (i == 0) { pnum[0] = 0; tmp_ptr++; continue; } for (j = 0; j < i; j++) { if (paddr[i] == paddr[j]) { pnum[i] = pnum[j]; break; } } if (j == i) pnum[i] = tmp_ptr++; } /* correct re-order */ for (i = 0; i < 128; i++) paddr1[i] = paddr[i]; restart: for (i = 0; i < 128; i++) { for (j = 0; j < i; j++) { if (paddr1[i] < paddr1[j]) { tmp = pnum[j]; pnum[j] = pnum[i]; pnum[i] = tmp; tmp = paddr1[j]; paddr1[j] = paddr1[i]; paddr1[i] = tmp; goto restart; } } } j = 0; for (i = 0; i < 128; i++) { if (i == 0) { paddr2[j] = paddr1[i]; continue; } if (paddr1[i] == paddr2[j]) continue; paddr2[++j] = paddr1[i]; } /* try to take care of unused patterns ... HARRRRRRD */ memset(paddr1, 0, 128 * 4); j = 0; k = paddr[0]; /* 120 ... leaves 8 unused ptk_tableible patterns .. */ for (i = 0; i < 120; i++) { paddr1[j] = paddr2[i]; j += 1; if ((paddr2[i + 1] - paddr2[i]) > 1024) { paddr1[j] = paddr2[i] + 1024; j += 1; } } for (c1 = 0; c1 < 128; c1++) { for (c2 = 0; c2 < 128; c2++) { if (paddr[c1] == paddr1[c2]) { pnum1[c1] = c2; } } } memset(pnum, 0, 128); pat_addr = 999999l; for (i = 0; i < 128; i++) { pnum[i] = pnum1[i]; if (paddr[i] < pat_addr) pat_addr = paddr[i]; } /* try to get the number of pattern in pattern list */ for (nop = 128; nop > 0; nop--) { if (pnum[nop - 1] != 0) break; } /* write this value */ write8(out, nop); /* get highest pattern number */ for (i = 0; i < nop; i++) if (pnum[i] > npat) npat = pnum[i]; write8(out, 0x7f); /* ntk restart byte */ for (i = 0; i < 128; i++) /* write pattern list */ write8(out, pnum[i]); write32b(out, PW_MOD_MAGIC); /* ID string */ smp_addr = hio_tell(in); hio_seek(in, pat_addr, SEEK_SET); /* pattern datas */ /* read ALL pattern data */ /* FIXME: shouldn't use file size */ #if 0 j = ftell (in); fseek (in, 0, 2); /* SEEK_END */ psize = ftell (in) - j; fseek (in, j, 0); /* SEEK_SET */ #endif psize = npat * 1024; pdata = (uint8 *) malloc (psize); psize = hio_read(pdata, 1, psize, in); npat += 1; /* coz first value is $00 */ pat = (uint8 *)malloc(npat * 1024); memset(pat, 0, npat * 1024); j = 0; for (i = 0; j < psize; i++) { if (pdata[i] == 0xff) { i += 1; ocpt[(k + 3) % 4] = 0xff - pdata[i]; continue; } if (ocpt[k % 4] != 0) { ins = onote[k % 4][0]; note = onote[k % 4][1]; fxt = onote[k % 4][2]; fxp = onote[k % 4][3]; ocpt[k % 4] -= 1; pat[j] = ins & 0xf0; pat[j] |= ptk_table[(note / 2)][0]; pat[j + 1] = ptk_table[(note / 2)][1]; pat[j + 2] = (ins << 4) & 0xf0; pat[j + 2] |= fxt; pat[j + 3] = fxp; k += 1; j += 4; i -= 1; continue; } ins = pdata[i]; note = pdata[i + 1]; fxt = pdata[i + 2]; fxp = pdata[i + 3]; onote[k % 4][0] = ins; onote[k % 4][1] = note; onote[k % 4][2] = fxt; onote[k % 4][3] = fxp; i += 3; pat[j] = ins & 0xf0; pat[j] |= ptk_table[(note / 2)][0]; pat[j + 1] = ptk_table[(note / 2)][1]; pat[j + 2] = (ins << 4) & 0xf0; pat[j + 2] |= fxt; pat[j + 3] = fxp; k += 1; j += 4; } fwrite(pat, npat * 1024, 1, out); free(pdata); free(pat); /* Sample data */ hio_seek(in, smp_addr, SEEK_SET); pw_move_data(out, in, ssize); return 0; }
static int depack_fuchs(FILE *in, FILE *out) { uint8 *tmp; uint8 c1; uint8 pmax; int ssize = 0; int SampleSizes[16]; int LoopStart[16]; int i, j; memset(SampleSizes, 0, 16 * 4); memset(LoopStart, 0, 16 * 4); pw_write_zero(out, 1080); /* write ptk header */ fseek(out, 0, SEEK_SET); pw_move_data(out, in, 10); /* read/write title */ ssize = read32b(in); /* read all sample data size */ /* read/write sample sizes */ for (i = 0; i < 16; i++) { fseek(out, 42 + i * 30, SEEK_SET); write16b(out, (SampleSizes[i] = read16b(in)) / 2); } /* read/write volumes */ for (i = 0; i < 16; i++) { fseek(out, 45 + i * 30, SEEK_SET); fseek(in, 1, SEEK_CUR); write8(out, read8(in)); } /* read/write loop start */ for (i = 0; i < 16; i++) { fseek(out, 46 + i * 30, SEEK_SET); write8(out, (LoopStart[i] = read16b(in)) / 2); } /* write replen */ for (i = 0; i < 16; i++) { fseek(out, 48 + i * 30, SEEK_SET); j = SampleSizes[i] - LoopStart[i]; if ((j == 0) || (LoopStart[i] == 0)) write16b(out, 0x0001); else write16b(out, j / 2); } /* fill replens up to 31st sample wiz $0001 */ for (i = 16; i < 31; i++) { fseek(out, 48 + i * 30, SEEK_SET); write16b(out, 0x0001); } /* that's it for the samples ! */ /* now, the pattern list */ /* read number of pattern to play */ fseek(out, 950, SEEK_SET); /* bypass empty byte (saved wiz a WORD ..) */ fseek(in, 1, SEEK_CUR); write8(out, read8(in)); /* write ntk byte */ write8(out, 0x7f); /* read/write pattern list */ for (pmax = i = 0; i < 40; i++) { fseek(in, 1, SEEK_CUR); write8(out, c1 = read8(in)); if (c1 > pmax) pmax = c1; } /* write ptk's ID */ fseek(out, 0, SEEK_END); write32b(out, PW_MOD_MAGIC); /* now, the pattern data */ /* bypass the "SONG" ID */ fseek(in, 4, 1); /* read pattern data size */ j = read32b(in); /* read pattern data */ tmp = (uint8 *)malloc(j); fread(tmp, j, 1, in); /* convert shits */ for (i = 0; i < j; i += 4) { /* convert fx C arg back to hex value */ if ((tmp[i + 2] & 0x0f) == 0x0c) { c1 = tmp[i + 3]; if (c1 <= 9) { tmp[i + 3] = c1; continue; } if ((c1 >= 16) && (c1 <= 25)) { tmp[i + 3] = (c1 - 6); continue; } if ((c1 >= 32) && (c1 <= 41)) { tmp[i + 3] = (c1 - 12); continue; } if ((c1 >= 48) && (c1 <= 57)) { tmp[i + 3] = (c1 - 18); continue; } if ((c1 >= 64) && (c1 <= 73)) { tmp[i + 3] = (c1 - 24); continue; } if ((c1 >= 80) && (c1 <= 89)) { tmp[i + 3] = (c1 - 30); continue; } if ((c1 >= 96) && (c1 <= 100)) { tmp[i + 3] = (c1 - 36); continue; } } } /* write pattern data */ fwrite(tmp, j, 1, out); free(tmp); /* read/write sample data */ fseek (in, 4, SEEK_CUR); /* bypass "INST" Id */ for (i = 0; i < 16; i++) { if (SampleSizes[i] != 0) pw_move_data(out, in, SampleSizes[i]); } return 0; }
static int depack_pru1 (HIO_HANDLE *in, FILE *out) { uint8 header[2048]; uint8 c1, c2, c3, c4; uint8 npat, max; uint8 ptable[128]; int ssize = 0; int i, j; memset(header, 0, 2048); memset(ptable, 0, 128); /* read and write whole header */ hio_read(header, 950, 1, in); fwrite(header, 950, 1, out); /* get whole sample size */ for (i = 0; i < 31; i++) { ssize += readmem16b(header + i * 30 + 42) * 2; } /* read and write size of pattern list */ write8(out, npat = hio_read8(in)); memset(header, 0, 2048); /* read and write ntk byte and pattern list */ hio_read(header, 129, 1, in); fwrite(header, 129, 1, out); /* write ID */ write32b(out, PW_MOD_MAGIC); /* get number of pattern */ max = 0; for (i = 1; i < 129; i++) { if (header[i] > max) max = header[i]; } /* pattern data */ hio_seek(in, 1084, SEEK_SET); for (i = 0; i <= max; i++) { for (j = 0; j < 256; j++) { header[0] = hio_read8(in); header[1] = hio_read8(in); header[2] = hio_read8(in); header[3] = hio_read8(in); c1 = header[0] & 0xf0; c3 = (header[0] & 0x0f) << 4; c3 |= header[2]; c4 = header[3]; c1 |= ptk_table[header[1]][0]; c2 = ptk_table[header[1]][1]; write8(out, c1); write8(out, c2); write8(out, c3); write8(out, c4); } } /* sample data */ pw_move_data(out, in, ssize); return 0; }
static int depack_ntp(FILE *in, FILE *out) { uint8 buf[1024]; int i, j; int pat_addr[128]; short body_addr, smp_addr, nins, len, npat; int size, ssize = 0; read32b(in); /* skip MODU */ pw_move_data(out, in, 16); /* title */ write32b(out, 0); body_addr = read16b(in) + 4; /* get 'BODY' address */ nins = read16b(in); /* number of samples */ len = read16b(in); /* size of pattern list */ npat = read16b(in); /* number of patterns stored */ smp_addr = read16b(in) + body_addr + 4; /* get 'SAMP' address */ memset(buf, 0, 930); /* instruments */ for (i = 0; i < nins; i++) { int x = read8(in); /* instrument number */ if (x > 30) { fseek(in, 7, SEEK_CUR); continue; } x *= 30; buf[x + 25] = read8(in); /* volume */ size = read16b(in); /* size */ buf[x + 22] = size >> 8; buf[x + 23] = size & 0xff; ssize += size * 2; buf[x + 26] = read8(in); /* loop start */ buf[x + 27] = read8(in); buf[x + 28] = read8(in); /* loop size */ buf[x + 29] = read8(in); } fwrite(buf, 930, 1, out); write8(out, len); write8(out, 0x7f); /* pattern list */ memset(buf, 0, 128); for (i = 0; i < len; i++) buf[i] = read16b(in); fwrite(buf, 128, 1, out); /* pattern addresses now */ /* Where is on it */ memset(pat_addr, 0, 256); for (i = 0; i < npat; i++) pat_addr[i] = read16b(in); write32b(out, PW_MOD_MAGIC); /* pattern data now ... *gee* */ for (i = 0; i < npat; i++) { fseek(in, body_addr + 4 + pat_addr[i], SEEK_SET); memset(buf, 0, 1024); for (j = 0; j < 64; j++) { int x = read16b(in); if (x & 0x0001) fread(buf + j * 16, 1, 4, in); if (x & 0x0002) fread(buf + j * 16 + 4, 1, 4, in); if (x & 0x0004) fread(buf + j * 16 + 8, 1, 4, in); if (x & 0x0008) fread(buf + j * 16 + 12, 1, 4, in); } fwrite(buf, 1024, 1, out); } /* samples */ fseek(in, smp_addr, SEEK_SET); pw_move_data(out, in, ssize); return 0; }
static int depack_crb(HIO_HANDLE *in, FILE *out) { uint8 c1; uint8 ptable[128]; uint8 pat_pos, pat_max; uint8 pat[1024]; int taddr[512]; int i, j, k, l, m; int size, ssize = 0; memset(ptable, 0, 128); memset(taddr, 0, 512 * 4); pw_write_zero(out, 20); /* write title */ /* read and write sample descriptions */ for (i = 0; i < 31; i++) { pw_write_zero(out, 22); /*sample name */ write16b(out, size = hio_read16b(in)); /* size */ ssize += size * 2; write8(out, hio_read8(in)); /* finetune */ write8(out, hio_read8(in)); /* volume */ write16b(out, hio_read16b(in)); /* loop start */ size = hio_read16b(in); /* loop size */ write16b(out, size ? size : 1); } write8(out, pat_pos = hio_read8(in)); /* pat table length */ write8(out, hio_read8(in)); /* NoiseTracker byte */ /* read and write pattern list and get highest patt number */ for (pat_max = i = 0; i < 128; i++) { write8(out, c1 = hio_read8(in)); if (c1 > pat_max) pat_max = c1; } pat_max++; /* write ptk's ID */ write32b(out, PW_MOD_MAGIC); /* pattern data */ for (i = 0; i < pat_max; i++) { memset(pat, 0, 1024); for (j = 0; j < 4; j++) { int x = hio_tell(in); if (x < 0) { return -1; } taddr[i * 4 + j] = x; for (k = 0; k < 64; k++) { int y = k * 16 + j * 4; c1 = hio_read8(in); if (c1 == 0x80) { k += hio_read24b(in); continue; } if (c1 == 0xc0) { m = hio_read24b(in); l = hio_tell(in); /* Sanity check */ if (l < 0 || m >= 2048) return -1; hio_seek(in, taddr[m >> 2], SEEK_SET); for (m = 0; m < 64; m++) { int x = m * 16 + j * 4; c1 = hio_read8(in); if (c1 == 0x80) { m += hio_read24b(in); continue; } pat[x] = c1; pat[x + 1] = hio_read8(in); pat[x + 2] = hio_read8(in); pat[x + 3] = hio_read8(in); } hio_seek(in, l, SEEK_SET); k += 100; continue; } pat[y] = c1; pat[y + 1] = hio_read8(in); pat[y + 2] = hio_read8(in); pat[y + 3] = hio_read8(in); } } fwrite (pat, 1024, 1, out); }