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++) { pw_write_zero(out, 22); /*sample name */ write16b(out, size = hio_read16b(in)); /* size */ ssize += size * 2; hio_read8(in); write8(out, 0); /* finetune byte */ write8(out, hio_read8(in)); /* volume */ write16b(out, hio_read16b(in)); /* loop start */ write16b(out, hio_read16b(in)); /* loop size */ hio_read32b(in); c1 = hio_read8(in); if(c1 != 0x00) c1 += 0x0b; fseek(out, -6, SEEK_END); write8(out, c1); fseek(out, 0, SEEK_END); hio_seek(in, 1, SEEK_CUR); } 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_tdd (FILE *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); fread(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] = read32b(in); /* read/write size */ write16b(out, size = read16b(in)); ssize += size; ssizes[i] = size; write8(out, read8(in)); /* read/write finetune */ write8(out, read8(in)); /* read/write volume */ /* read/write loop start */ write16b(out, (read32b(in) - saddr[i]) / 2); write16b(out, read16b(in)); /* read/write replen */ } /* bypass Samples datas */ fseek(in, ssize, SEEK_CUR); /* write ptk's ID string */ fseek (out, 0, 2); 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); fread(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; fseek(in, saddr[i], SEEK_SET); pw_move_data(out, in, ssizes[i]); } 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); }