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

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. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY;without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library;if not,write to the Free Software
  14. Foundation,Inc.,59 Temple Place - Suite 330,Boston,MA
  15. 02111-1307,USA.
  16. */
  17. /*==============================================================================
  18.   $Id: load_gdm.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $
  19.   General DigiMusic (GDM) module loader
  20. ==============================================================================*/
  21. /*
  22. Written by Kev Vance<kvance@zeux.org>
  23. based on the file format description written by 'MenTaLguY'
  24.                                                         <mental@kludge.org>
  25. */
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #ifdef HAVE_UNISTD_H
  30. #include <unistd.h>
  31. #endif
  32. #include <stdio.h>
  33. #ifdef HAVE_MEMORY_H
  34. #include <memory.h>
  35. #endif
  36. #include <string.h>
  37. #include "mikmod_internals.h"
  38. #ifdef SUNOS
  39. extern int fprintf(FILE *, const char *, ...);
  40. #endif
  41. typedef struct GDMNOTE {
  42. UBYTE note;
  43. UBYTE samp;
  44. struct {
  45. UBYTE effect;
  46. UBYTE param;
  47. } effect[4];
  48. } GDMNOTE;
  49. typedef GDMNOTE GDMTRACK[64];
  50. typedef struct GDMHEADER {
  51. CHAR  id1[4];
  52. CHAR  songname[32];
  53. CHAR  author[32];
  54. CHAR  eofmarker[3];
  55. CHAR  id2[4];
  56. UBYTE majorver;
  57. UBYTE minorver;
  58. UWORD trackerid;
  59. UBYTE t_majorver;
  60. UBYTE t_minorver;
  61. UBYTE pantable[32];
  62. UBYTE mastervol;
  63. UBYTE mastertempo;
  64. UBYTE masterbpm;
  65. UWORD flags;
  66. ULONG orderloc;
  67. UBYTE ordernum;
  68. ULONG patternloc;
  69. UBYTE patternnum;
  70. ULONG samhead;
  71. ULONG samdata;
  72. UBYTE samnum;
  73. ULONG messageloc;
  74. ULONG messagelen;
  75. ULONG scrollyloc;
  76. UWORD scrollylen;
  77. ULONG graphicloc;
  78. UWORD graphiclen;
  79. } GDMHEADER;
  80. typedef struct GDMSAMPLE {
  81. CHAR  sampname[32];
  82. CHAR  filename[13];
  83. UBYTE ems;
  84. ULONG length;
  85. ULONG loopbeg;
  86. ULONG loopend;
  87. UBYTE flags;
  88. UWORD c4spd;
  89. UBYTE vol;
  90. UBYTE pan;
  91. } GDMSAMPLE;
  92. static GDMHEADER *mh=NULL; /* pointer to GDM header */
  93. static GDMNOTE *gdmbuf=NULL; /* pointer to a complete GDM pattern */
  94. CHAR GDM_Version[]="General DigiMusic 1.xx";
  95. BOOL GDM_Test(void)
  96. {
  97. /* test for gdm magic numbers */
  98. UBYTE id[4];
  99. _mm_fseek(modreader,0x00,SEEK_SET);
  100. if (!_mm_read_UBYTES(id,4,modreader))
  101. return 0;
  102. if (!memcmp(id,"GDMxfe",4)) {
  103. _mm_fseek(modreader,71,SEEK_SET);
  104. if (!_mm_read_UBYTES(id,4,modreader))
  105. return 0;
  106. if (!memcmp(id,"GMFS",4))
  107. return 1;
  108. }
  109. return 0;
  110. }
  111. BOOL GDM_Init(void)
  112. {
  113. if (!(gdmbuf=(GDMNOTE*)_mm_malloc(32*64*sizeof(GDMNOTE)))) return 0;
  114. if (!(mh=(GDMHEADER*)_mm_malloc(sizeof(GDMHEADER)))) return 0;
  115. return 1;
  116. }
  117. void GDM_Cleanup(void)
  118. {
  119. _mm_free(mh);
  120. _mm_free(gdmbuf);
  121. }
  122. BOOL GDM_ReadPattern(void)
  123. {
  124. int pos,flag,ch,i,maxch;
  125. GDMNOTE n;
  126. UWORD length,x=0;
  127. /* get pattern length */
  128. length=_mm_read_I_UWORD(modreader)-2;
  129. /* clear pattern data */
  130. memset(gdmbuf,255,32*64*sizeof(GDMNOTE));
  131. pos=0;
  132. maxch=0;
  133. while (x<length) {
  134. memset(&n,255,sizeof(GDMNOTE));
  135. flag=_mm_read_UBYTE(modreader);
  136. x++;
  137. if (_mm_eof(modreader)) {
  138. _mm_errno=MMERR_LOADING_PATTERN;
  139. return 0;
  140. }
  141. ch=flag&31;
  142. if (ch>maxch) maxch=ch;
  143. if (!flag) {
  144. pos++;
  145. continue;
  146. }
  147. if (flag&0x60) {
  148. if (flag&0x20) {
  149. /* new note */
  150. n.note=_mm_read_UBYTE(modreader)&127;
  151. n.samp=_mm_read_UBYTE(modreader);
  152. x +=2;
  153. }
  154. if (flag&0x40) {
  155. do {
  156. /* effect channel set */
  157. i=_mm_read_UBYTE(modreader);
  158. n.effect[i>>6].effect=i&31;
  159. n.effect[i>>6].param=_mm_read_UBYTE(modreader);
  160. x +=2;
  161. } while (i&32);
  162. }
  163. memcpy(gdmbuf+(64U*ch)+pos,&n,sizeof(GDMNOTE));
  164. }
  165. }
  166. return 1;
  167. }
  168. UBYTE *GDM_ConvertTrack(GDMNOTE*tr)
  169. {
  170. int t,i=0;
  171. UBYTE note,ins,inf;
  172. UniReset();
  173. for (t=0;t<64;t++) {
  174. note=tr[t].note;
  175. ins=tr[t].samp;
  176. if ((ins)&&(ins!=255))
  177. UniInstrument(ins-1);
  178. if (note!=255) {
  179. UniNote(((note>>4)*OCTAVE)+(note&0xf)-1);
  180. }
  181. for (i=0;i<4;i++) {
  182. inf = tr[t].effect[i].param;
  183. switch (tr[t].effect[i].effect) {
  184. case 1: /* toneslide up */
  185. UniEffect(UNI_S3MEFFECTF,inf);
  186. break;
  187. case 2: /* toneslide down */
  188. UniEffect(UNI_S3MEFFECTE,inf);
  189. break;
  190. case 3: /* glissando to note */
  191. UniEffect(UNI_ITEFFECTG,inf);
  192. break;
  193. case 4: /* vibrato */
  194. UniEffect(UNI_ITEFFECTH,inf);
  195. break;
  196. case 5: /* portamento+volslide */
  197. UniEffect(UNI_ITEFFECTG,0);
  198. UniEffect(UNI_S3MEFFECTD,inf);
  199. break;
  200. case 6: /* vibrato+volslide */
  201. UniEffect(UNI_ITEFFECTH,0);
  202. UniEffect(UNI_S3MEFFECTD,inf);
  203. break;
  204. case 7: /* tremolo */
  205. UniEffect(UNI_S3MEFFECTR,inf);
  206. break;
  207. case 8: /* tremor */
  208. UniEffect(UNI_S3MEFFECTI,inf);
  209. break;
  210. case 9: /* offset */
  211. UniPTEffect(0x09,inf);
  212. break;
  213. case 0x0a: /* volslide */
  214. UniEffect(UNI_S3MEFFECTD,inf);
  215. break;
  216. case 0x0b: /* jump to order */
  217. UniPTEffect(0x0b,inf);
  218. break;
  219. case 0x0c: /* volume set */
  220. UniPTEffect(0x0c,inf);
  221. break;
  222. case 0x0d: /* pattern break */
  223. UniPTEffect(0x0d,inf);
  224. break;
  225. case 0x0e: /* extended */
  226. switch (inf&0xf0) {
  227. case 0x10: /* fine portamento up */
  228. UniEffect(UNI_S3MEFFECTF, 0x0f|((inf<<4)&0x0f));
  229. break;
  230. case 0x20: /* fine portamento down */
  231. UniEffect(UNI_S3MEFFECTE, 0xf0|(inf&0x0f));
  232. break;
  233. case 0x30: /* glissando control */
  234. UniEffect(SS_GLISSANDO, inf&0x0f);
  235. break;
  236. case 0x40: /* vibrato waveform */
  237. UniEffect(SS_VIBWAVE, inf&0x0f);
  238. break;
  239. case 0x50: /* set c4spd */
  240. UniEffect(SS_FINETUNE, inf&0x0f);
  241. break;
  242. case 0x60: /* loop fun */
  243. UniEffect(UNI_ITEFFECTS0, (inf&0x0f)|0xb0);
  244. break;
  245. case 0x70: /* tremolo waveform */
  246. UniEffect(SS_TREMWAVE, inf&0x0f);
  247. break;
  248. case 0x80: /* extra fine porta up */
  249. UniEffect(UNI_S3MEFFECTF, 0x0e|((inf<<4)&0x0f));
  250. break;
  251. case 0x90: /* extra fine porta down */
  252. UniEffect(UNI_S3MEFFECTE, 0xe0|(inf&0x0f));
  253. break;
  254. case 0xa0: /* fine volslide up */
  255. UniEffect(UNI_S3MEFFECTD, 0x0f|((inf<<4)&0x0f));
  256. break;
  257. case 0xb0: /* fine volslide down */
  258. UniEffect(UNI_S3MEFFECTE, 0xf0|(inf&0x0f));
  259. break;
  260. case 0xc0: /* note cut */
  261. case 0xd0: /* note delay */
  262. case 0xe0: /* extend row */
  263. UniPTEffect(0xe,inf);
  264. break;
  265. }
  266. break;
  267. case 0x0f: /* set tempo */
  268. UniEffect(UNI_S3MEFFECTA,inf);
  269. break;
  270. case 0x10: /* arpeggio */
  271. UniPTEffect(0x0,inf);
  272. break;
  273. case 0x12: /* retrigger */
  274. UniEffect(UNI_S3MEFFECTQ,inf);
  275. break;
  276. case 0x13: /* set global volume */
  277. UniEffect(UNI_XMEFFECTG,inf<<1);
  278. break;
  279. case 0x14: /* fine vibrato */
  280. UniEffect(UNI_ITEFFECTU,inf);
  281. break;
  282. case 0x1e: /* special */
  283. switch (inf&0xf0) {
  284. case 8: /* set pan position */
  285. if (inf >=128)
  286. UniPTEffect(0x08,255);
  287. else
  288. UniPTEffect(0x08,inf<<1);
  289. break;
  290. }
  291. break;
  292. case 0x1f: /* set bpm */
  293. if (inf >=0x20)
  294. UniEffect(UNI_S3MEFFECTT,inf);
  295. break;
  296. }
  297. }
  298. UniNewline();
  299. }
  300. return UniDup();
  301. }
  302. BOOL GDM_Load(BOOL curious)
  303. {
  304. int i,x,u,track;
  305. SAMPLE *q;
  306. GDMSAMPLE s;
  307. ULONG position;
  308. /* read header */
  309. _mm_read_string(mh->id1,4,modreader);
  310. _mm_read_string(mh->songname,32,modreader);
  311. _mm_read_string(mh->author,32,modreader);
  312. _mm_read_string(mh->eofmarker,3,modreader);
  313. _mm_read_string(mh->id2,4,modreader);
  314. mh->majorver=_mm_read_UBYTE(modreader);
  315. mh->minorver=_mm_read_UBYTE(modreader);
  316. mh->trackerid=_mm_read_I_UWORD(modreader);
  317. mh->t_majorver=_mm_read_UBYTE(modreader);
  318. mh->t_minorver=_mm_read_UBYTE(modreader);
  319. _mm_read_UBYTES(mh->pantable,32,modreader);
  320. mh->mastervol=_mm_read_UBYTE(modreader);
  321. mh->mastertempo=_mm_read_UBYTE(modreader);
  322. mh->masterbpm=_mm_read_UBYTE(modreader);
  323. mh->flags=_mm_read_I_UWORD(modreader);
  324. mh->orderloc=_mm_read_I_ULONG(modreader);
  325. mh->ordernum=_mm_read_UBYTE(modreader);
  326. mh->patternloc=_mm_read_I_ULONG(modreader);
  327. mh->patternnum=_mm_read_UBYTE(modreader);
  328. mh->samhead=_mm_read_I_ULONG(modreader);
  329. mh->samdata=_mm_read_I_ULONG(modreader);
  330. mh->samnum=_mm_read_UBYTE(modreader);
  331. mh->messageloc=_mm_read_I_ULONG(modreader);
  332. mh->messagelen=_mm_read_I_ULONG(modreader);
  333. mh->scrollyloc=_mm_read_I_ULONG(modreader);
  334. mh->scrollylen=_mm_read_I_UWORD(modreader);
  335. mh->graphicloc=_mm_read_I_ULONG(modreader);
  336. mh->graphiclen=_mm_read_I_UWORD(modreader);
  337. /* have we ended abruptly? */
  338. if (_mm_eof(modreader)) {
  339. _mm_errno=MMERR_LOADING_HEADER;
  340. return 0;
  341. }
  342. /* any orders? */
  343. if(mh->ordernum==255) {
  344. _mm_errno=MMERR_LOADING_PATTERN;
  345. return 0;
  346. }
  347. /* now we fill */
  348. of.modtype=strdup(GDM_Version);
  349. of.modtype[18]=mh->majorver+'0';
  350. of.modtype[20]=mh->minorver/10+'0';
  351. of.modtype[21]=mh->minorver%10+'0';
  352. of.songname=DupStr(mh->songname,32,0);
  353. of.numpat=mh->patternnum+1;
  354. of.reppos=0;
  355. of.numins=of.numsmp=mh->samnum+1;
  356. of.initspeed=mh->mastertempo;
  357. of.inittempo=mh->masterbpm;
  358. of.initvolume=mh->mastervol<<1;
  359. of.flags|=UF_S3MSLIDES | UF_PANNING;
  360. /* XXX whenever possible, we should try to determine the original format.
  361.    Here we assume it was S3M-style wrt bpmlimit... */
  362. of.bpmlimit = 32;
  363. /* read the order data */
  364. if (!AllocPositions(mh->ordernum+1)) {
  365. _mm_errno=MMERR_OUT_OF_MEMORY;
  366. return 0;
  367. }
  368. _mm_fseek(modreader,mh->orderloc,SEEK_SET);
  369. for (i=0;i<mh->ordernum+1;i++)
  370. of.positions[i]=_mm_read_UBYTE(modreader);
  371. of.numpos=0;
  372. for (i=0;i<mh->ordernum+1;i++) {
  373. int order=of.positions[i];
  374. if(order==255) order=LAST_PATTERN;
  375. of.positions[of.numpos]=order;
  376. if (of.positions[i]<254) of.numpos++;
  377. }
  378. /* have we ended abruptly yet? */
  379. if (_mm_eof(modreader)) {
  380. _mm_errno=MMERR_LOADING_HEADER;
  381. return 0;
  382. }
  383. /* time to load the samples */
  384. if (!AllocSamples()) {
  385. _mm_errno=MMERR_OUT_OF_MEMORY;
  386. return 0;
  387. }
  388. q=of.samples;
  389. position=mh->samdata;
  390. /* seek to instrument position */
  391. _mm_fseek(modreader,mh->samhead,SEEK_SET);
  392. for (i=0;i<of.numins;i++) {
  393. /* load sample info */
  394. _mm_read_UBYTES(s.sampname,32,modreader);
  395. _mm_read_UBYTES(s.filename,12,modreader);
  396. s.ems=_mm_read_UBYTE(modreader);
  397. s.length=_mm_read_I_ULONG(modreader);
  398. s.loopbeg=_mm_read_I_ULONG(modreader);
  399. s.loopend=_mm_read_I_ULONG(modreader);
  400. s.flags=_mm_read_UBYTE(modreader);
  401. s.c4spd=_mm_read_I_UWORD(modreader);
  402. s.vol=_mm_read_UBYTE(modreader);
  403. s.pan=_mm_read_UBYTE(modreader);
  404. if (_mm_eof(modreader)) {
  405. _mm_errno=MMERR_LOADING_SAMPLEINFO;
  406. return 0;
  407. }
  408. q->samplename=DupStr(s.sampname,32,0);
  409. q->speed=s.c4spd;
  410. q->length=s.length;
  411. q->loopstart=s.loopbeg;
  412. q->loopend=s.loopend;
  413. q->volume=s.vol;
  414. q->panning=s.pan;
  415. q->seekpos=position;
  416. position +=s.length;
  417. if (s.flags&1)
  418. q->flags |=SF_LOOP;
  419. if (s.flags&2)
  420. q->flags |=SF_16BITS;
  421. if (s.flags&16)
  422. q->flags |=SF_STEREO;
  423. q++;
  424. }
  425. /* set the panning */
  426. for (i=x=0;i<32;i++) {
  427. of.panning[i]=mh->pantable[i];
  428. if (!of.panning[i])
  429. of.panning[i]=PAN_LEFT;
  430. else if (of.panning[i]==8)
  431. of.panning[i]=PAN_CENTER;
  432. else if (of.panning[i]==15)
  433. of.panning[i]=PAN_RIGHT;
  434. else if (of.panning[i]==16)
  435. of.panning[i]=PAN_SURROUND;
  436. else if (of.panning[i]==255)
  437. of.panning[i]=128;
  438. else
  439. of.panning[i]<<=3;
  440. if (mh->pantable[i]!=255)
  441. x=i;
  442. }
  443. of.numchn=x+1;
  444. if (of.numchn<1)
  445. of.numchn=1; /* for broken counts */
  446. /* load the pattern info */
  447. of.numtrk=of.numpat*of.numchn;
  448. /* jump to patterns */
  449. _mm_fseek(modreader,mh->patternloc,SEEK_SET);
  450. if (!AllocTracks()) {
  451. _mm_errno=MMERR_OUT_OF_MEMORY;
  452. return 0;
  453. }
  454. if (!AllocPatterns()) {
  455. _mm_errno=MMERR_OUT_OF_MEMORY;
  456. return 0;
  457. }
  458. for (i=track=0;i<of.numpat;i++) {
  459. if (!GDM_ReadPattern()) {
  460. _mm_errno=MMERR_LOADING_PATTERN;
  461. return 0;
  462. }
  463. for (u=0;u<of.numchn;u++,track++) {
  464. of.tracks[track]=GDM_ConvertTrack(&gdmbuf[u<<6]);
  465. if (!of.tracks[track]) {
  466. _mm_errno=MMERR_LOADING_TRACK;
  467. return 0;
  468. }
  469. }
  470. }
  471. return 1;
  472. }
  473. CHAR *GDM_LoadTitle(void)
  474. {
  475. CHAR s[32];
  476. _mm_fseek(modreader,4,SEEK_SET);
  477. if (!_mm_read_UBYTES(s,32,modreader)) return NULL;
  478. return DupStr(s,28,0);
  479. }
  480. MIKMODAPI MLOADER load_gdm=
  481. {
  482. NULL,
  483. "GDM",
  484. "GDM (General DigiMusic)",
  485. GDM_Init,
  486. GDM_Test,
  487. GDM_Load,
  488. GDM_Cleanup,
  489. GDM_LoadTitle
  490. };
  491. /* ex:set ts=4: */