load_far.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:8k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* MikMod sound library
  2. (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file
  3. AUTHORS for complete list.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of
  7. the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  17. 02111-1307, USA.
  18. */
  19. /*==============================================================================
  20.   $Id: load_far.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $
  21.   Farandole (FAR) module loader
  22. ==============================================================================*/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #ifdef HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #include <stdio.h>
  30. #ifdef HAVE_MEMORY_H
  31. #include <memory.h>
  32. #endif
  33. #include <string.h>
  34. #include "mikmod_internals.h"
  35. #ifdef SUNOS
  36. extern int fprintf(FILE *, const char *, ...);
  37. #endif
  38. /*========== Module structure */
  39. typedef struct FARHEADER1 {
  40. UBYTE id[4]; /* file magic */
  41. CHAR  songname[40]; /* songname */
  42. CHAR  blah[3]; /* 13,10,26 */
  43. UWORD headerlen; /* remaining length of header in bytes */
  44. UBYTE version;
  45. UBYTE onoff[16];
  46. UBYTE edit1[9];
  47. UBYTE speed;
  48. UBYTE panning[16];
  49. UBYTE edit2[4];
  50. UWORD stlen;
  51. } FARHEADER1;
  52. typedef struct FARHEADER2 {
  53. UBYTE orders[256];
  54. UBYTE numpat;
  55. UBYTE snglen;
  56. UBYTE loopto;
  57. UWORD patsiz[256];
  58. } FARHEADER2;
  59. typedef struct FARSAMPLE {
  60. CHAR  samplename[32];
  61. ULONG length;
  62. UBYTE finetune;
  63. UBYTE volume;
  64. ULONG reppos;
  65. ULONG repend;
  66. UBYTE type;
  67. UBYTE loop;
  68. } FARSAMPLE;
  69. typedef struct FARNOTE {
  70. UBYTE note,ins,vol,eff;
  71. } FARNOTE;
  72. /*========== Loader variables */
  73. static CHAR FAR_Version[] = "Farandole";
  74. static FARHEADER1 *mh1 = NULL;
  75. static FARHEADER2 *mh2 = NULL;
  76. static FARNOTE *pat = NULL;
  77. static unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26};
  78. /*========== Loader code */
  79. BOOL FAR_Test(void)
  80. {
  81. UBYTE id[47];
  82. if(!_mm_read_UBYTES(id,47,modreader)) return 0;
  83. if((memcmp(id,FARSIG,4))||(memcmp(id+44,FARSIG+4,3))) return 0;
  84. return 1;
  85. }
  86. BOOL FAR_Init(void)
  87. {
  88. if(!(mh1 = (FARHEADER1*)_mm_malloc(sizeof(FARHEADER1)))) return 0;
  89. if(!(mh2 = (FARHEADER2*)_mm_malloc(sizeof(FARHEADER2)))) return 0;
  90. if(!(pat = (FARNOTE*)_mm_malloc(256*16*4*sizeof(FARNOTE)))) return 0;
  91. return 1;
  92. }
  93. void FAR_Cleanup(void)
  94. {
  95. _mm_free(mh1);
  96. _mm_free(mh2);
  97. _mm_free(pat);
  98. }
  99. static UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows)
  100. {
  101. int t,vibdepth=1;
  102. UniReset();
  103. for(t=0;t<rows;t++) {
  104. if(n->note) {
  105. UniInstrument(n->ins);
  106. UniNote(n->note+3*OCTAVE-1);
  107. }
  108. if (n->vol&0xf) UniPTEffect(0xc,(n->vol&0xf)<<2);
  109. if (n->eff)
  110. switch(n->eff>>4) {
  111. case 0x3: /* porta to note */
  112. UniPTEffect(0x3,(n->eff&0xf)<<4);
  113. break;
  114. case 0x4: /* retrigger */
  115. UniPTEffect(0x0e, 0x90 | (n->eff & 0x0f));
  116. break;
  117. case 0x5: /* set vibrato depth */
  118. vibdepth=n->eff&0xf;
  119. break;
  120. case 0x6: /* vibrato */
  121. UniPTEffect(0x4,((n->eff&0xf)<<4)|vibdepth);
  122. break;
  123. case 0x7: /* volume slide up */
  124. UniPTEffect(0xa,(n->eff&0xf)<<4);
  125. break;
  126. case 0x8: /* volume slide down */
  127. UniPTEffect(0xa,n->eff&0xf);
  128. break;
  129. case 0xb: /* panning */
  130. UniPTEffect(0xe,0x80|(n->eff&0xf));
  131. break;
  132. case 0xf: /* set speed */
  133. UniPTEffect(0xf,n->eff&0xf);
  134. break;
  135. /* others not yet implemented */
  136. default:
  137. #ifdef MIKMOD_DEBUG
  138. fprintf(stderr,"rFAR: unsupported effect %02Xn",n->eff);
  139. #endif
  140. break;
  141. }
  142. UniNewline();
  143. n+=16;
  144. }
  145. return UniDup();
  146. }
  147. BOOL FAR_Load(BOOL curious)
  148. {
  149. int t,u,tracks=0;
  150. SAMPLE *q;
  151. FARSAMPLE s;
  152. FARNOTE *crow;
  153. UBYTE smap[8];
  154. /* try to read module header (first part) */
  155. _mm_read_UBYTES(mh1->id,4,modreader);
  156. _mm_read_SBYTES(mh1->songname,40,modreader);
  157. _mm_read_SBYTES(mh1->blah,3,modreader);
  158. mh1->headerlen = _mm_read_I_UWORD (modreader);
  159. mh1->version   = _mm_read_UBYTE (modreader);
  160. _mm_read_UBYTES(mh1->onoff,16,modreader);
  161. _mm_read_UBYTES(mh1->edit1,9,modreader);
  162. mh1->speed     = _mm_read_UBYTE(modreader);
  163. _mm_read_UBYTES(mh1->panning,16,modreader);
  164. _mm_read_UBYTES(mh1->edit2,4,modreader);
  165. mh1->stlen     = _mm_read_I_UWORD (modreader);
  166. /* init modfile data */
  167. of.modtype   = strdup(FAR_Version);
  168. of.songname  = DupStr(mh1->songname,40,1);
  169. of.numchn    = 16;
  170. of.initspeed = mh1->speed;
  171. of.inittempo = 80;
  172. of.reppos    = 0;
  173. of.flags    |= UF_PANNING;
  174. for(t=0;t<16;t++) of.panning[t]=mh1->panning[t]<<4;
  175. /* read songtext into comment field */
  176. if(mh1->stlen)
  177. if (!ReadLinedComment(mh1->stlen, 66)) return 0;
  178. /* try to read module header (second part) */
  179. _mm_read_UBYTES(mh2->orders,256,modreader);
  180. mh2->numpat        = _mm_read_UBYTE(modreader);
  181. mh2->snglen        = _mm_read_UBYTE(modreader);
  182. mh2->loopto        = _mm_read_UBYTE(modreader);
  183. _mm_read_I_UWORDS(mh2->patsiz,256,modreader);
  184. of.numpos = mh2->snglen;
  185. if(!AllocPositions(of.numpos)) return 0;
  186. for(t=0;t<of.numpos;t++) {
  187. if(mh2->orders[t]==0xff) break;
  188. of.positions[t] = mh2->orders[t];
  189. }
  190. /* count number of patterns stored in file */
  191. of.numpat = 0;
  192. for(t=0;t<256;t++)
  193. if(mh2->patsiz[t])
  194. if((t+1)>of.numpat) of.numpat=t+1;
  195. of.numtrk = of.numpat*of.numchn;
  196. /* seek across eventual new data */
  197. _mm_fseek(modreader,mh1->headerlen-(869+mh1->stlen),SEEK_CUR);
  198. /* alloc track and pattern structures */
  199. if(!AllocTracks()) return 0;
  200. if(!AllocPatterns()) return 0;
  201. for(t=0;t<of.numpat;t++) {
  202. UBYTE rows=0,tempo;
  203. memset(pat,0,256*16*4*sizeof(FARNOTE));
  204. if(mh2->patsiz[t]) {
  205. rows  = _mm_read_UBYTE(modreader);
  206. tempo = _mm_read_UBYTE(modreader);
  207. crow = pat;
  208. /* file often allocates 64 rows even if there are less in pattern */
  209. if (mh2->patsiz[t]<2+(rows*16*4)) {
  210. _mm_errno = MMERR_LOADING_PATTERN;
  211. return 0;
  212. }
  213. for(u=(mh2->patsiz[t]-2)/4;u;u--,crow++) {
  214. crow->note = _mm_read_UBYTE(modreader);
  215. crow->ins  = _mm_read_UBYTE(modreader);
  216. crow->vol  = _mm_read_UBYTE(modreader);
  217. crow->eff  = _mm_read_UBYTE(modreader);
  218. }
  219. if(_mm_eof(modreader)) {
  220. _mm_errno = MMERR_LOADING_PATTERN;
  221. return 0;
  222. }
  223. crow=pat;
  224. of.pattrows[t] = rows;
  225. for(u=16;u;u--,crow++)
  226. if(!(of.tracks[tracks++]=FAR_ConvertTrack(crow,rows))) {
  227. _mm_errno=MMERR_LOADING_PATTERN;
  228. return 0;
  229. }
  230. } else
  231. tracks+=16;
  232. }
  233. /* read sample map */
  234. if(!_mm_read_UBYTES(smap,8,modreader)) {
  235. _mm_errno = MMERR_LOADING_HEADER;
  236. return 0;
  237. }
  238. /* count number of samples used */
  239. of.numins = 0;
  240. for(t=0;t<64;t++)
  241. if(smap[t>>3]&(1<<(t&7))) of.numins=t+1;
  242. of.numsmp = of.numins;             
  243. /* alloc sample structs */
  244. if(!AllocSamples()) return 0;
  245. q = of.samples;
  246. for(t=0;t<of.numsmp;t++) {
  247. q->speed      = 8363;
  248. q->flags      = SF_SIGNED;
  249. if(smap[t>>3]&(1<<(t&7))) {
  250. _mm_read_SBYTES(s.samplename,32,modreader);
  251. s.length   = _mm_read_I_ULONG(modreader);
  252. s.finetune = _mm_read_UBYTE(modreader);
  253. s.volume   = _mm_read_UBYTE(modreader);
  254. s.reppos   = _mm_read_I_ULONG(modreader);
  255. s.repend   = _mm_read_I_ULONG(modreader);
  256. s.type     = _mm_read_UBYTE(modreader);
  257. s.loop     = _mm_read_UBYTE(modreader);
  258. q->samplename = DupStr(s.samplename,32,1);
  259. q->length     = s.length;
  260. q->loopstart  = s.reppos;
  261. q->loopend    = s.repend;
  262. q->volume     = s.volume<<2;
  263. if(s.type&1) q->flags|=SF_16BITS;
  264. if(s.loop&8) q->flags|=SF_LOOP;
  265. q->seekpos    = _mm_ftell(modreader);
  266. _mm_fseek(modreader,q->length,SEEK_CUR);
  267. } else 
  268. q->samplename = DupStr(NULL,0,0);
  269. q++;
  270. }
  271. return 1;
  272. }
  273. CHAR *FAR_LoadTitle(void)
  274. {
  275. CHAR s[40];
  276. _mm_fseek(modreader,4,SEEK_SET);
  277. if(!_mm_read_UBYTES(s,40,modreader)) return NULL;
  278.    
  279. return(DupStr(s,40,1));
  280. }
  281. /*========== Loader information */
  282. MIKMODAPI MLOADER load_far={
  283. NULL,
  284. "FAR",
  285. "FAR (Farandole Composer)",
  286. FAR_Init,
  287. FAR_Test,
  288. FAR_Load,
  289. FAR_Cleanup,
  290. FAR_LoadTitle
  291. };
  292. /* ex:set ts=4: */