home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "mloader.h"
- #include "munitrk.h"
-
-
-
- typedef struct DSMNOTE{
- UBYTE note,ins,vol,cmd,inf;
- } DSMNOTE;
-
- typedef struct DSMINST{
- UBYTE filename[13];
- UWORD flags;
- UBYTE volume;
- ULONG length;
- ULONG loopstart;
- ULONG loopend;
- ULONG reserved1;
- UWORD c2spd;
- UWORD reserved2;
- UBYTE samplename[28];
- } DSMINST;
-
-
-
- typedef struct DSMSONG{
- char songname[28];
- UWORD reserved1;
- UWORD flags;
- ULONG reserved2;
- UWORD numord;
- UWORD numsmp;
- UWORD numpat;
- UWORD numtrk;
- UBYTE globalvol;
- UBYTE mastervol;
- UBYTE speed;
- UBYTE bpm;
- UBYTE panpos[16];
- UBYTE orders[128];
- } DSMSONG;
-
-
-
- #define MOTLONG(a,b,c,d) (((ULONG)d<<24)|((ULONG)c<<16)|((ULONG)b<<8)|a)
- #define SONGID MOTLONG('S','O','N','G')
- #define INSTID MOTLONG('I','N','S','T')
- #define PATTID MOTLONG('P','A','T','T')
-
-
- ULONG blockid;
- ULONG blockln;
- ULONG blocklp;
-
- static DSMSONG *mh;
- DSMNOTE *dsmbuf;
-
- char DSM_Version[]="DSIK DSM-format";
-
-
-
- BOOL DSM_Test(void)
- {
- char id[12];
- rewind(modfp);
-
- if(!fread(id,12,1,modfp)) return 0;
-
- if(!memcmp(id,"RIFF",4) &&
- !memcmp(&id[8],"DSMF",4)) return 1;
- return 0;
- }
-
-
-
- BOOL DSM_Init(void)
- {
- dsmbuf=NULL;
- mh=NULL;
-
- if(!(dsmbuf=(DSMNOTE *)MyMalloc(16*64*sizeof(DSMNOTE)))) return 0;
- if(!(mh=(DSMSONG *)MyCalloc(1,sizeof(DSMSONG)))) return 0;
- return 1;
- }
-
-
-
- void DSM_Cleanup(void)
- {
- if(dsmbuf!=NULL) free(dsmbuf);
- if(mh!=NULL) free(mh);
- }
-
-
-
- BOOL GetBlockHeader(void)
- {
- /* make sure we're at the right position for reading the
- next riff block, no matter how many bytes read */
-
- fseek(modfp,blocklp+blockln,SEEK_SET);
-
- while(1){
-
- if(!fread(&blockid,sizeof(ULONG),1,modfp) ||
- !fread(&blockln,sizeof(ULONG),1,modfp)){
- myerr=ERROR_LOADING_HEADER;
- return 0;
- }
-
- if(blockid!=SONGID &&
- blockid!=INSTID &&
- blockid!=PATTID ){
-
- printf("Skipping unknown block type %4.4s\n",&blockid);
-
- fseek(modfp,blockln,SEEK_CUR);
- }
- else break;
- }
-
- blocklp=ftell(modfp);
- return 1;
- }
-
-
-
- BOOL DSM_ReadPattern(void)
- {
- int row=0,flag;
- DSMNOTE *n;
-
- // clear pattern data
-
- memset(dsmbuf,255,16*64*sizeof(DSMNOTE));
-
- fgetc(modfp);
- fgetc(modfp);
-
- while(row<64){
-
- flag=fgetc(modfp);
-
- if(flag==EOF){
- myerr=ERROR_LOADING_PATTERN;
- return 0;
- }
-
- if(flag){
-
- n=&dsmbuf[((flag&0xf)*64)+row];
- if(flag&0x80) n->note=fgetc(modfp);
- if(flag&0x40) n->ins=fgetc(modfp);
- if(flag&0x20) n->vol=fgetc(modfp);
- if(flag&0x10){
- n->cmd=fgetc(modfp);
- n->inf=fgetc(modfp);
- }
- }
- else row++;
- }
- return 1;
- }
-
-
-
- UBYTE *DSM_ConvertTrack(DSMNOTE *tr)
- {
- int t;
-
- UBYTE note,ins,vol,cmd,inf;
-
- UniReset();
- for(t=0;t<64;t++){
-
- note=tr[t].note;
- ins=tr[t].ins;
- vol=tr[t].vol;
- cmd=tr[t].cmd;
- inf=tr[t].inf;
-
- if(ins!=0 && ins!=255){
- UniInstrument(ins-1);
- }
-
- if(note!=255){
- UniNote(note-1); // <- normal note
- }
-
-
- if(vol<65){
- UniPTEffect(0xc,vol);
- }
-
- if(cmd!=255){
-
- if(cmd==0x8){
- if(inf<=0x80){
- inf=(inf<0x80) ? inf<<1 : 255;
- UniPTEffect(cmd,inf);
- }
- }
- else if(cmd==0xb){
- if(inf<=0x7f) UniPTEffect(cmd,inf);
- }
- else UniPTEffect(cmd,inf);
-
- }
-
- UniNewline();
- }
- return UniDup();
- }
-
-
-
- BOOL DSM_Load(void)
- {
- int t;
- DSMINST s;
- INSTRUMENT *d;
- SAMPLE *q;
-
- int cursmp=0,curpat=0,track=0;
-
- blocklp=0;
- blockln=12;
-
- if(!GetBlockHeader()) return 0;
-
- if(blockid!=SONGID){
- myerr=ERROR_LOADING_HEADER;
- return 0;
- }
-
- if(!fread(mh,sizeof(DSMSONG),1,modfp)){
- myerr=ERROR_LOADING_HEADER;
- return 0;
- }
-
- /* set module variables */
-
- of.initspeed=mh->speed;
- of.inittempo=mh->bpm;
- of.modtype=strdup(DSM_Version);
- of.numchn=mh->numtrk;
- of.numpat=mh->numpat;
- of.numtrk=of.numchn*of.numpat;
-
- of.songname=DupStr(mh->songname,28); // make a cstr of songname
-
- for(t=0;t<16;t++){
- of.panning[t]=mh->panpos[t]<0x80 ? (mh->panpos[t]<<1) : 255;
- }
-
- of.numpos=0;
- for(t=0;t<mh->numord;t++){
- of.positions[of.numpos]=mh->orders[t];
- if(mh->orders[t]<254) of.numpos++;
- }
-
- of.numins=mh->numsmp;
-
- if(!AllocInstruments()) return 0;
- if(!AllocTracks()) return 0;
- if(!AllocPatterns()) return 0;
-
- while(cursmp<of.numins || curpat<of.numpat){
-
- if(!GetBlockHeader()) return 0;
-
- if(blockid==INSTID && cursmp<of.numins){
-
- d=&of.instruments[cursmp];
-
- d->numsmp=1;
- if(!AllocSamples(d)) return 0;
- q=d->samples;
-
- // try to read sample info
-
- if(!fread(&s,sizeof(DSMINST),1,modfp)){
- myerr=ERROR_LOADING_SAMPLEINFO;
- return 0;
- }
-
- d->insname=DupStr(s.samplename,28);
- q->seekpos=ftell(modfp);
- q->c2spd=s.c2spd;
- q->length=s.length;
- q->loopstart=s.loopstart;
- q->loopend=s.loopend;
- q->volume=s.volume;
- q->flags=0;
-
- if(s.flags&1) q->flags|=SF_LOOP;
- if(s.flags&2) q->flags|=SF_SIGNED;
-
- cursmp++;
- }
- else if(blockid==PATTID && curpat<of.numpat){
-
- DSM_ReadPattern();
-
- for(t=0;t<of.numchn;t++){
- if(!(of.tracks[track++]=DSM_ConvertTrack(&dsmbuf[t*64]))) return 0;
- }
-
- curpat++;
- }
- }
-
- return 1;
- }
-
-
-
-
- LOADER dsmload={
- NULL,
- "DSM",
- "DSM loader v0.1",
- DSM_Init,
- DSM_Test,
- DSM_Load,
- DSM_Cleanup
- };
-