comparison playercode/load_669.c @ 4:5d614bcc4287

Initial entry of mikmod into the CVS tree.
author darius
date Fri, 23 Jan 1998 16:05:08 +0000
parents
children
comparison
equal deleted inserted replaced
3:71e20a32bd84 4:5d614bcc4287
1 /*
2
3 Name: LOAD_669.C
4
5 Description:
6 Tran's 669 module loader
7
8 Portability:
9 All systems - all compilers (hopefully)
10
11 If this module is found to not be portable to any particular platform,
12 please contact Jake Stine at dracoirs@epix.net (see MIKMOD.TXT for
13 more information on contacting the author).
14
15 */
16
17 #include <string.h>
18 #include "mikmod.h"
19
20
21 // Raw 669 header struct:
22
23 typedef struct S69HEADER
24 { UBYTE marker[2];
25 CHAR message[108];
26 UBYTE nos;
27 UBYTE nop;
28 UBYTE looporder;
29 UBYTE orders[0x80];
30 UBYTE tempos[0x80];
31 UBYTE breaks[0x80];
32 } S69HEADER;
33
34
35 // Raw 669 sampleinfo struct:
36
37 typedef struct S69SAMPLE
38 { CHAR filename[13];
39 SLONG length;
40 SLONG loopbeg;
41 SLONG loopend;
42 } S69SAMPLE;
43
44
45 // Raw 669 Note struct
46
47 typedef struct S69NOTE
48 { UBYTE a,b,c;
49 } S69NOTE;
50
51
52 static S69NOTE *s69pat = NULL;
53 static S69HEADER *mh = NULL;
54
55 static CHAR *S69_Version[] =
56 { "669",
57 "Extended 669"
58 };
59
60
61 BOOL S69_Test(void)
62 {
63 UBYTE id[2];
64
65 if(!_mm_read_UBYTES(id,2,modfp)) return 0;
66 if(!memcmp(id,"if",2) || !memcmp(id,"JN",2))
67 { _mm_fseek(modfp,108,SEEK_CUR);
68 if(_mm_read_UBYTE(modfp) > 64) return 0;
69 if(_mm_read_UBYTE(modfp) > 128) return 0;
70 if(_mm_read_UBYTE(modfp) > 120) return 0;
71 return 1;
72 }
73 return 0;
74 }
75
76
77 BOOL S69_Init(void)
78 {
79 if(!(s69pat=(S69NOTE *)_mm_malloc(64*8*sizeof(S69NOTE)))) return 0;
80 if(!(mh=(S69HEADER *)_mm_calloc(1,sizeof(S69HEADER)))) return 0;
81 return 1;
82 }
83
84
85 void S69_Cleanup(void)
86 {
87 if(s69pat!=NULL) free(s69pat);
88 if(mh!=NULL) free(mh);
89
90 mh = NULL;
91 s69pat = NULL;
92 }
93
94
95 BOOL S69_LoadPatterns(void)
96 {
97 int t,s,q,tracks=0,t2,t3;
98 UBYTE note,inst,vol,a,b,c, lo;
99 S69NOTE *cur;
100
101 if(!AllocPatterns()) return 0;
102 if(!AllocTracks()) return 0;
103
104 for(t=0; t<of.numpat; t++)
105 { of.pattrows[t] = mh->breaks[t]+1;
106
107 // Load the pattern into the temp buffer
108 // and convert it into the 3-byte format
109
110 cur = s69pat;
111 for(t2=64; t2; t2--)
112 { for(t3=8; t3; t3--, cur++)
113 { cur->a = _mm_read_UBYTE(modfp);
114 cur->b = _mm_read_UBYTE(modfp);
115 cur->c = _mm_read_UBYTE(modfp);
116 }
117 }
118
119 if(feof(modfp))
120 { _mm_errno = MMERR_LOADING_PATTERN;
121 return 0;
122 }
123
124 for(s=0; s<8; s++)
125 { UniReset();
126 UniPTEffect(0xf,75); // was 78
127 UniPTEffect(0xf,3);
128
129 for(q=0; q<64; q++)
130 { a = s69pat[(q*8)+s].a;
131 b = s69pat[(q*8)+s].b;
132 c = s69pat[(q*8)+s].c;
133
134 note = a >> 2;
135 inst = ((a & 0x3) << 4) | ((b & 0xf0) >> 4);
136 vol = b & 0xf;
137
138 if(note < 0x3e)
139 { UniInstrument(inst);
140 UniNote(note+24);
141 }
142
143 if(note < 0x3f) UniPTEffect(0xc,vol<<2);
144
145 lo = c & 0xf;
146 switch(c >> 4)
147 { case 0:
148 UniPTEffect(0x1,lo);
149 break;
150
151 case 1:
152 UniPTEffect(0x2,lo);
153 break;
154
155 case 2:
156 UniPTEffect(0x3,lo);
157 break;
158
159 case 4:
160 UniPTEffect(0x4,lo);
161 break;
162 }
163 UniNewline();
164 }
165 if(!(of.tracks[tracks++]=UniDup())) return 0;
166 }
167 }
168 return 1;
169 }
170
171
172 BOOL S69_Load(void)
173 {
174 int t;
175 S69SAMPLE s;
176 SAMPLE *q;
177
178 // try to read module header
179
180 _mm_read_UBYTES(mh->marker,2,modfp);
181 _mm_read_UBYTES((UBYTE *)mh->message,108,modfp);
182 mh->nos = _mm_read_UBYTE(modfp);
183 mh->nop = _mm_read_UBYTE(modfp);
184 mh->looporder = _mm_read_UBYTE(modfp);
185 _mm_read_UBYTES(mh->orders,0x80,modfp);
186 _mm_read_UBYTES(mh->tempos,0x80,modfp);
187 _mm_read_UBYTES(mh->breaks,0x80,modfp);
188
189 // set module variables
190
191 of.initspeed = 6;
192 of.inittempo = 125;
193 of.songname = DupStr(mh->message,108);
194 of.modtype = strdup(S69_Version[memcmp(mh->marker,"JN",2)==0]);
195 of.numchn = 8;
196 of.numpat = mh->nop;
197 of.numins = of.numsmp = mh->nos;
198 of.numtrk = of.numchn*of.numpat;
199 of.flags = UF_XMPERIODS; // | UF_LINEAR;
200
201 if(!AllocPositions(0x80)) return 0;
202 for(t=0; t<0x80; t++)
203 { if(mh->orders[t]==0xff) break;
204 of.positions[t] = mh->orders[t];
205 }
206
207 of.numpos = t;
208
209 if(!AllocSamples()) return 0;
210 q = of.samples;
211
212 for(t=0; t<of.numins; t++)
213 { // try to read sample info
214
215 _mm_read_UBYTES((UBYTE *)s.filename,13,modfp);
216 s.length = _mm_read_I_SLONG(modfp);
217 s.loopbeg = _mm_read_I_SLONG(modfp);
218 s.loopend = _mm_read_I_SLONG(modfp);
219
220 if((s.length < 0) || (s.loopbeg < -1) || (s.loopend < -1))
221 { _mm_errno = MMERR_LOADING_HEADER;
222 return 0;
223 }
224
225 q->samplename = DupStr(s.filename,13);
226
227 q->seekpos = 0;
228 q->speed = 0;
229 q->length = s.length;
230 q->loopstart = s.loopbeg;
231 q->loopend = (s.loopend<s.length) ? s.loopend : s.length;
232 q->flags = (s.loopbeg<s.loopend) ? SF_LOOP : 0;
233 q->volume = 64;
234
235 q++;
236 }
237
238 if(!S69_LoadPatterns()) return 0;
239
240 return 1;
241 }
242
243
244 MLOADER load_669 =
245 { NULL,
246 "669",
247 "Portable 669 loader v0.1",
248 S69_Init,
249 S69_Test,
250 S69_Load,
251 S69_Cleanup,
252 NULL
253 };
254
255