1 /*
2  *   Skyt_Packer.c   Copyright (C) 1997 Asle / ReDoX
3  *
4  *   Modified in 2009,2014 by Claudio Matsuoka
5  */
6 
7 #include "prowiz.h"
8 
9 
depack_skyt(HIO_HANDLE * in,FILE * out)10 static int depack_skyt(HIO_HANDLE *in, FILE *out)
11 {
12 	uint8 c1, c2, c3, c4;
13 	uint8 ptable[128];
14 	uint8 pat_pos;
15 	uint8 pat[1024];
16 	int i = 0, j = 0, k = 0;
17 	int trkval[128][4];
18 	int trk_addr;
19 	int max_trk;
20 	int size, ssize = 0;
21 
22 	memset(ptable, 0, sizeof(ptable));
23 	memset(trkval, 0, sizeof(trkval));
24 
25 	pw_write_zero(out, 20);			/* write title */
26 
27 	/* read and write sample descriptions */
28 	for (i = 0; i < 31; i++) {
29 		pw_write_zero(out, 22);			/*sample name */
30 		write16b(out, size = hio_read16b(in));	/* sample size */
31 		ssize += size * 2;
32 		write8(out, hio_read8(in));			/* finetune */
33 		write8(out, hio_read8(in));			/* volume */
34 		write16b(out, hio_read16b(in));		/* loop start */
35 		write16b(out, hio_read16b(in));		/* loop size */
36 	}
37 
38 	hio_read32b(in);			/* bypass 8 empty bytes */
39 	hio_read32b(in);
40 	hio_read32b(in);			/* bypass "SKYT" ID */
41 
42 	pat_pos = hio_read8(in) + 1;		/* pattern table lenght */
43 	if (pat_pos >= 128) {
44 		return -1;
45 	}
46 	write8(out, pat_pos);
47 	write8(out, 0x7f);			/* write NoiseTracker byte */
48 
49 	/* read track numbers ... and deduce pattern list */
50 	max_trk = 0;
51 	for (i = 0; i < pat_pos; i++) {
52 		for (j = 0; j < 4; j++) {
53 			trkval[i][j] = hio_read16b(in);
54 			if (trkval[i][j] > max_trk) {
55 					max_trk = trkval[i][j];
56 			}
57 		}
58 	}
59 
60 	/* write pseudo pattern list */
61 	for (i = 0; i < 128; i++) {
62 		write8(out, i < pat_pos ? i : 0);
63 	}
64 
65 	write32b(out, PW_MOD_MAGIC);		/* write ptk's ID */
66 
67 	hio_read8(in);				/* bypass $00 unknown byte */
68 
69 	/* get track address */
70 	trk_addr = hio_tell(in);
71 
72 	/* track data */
73 	for (i = 0; i < pat_pos; i++) {
74 		memset(pat, 0, sizeof(pat));
75 		for (j = 0; j < 4; j++) {
76 			/* track 0 is blank and doesn't exist in the file. */
77 			if (trkval[i][j] == 0) {
78 				continue;
79 			}
80 			hio_seek(in, trk_addr + ((trkval[i][j] - 1)<<8), SEEK_SET);
81 			for (k = 0; k < 64; k++) {
82 				int x = k * 16 + j * 4;
83 
84 				c1 = hio_read8(in);
85 				c2 = hio_read8(in);
86 				c3 = hio_read8(in);
87 				c4 = hio_read8(in);
88 
89 				if (hio_error(in) || !PTK_IS_VALID_NOTE(c1)) {
90 					return -1;
91 				}
92 
93 				pat[x] = (c2 & 0xf0) | ptk_table[c1][0];
94 				pat[x + 1] = ptk_table[c1][1];
95 				pat[x + 2] = ((c2 << 4) & 0xf0) | c3;
96 				pat[x + 3] = c4;
97 			}
98 		}
99 		fwrite(pat, 1024, 1, out);
100 	}
101 
102 	/* skip to the end of the tracks/the start of the sample data. */
103 	if (hio_seek(in, trk_addr + (max_trk << 8), SEEK_SET) < 0) {
104 		return -1;
105 	}
106 
107 	/* sample data */
108 	pw_move_data(out, in, ssize);
109 
110 	return 0;
111 }
112 
test_skyt(const uint8 * data,char * t,int s)113 static int test_skyt(const uint8 *data, char *t, int s)
114 {
115 	int i;
116 
117 	PW_REQUEST_DATA(s, 8 * 31 + 12);
118 
119 	/* test 2 */
120 	for (i = 0; i < 31; i++) {
121 		if (data[8 * i + 4] > 0x40)
122 			return -1;
123 	}
124 
125 	if (readmem32b(data + 256) != MAGIC4('S','K','Y','T'))
126 		return -1;
127 
128 	pw_read_title(NULL, t, 0);
129 
130 	return 0;
131 }
132 
133 const struct pw_format pw_skyt = {
134 	"SKYT Packer",
135 	test_skyt,
136 	depack_skyt
137 };
138 
139