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