예제 #1
0
파일: pha.c 프로젝트: Nlcke/gideros
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;
}
예제 #2
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;
}
예제 #3
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);
	}