/* MED-stmod.c: SoundTracker 2.x module load/save & ST-song save functions © 1989, 1990 by Teijo Kinnunen */ #include "med.h" #include "medproto.h" extern struct Kappale far song; extern UBYTE samplenum,blocks; extern struct Gadget far gadget3[]; extern struct Soitin *sample[]; extern struct Lohko *lohko[]; extern BPTR fh; static void __regargs ConvertToST(UBYTE,UBYTE *); char *STModLoader(char *name) { struct ST24Mod stsong = { 0 }; UBYTE scntr,*cnvblk; long modlen,samplelen = 0,readlen; if(*name == '\0') return(AskName()); if(!(fh = Open2(name,MODE_OLDFILE))) return(DISKERR); if(AlustaKappale(TRUE)) return(nomem); NollaaVarit(); blocks = 0; Ilmoita("Loading ST/NT-module..."); Seek(fh,0,OFFSET_END); modlen = Seek(fh,0,OFFSET_BEGINNING); if(Read(fh,(void *)&stsong,sizeof(struct ST24Mod)) < sizeof(struct ST24Mod)) return(DISKERR); modlen -= sizeof(struct ST24Mod); /* length of the remaining part */ for(scntr = 0; scntr < 31; scntr++) { samplelen += stsong.sample[scntr].length * 2; } modlen -= samplelen; if(modlen < 0) return("Not a valid module."); if(!(cnvblk = AllocMem(1028,MEMF_PUBLIC))) return(nomem); Ilmoita("Loading blocks..."); while(modlen > 0) { /* Load the song */ if(blocks >= 100) break; /* too many blocks */ if(AllocBlock((UWORD)blocks,4,64)) { FreeMem(cnvblk,1028); return(nomem); } blocks++; TulostaLohkoJaSoitin(); if(modlen > 1024) readlen = 1024; else { readlen = modlen; memset((void *)cnvblk,0,1028); } if(Read(fh,cnvblk+4,readlen) < readlen) { FreeMem(cnvblk,1028); return(DISKERR); } modlen -= readlen; ConvertTo200(cnvblk,(UBYTE *)lohko[blocks-1],TRUE); } FreeMem(cnvblk,1028); song.numblocks = blocks; song.deftempo = 6; song.songlen = stsong.songlen; song.flags |= FLAG_VOLHEX|FLAG_STSLIDE; memcpy((char *)(song.playseq),(char *)(stsong.playseq),128); for(scntr = 0; scntr < 31; scntr++) { strcpy(song.sample[scntr].sname,stsong.sample[scntr].name); song.sample[scntr].svol = stsong.sample[scntr].volume; song.sample[scntr].rep = stsong.sample[scntr].repeat; song.sample[scntr].replen = stsong.sample[scntr].replen; } StripPaths(); PaivitaNaytto(TRUE); DispVolAndSldType(); SetTempo(6); Ilmoita("Loading samples..."); samplenum = 0; PaivitaSoittimennimi(); for(scntr = 0; scntr < 31; scntr++) { samplelen = stsong.sample[scntr].length * 2; if(samplelen) { if(NewInstrument(samplelen,samplenum)) return(nomem); if(Read(fh,(char *)(sample[samplenum]) + sizeof(struct Soitin),samplelen) < samplelen) return(DISKERR); } SeurSoitin(); } samplenum = 0; PaivitaSoittimennimi(); Close(fh); fh = 0L; Ilmoita("Module loaded."); return(NOERR); } static void __regargs ConvertToST(UBYTE block,UBYTE *bgto) { extern UWORD periodit[]; register UWORD cnt,cnt2,per; register UBYTE instrG_V,nnum,*to,*from; memset(bgto,0,1024); for(cnt = 0; cnt < 64; cnt++) { to = bgto + 16 * cnt; from = &lohko[block]->music[cnt * lohko[block]->numtracks * 3]; if(cnt > lohko[block]->lines) { *(to-1) = 0; *(to-2) &= 0xf0; *(to-2) |= 0x0d; /* insert pattern break */ break; } for(cnt2 = 0; cnt2 < 4; cnt2++) { nnum = *from++; instrG_V = 0; if(nnum & 0x80) instrG_V = 1; if(nnum & 0x40) instrG_V += 2; if(!(nnum &= 0x3f)) per = 0; else per = periodit[nnum - 1]; if(instrG_V) per |= (instrG_V << 12); *to++ = (UBYTE)(per >> 8); *to++ = (UBYTE)(per & 0xff); nnum = *from++; /* Reuse the register variables */ instrG_V = *from++; *to = nnum & 0xf0; /* some command conversions: */ switch(nnum & 0x0f) { /* vv F00 -> D00 */ case 0xF: switch(instrG_V) { case 0: *to |= 0xD; break; case 0xF8: *to |= 0xE; instrG_V = 1; break; case 0xF9: *to |= 0xE; instrG_V = 0; break; case 0xFD: *to |= 0x3; instrG_V = 0xff; break; case 0xFF: *to |= 0xC; instrG_V = 0; break; default: *to |= nnum; } break; case 0xD: *to |= 0x0A; break; /* Dxx->Axx */ default: *to |= nnum; } to++; *to++ = instrG_V; } } } char *SaveSTMod(char *name) { UBYTE oldexists = 0,scnt,*convblk,lastused = 0; ULONG null = NULL; struct ST24Mod mod; if(*name == '\0') return(AskName()); if(IsHere(name)) { oldexists = 1; Ilmoita(fileex); if(!Continue()) return(notsaved); } if(!(fh = Open2(name,MODE_NEWFILE))) return(DISKERR); Ilmoita("Saving ST/NT-module..."); memset((void *)(&mod),0,sizeof(mod)); strcpy(mod.songname,name); for(scnt = 0; scnt < 32; scnt++) { strcpy(mod.sample[scnt].name,song.sample[scnt].sname); mod.sample[scnt].length = sample[scnt]->length / 2; if(sample[scnt]) mod.sample[scnt].volume = song.sample[scnt].svol; mod.sample[scnt].repeat = song.sample[scnt].rep; if(song.sample[scnt].replen < 2) mod.sample[scnt].replen = 1; else mod.sample[scnt].replen = song.sample[scnt].replen; } mod.songlen = song.songlen; memcpy(mod.playseq,song.playseq,128); mod.mk = ((long)'M')<<24|((long)'.')<<16|((long)'K')<<8|'.'; mod.I_dont_know_what_this_byte_is = 0x78; /* that's it!! */ if(Write(fh,(char *)(&mod),sizeof(mod)) < sizeof(mod)) return(DISKERR); convblk = AllocMem(1024,MEMF_PUBLIC); if(!convblk) return(nomem); Ilmoita("Saving blocks..."); for(scnt = 0; scnt < song.songlen; scnt++) /* find last used block */ if(song.playseq[scnt] > lastused) lastused = song.playseq[scnt]; for(scnt = 0; scnt <= lastused; scnt++) { ConvertToST(scnt,convblk); if(Write(fh,convblk,1024) != 1024) { FreeMem(convblk,1024); return(DISKERR); } } FreeMem(convblk,1024); Ilmoita("Saving samples..."); for(scnt = 0; scnt < 32; scnt++) { if(sample[scnt] && sample[scnt]->length > 4) { if(Write(fh,(char *)(&null),4) != 4) return(DISKERR); if(Write(fh,(char *)sample[scnt] + sizeof(struct Soitin) + 4,sample[scnt]->length - 4) != sample[scnt]->length - 4) return(DISKERR); } } if(fh) Close(fh); fh = 0L; if(!oldexists) InsertSavedFile(name); Ilmoita("Module saved."); return(NOERR); }