Mercurial > ~darius > hgwebdir.cgi > mikmod
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 |