/* MED - music editor © 1989, 1990 by Teijo Kinnunen */
/* med-tied.c: some file handling... ("tied" means "tiedosto" = "file") */
#include <dos.h>
#include "med.h"
#include "medproto.h"

#define ID(a,b,c,d) ((long)a << 24|(long)b << 16|(long)c << 8|d)
extern struct Kappale far song;
typedef LONG Fixed;
typedef LONG IFFP;
typedef IFFP ClientProc();
typedef struct _ClientFrame {
	ClientProc *getList,*getProp,*getForm,*getCat; } ClientFrame;
typedef struct { ULONG oneShotHiSamples, repeatHiSamples, samplesPerHiCycle;
	UWORD samplesPerSec; UBYTE ctOctave, sCompression; Fixed volume; }
	Voice8Header;
typedef struct {
   ClientFrame clientFrame;
   UBYTE foundVHDR;
   UBYTE pad1;
   Voice8Header sampHdr;
   } SVXFrame;
extern SVXFrame smusFrame;
extern BYTE *buf;
extern int szBuf;
extern UBYTE samplenum,blocks,lastmidic,lastmidip;
extern UWORD lastrep,lastreplen;
extern struct Screen *screen;
extern struct Window *window;
extern struct ViewPort *vp;
extern struct Lohko far *lohko[];
extern char kappaleennimi[];	/* the name of the song */
static union { struct SoundTrackerKappale oldst; struct Kappale111 oldsng; } far old;
extern struct Gadget far gadget3[],far gadget7[];
extern struct Soitin *sample[];
IFFP __stdargs ReadSample(LONG);
static BOOL loadingsong = FALSE;
static BOOL __regargs LoadOldBlocks(BOOL);
static char * __regargs LoadST(void);
static char * __regargs Load112(void);
static char * __regargs LoadIFFSample(void);
static void Change3to5(void);
BPTR fh = NULL;
static char *prevsn;

BOOL NewInstrument(ULONG size,UBYTE num)
{
	if(sample[num]) {
		FreeMem((void *)sample[num],sample[num]->length +
		sizeof(struct Soitin));
		sample[num] = NULL;
	}
	sample[num] = AllocMem(size + sizeof(struct Soitin),
				MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
	if(!sample[num]) return(TRUE);
	sample[num]->length = size;
	return(FALSE);
}

char *LoadInstrument(char *name,BOOL src)
{
	ULONG length;
	char latausnimi[100],tunnus[5];
	struct SongSample *ss = &song.sample[samplenum];
	if(*name == '\0') return(AskName());
	if(src) ConstructDirName(ss->sname,latausnimi);
	else strcpy(latausnimi,name);
	if(!loadingsong) {
		if(!ss->svol) ss->svol = 64;
		ss->rep = lastrep;
		ss->replen = lastreplen;
		if(lastmidic) {
			ss->midich = lastmidic;
			ss->midipreset = lastmidip;
			Ilmoita("OK.");
			return(NOERR);
		}
	}
	if(gadget7[20].GadgetID & 0x1000) stccpy(ss->sname,latausnimi,39);
	if(!(fh = Open2(latausnimi,MODE_OLDFILE))) return(DISKERR);
	if(Read(fh,tunnus,4) != 4) return("Too short.");
	tunnus[4] = '\0';
	if(!strcmp(tunnus,"FORM")) {
		char *res = LoadIFFSample();
		if(!src) PaivitaSoittimennimi();
		return(res);
	}
	Ilmoita("Loading raw sample...");
	Seek(fh,0,OFFSET_END);
	length = Seek(fh,0,OFFSET_BEGINNING);
	if(NewInstrument(length,samplenum)) return(nomem);
	if(Read(fh,(char *)(sample[samplenum]) + sizeof(struct Soitin),
		length) != length) {
		FreeMem((void *)sample[samplenum],
    			sample[samplenum]->length + sizeof(struct Soitin));
		sample[samplenum] = NULL;
		return(DISKERR);
	}
	if(fh) Close(fh);
	fh = NULL;
	if(!src) PaivitaSoittimennimi();
	return(NOERR);
}

char *LoadSong(char *nimi)
{
	UWORD scnt,mod = FALSE;
	char *loadres;
	ULONG id;
	if(*nimi == '\0') return(AskName());
	if(!(fh = Open2(nimi,MODE_OLDFILE))) return(DISKERR);
	if(Read(fh,(void *)&id,4) != 4) return("Not a song!");
	if(id == ID('P','A','C','K')) return("I don't load packed ST/NT-songs.");
	if((id & 0xffffff00) == ID('M','E','D',0) && (id & 0xff) > 4)
		return("You need a newer MED.");
	Seek(fh,0,OFFSET_BEGINNING);
	if(prevsn = (char *)AllocMem(63 * 40,MEMF_PUBLIC|MEMF_CLEAR)) {
		for(scnt = 0; scnt < 63; scnt++)
			strcpy(prevsn + scnt * 40,song.sample[scnt].sname);
	}
	if(AlustaKappale(FALSE)) return(nomem);
	NollaaVarit();
	blocks = 0;
	if(id == ID('M','E','D',2)) {
		if(loadres = Load112()) return(loadres);
		Change3to5();
	} else if(id == ID('M','E','D',3)) {
		if(loadres = Load200Song()) return(loadres);
		LoadRGB4(vp,song.rgb,4);	
		Change3to5();
	} else if(id == ID('M','E','D',4)) {
		if(loadres = Load210Song()) return(loadres);
		LoadRGB4(vp,song.rgb,4);
	} else if(id == ID('M','M','D','0')) {
		if(loadres = LoadMod()) return(loadres);
		mod = TRUE;
	} else {
		if(id == ID('S','O','N','G')) Ilmoita("Loading SoundFX-song...");
		else Ilmoita("Loading SoundTracker-song...");
		if(loadres = LoadST()) return(loadres);
	}
	AsetaSuodatin();
	DispVolAndSldType();
	UpdateJumpGadgets();
	PaivitaNaytto(TRUE);
	samplenum = 0;
	SetTempo(song.deftempo);
	PaivitaSoittimennimi();
	loadingsong = TRUE; /* this flag is meaningful only when loading */
	StripPaths();		/* samples */
	if(song.flags & FLAG_INSTRSATT) {
		loadres = LoadAttachedInstrs();
		Ilmoita("Song + samples loaded.");
	}
	if(fh) { Close(fh); fh = 0L; }
	if(!mod && !(song.flags & FLAG_INSTRSATT) && !(loadres = LoadSongSamples()))
		Ilmoita("Loaded.");
	samplenum = 0;
	PaivitaSoittimennimi();
	loadingsong = FALSE;
	return(loadres);
}

static BOOL __regargs LoadOldBlocks(st)
BOOL st; /* SoundTracker ?? */
{
	long bytesleft = Seek(fh,0,OFFSET_END),lpt1 = 1024,lpt2 = 1028;
	BOOL error = FALSE;
	ULONG *convblk = AllocMem(1024 + 4,MEMF_PUBLIC|MEMF_CLEAR);
	if(!convblk) return(TRUE);	/* no memory */
	bytesleft = Seek(fh,bytesleft,OFFSET_BEGINNING) - bytesleft;
	for(;;) {
		if(blocks >= 100) return(TRUE); /* Help...no more!!!! */
		memset((void *)convblk,0,1028);
		if(st) {
			*convblk = 0L;
			if(lpt1 > bytesleft) lpt1 = bytesleft;
			if(Read(fh,(char *)(convblk + 1),lpt1)
				< lpt1) { error = TRUE; break; }
			if((bytesleft -= 1024) <= 0) break; /* 0 left */
		} else {
			if(lpt2 > bytesleft) lpt2 = bytesleft;
			if(Read(fh,(char *)convblk,lpt2) < lpt2)
				{ error = TRUE; break; }
			if((bytesleft -= 1028) <= 0) break;
		}
		ConvertTo200((UBYTE *)convblk,(UBYTE *)lohko[blocks],FALSE);
		if(AllocBlock((UWORD)++blocks,4,64)) {
			error = TRUE; /* Out of memory!!*/
			break;
		}
		TulostaLohkoJaSoitin();
	}
	ConvertTo200((UBYTE *)convblk,(UBYTE *)lohko[blocks],FALSE);
	blocks++;
	FreeMem((void *)convblk,1028);
	return(error);
}

BOOL diskerr(char *txt)
{
	char virheteksti[45];
	if(fh) { Close(fh); fh = 0L; }
	if(txt == NOERR) return(FALSE);
	DisplayBeep(screen);
	if(txt == DISKERR) {
		switch(IoErr()) {
			case 103: txt = "Insufficient free store"; break;
			case 202: txt = "Object in use"; break;
			case 203: txt = "Object already exists"; break;
			case 204: txt = "Directory not found"; break;
			case 205: txt = "Object not found"; break;
			case 210: txt = "Invalid filename"; break;
			case 212: txt = "Object not of required type"; break;
			case 213: txt = "Disk not validated"; break;
			case 214: txt = "Disk write-protected"; break;
			case 216: txt = "Directory not empty"; break;
			case 218: txt = "Device not mounted"; break;
			case 221: txt = "Disk full"; break;
			case 222: txt = "Protected from deletion"; break;
			case 223: txt = "Protected from writing"; break;
			case 224: txt = "Protected from reading"; break;
			case 225: txt = "Not a DOS disk"; break;
			case 226: txt = "No disk in drive"; break;
			default:  txt = "Failed.";
		}
		strcpy(virheteksti,"E: "); /* E: means Error: */
		strcat(virheteksti,txt);
		txt = virheteksti;
	}
	if(prevsn) { FreeMem(prevsn,63 * 40); prevsn = 0L; }
	Ilmoita(txt);
	return(TRUE);
}

static char * __regargs LoadIFFSample()
{
	Seek(fh,0,OFFSET_BEGINNING);
	Ilmoita("Loading IFF-sample...");
	if(sample[samplenum]) {
		FreeMem((void *)sample[samplenum],
			sample[samplenum]->length + sizeof(struct Soitin));
		sample[samplenum] = NULL;
	}
	buf = NULL; szBuf = NULL;
	(void)ReadSample((LONG)fh);
	if(fh) Close(fh);
	fh = 0L;
	if(!buf) return("Failed to load.");
	sample[samplenum] = (struct Soitin *)buf;
	sample[samplenum]->length = szBuf;
	switch(smusFrame.sampHdr.ctOctave) {
		case 5:	sample[samplenum]->type = IFF5OCT;	break;
		case 3:	sample[samplenum]->type = IFF3OCT;	break;
		default: sample[samplenum]->type = 0;
	}
	if(loadingsong); /* <- tiedot ovat jo kappaleessa */
	else if(smusFrame.sampHdr.repeatHiSamples) {
		song.sample[samplenum].rep = smusFrame.sampHdr.oneShotHiSamples / 2;
		song.sample[samplenum].replen = smusFrame.sampHdr.repeatHiSamples / 2;
		song.sample[samplenum].svol = 64; /* Täysillä vaan */
	} else {
		song.sample[samplenum].rep = 0;
		song.sample[samplenum].replen = 0;
		song.sample[samplenum].svol = 64;
	}
	return(NOERR);
}

void ConvertTo200(UBYTE *from,UBYTE *to,BOOL st24conv)
{
	extern UWORD periodit[];
	register UWORD testper,count;
	register UBYTE newnotenum = 0,instrG_V = 0;
	from += 4;	/* skip 4 bytes */
	to += BLKHDRSZ;
	for(count = 0; count < (64 * 4); count++) {
		testper = *((UWORD *)from);
		from += 2;
		newnotenum = instrG_V = 0;
		if(testper & 0x9000) { testper &= ~0x9000; instrG_V = 1; }
		if(testper)	while(testper < periodit[newnotenum++]);
		if(instrG_V) newnotenum |= 0x80;
		*to++ = newnotenum;
		if(st24conv) { /* convert some ST2.4's cmds to MED equivalents */
			newnotenum = *from++; /* reuse var "newnotenum" */
			if((newnotenum & 0x0f) == 0xd) { /* 0Dxx -> 0F00 */
				*to++ = (newnotenum & 0xf0) | 0xf;
				*to++ = 0;
				from++;
				continue; /* SoundTracker's Pattern Break */
			} else if((newnotenum & 0x0f) == 0xa) /*Axx->Dxx*/
				*to++ = (newnotenum & 0xf0) | 0xd;
			else if((newnotenum & 0x0f) == 0xe) { /*Exx->FF8/FF9 */
				*to++ = (newnotenum & 0xf0) | 0xf;
				if(*from++) *to++ = 0xF8; else *to++ = 0xF9;
				continue;
			}
			else *to++ = newnotenum;
		} else *to++ = *from++;
		*to++ = *from++;
	}
}

void DeleteSamplesNotUsed()
{ /* this is the routine which preserves the old samples */
	struct Soitin *oldsamples[63];
	UBYTE scnt,scnt2,*tstptr;
	for(scnt = 0; scnt < 63; scnt++) {
		oldsamples[scnt] = sample[scnt]; sample[scnt] = 0L;
	}
	if(!(song.flags & FLAG_INSTRSATT)) {
		for(scnt = 0; scnt < 63; scnt++) {
			if(song.sample[scnt].sname[0]) {
				for(scnt2 = 0; scnt2 < 63; scnt2++) {
					tstptr = prevsn + 40 * scnt2;
					if(*tstptr && !stricmp(song.
						sample[scnt].sname,tstptr)) {
						sample[scnt] = oldsamples[scnt2];
						oldsamples[scnt2] = 0L;
						*tstptr = '\0';
						break;
					}
				}
			}
		}
	}
	if(prevsn) { FreeMem(prevsn,63 * 40); prevsn = 0L; }
	for(scnt = 0; scnt < 63; scnt++)
		if(oldsamples[scnt]) FreeMem((void *)oldsamples[scnt],
			oldsamples[scnt]->length + sizeof(struct Soitin));
}

void clrxtoy(UBYTE x,UBYTE y)
{
	register UBYTE scnt;
	for(scnt = x; scnt < y; scnt++) {
		song.sample[scnt].sname[0] = 0;
		song.sample[scnt].rep = song.sample[scnt].replen = 0;
		song.sample[scnt].svol = song.sample[scnt].strans = 0;
	}
}

static char * __regargs Load112()
{
	register UBYTE scnt;
	Ilmoita("Loading MED1.12-song...");
	if(Read(fh,(char *)&old,sizeof(struct Kappale111)) <
		sizeof(struct Kappale111)) return(DISKERR);
	for(scnt = 0; scnt < 31; scnt++) {
		strcpy(song.sample[scnt].sname,old.oldsng.soitin[scnt+1]);
		song.sample[scnt].svol = old.oldsng.soittimenvoimakkuus[scnt+1];
		song.sample[scnt].rep = old.oldsng.stoisto[scnt+1] / 2;
		song.sample[scnt].replen = old.oldsng.stoistonpit[scnt+1] / 2;
		song.sample[scnt].strans = 0;
	}
	song.numblocks = blocks;
	memcpy((void *)song.playseq,(void *)old.oldsng.soittojarjestys,100);
	song.songlen = old.oldsng.kappaleen_pituus;
	song.deftempo = old.oldsng.tempo;
	song.flags = (UBYTE)(old.oldsng.liput);
	song.sliding = old.oldsng.vaihtoja;
	song.jumpmask = old.oldsng.hyppysoitin >> 1;
	LoadRGB4(vp,old.oldsng.rgb,4);
	DeleteSamplesNotUsed();
	clrxtoy(31,63);
	if(LoadOldBlocks(FALSE)) return(DISKERR);
	return(NOERR);
}

static char * __regargs LoadST()
{
	register UBYTE scnt;
	if(Read(fh,(char *)&old,sizeof(struct SoundTrackerKappale)) <
		sizeof(struct SoundTrackerKappale)) return(DISKERR);
	for(scnt = 0; scnt < 15; scnt++) {
		song.sample[scnt].svol = old.oldst.st_ins[scnt].sti_vol;
		song.sample[scnt].rep = old.oldst.st_ins[scnt].sti_repeat / 2;
		song.sample[scnt].replen = old.oldst.st_ins[scnt].sti_replen;
		song.sample[scnt].strans = 0;
		strcpy(song.sample[scnt].sname,old.oldst.st_ins[scnt].sti_nimi);
	}
	song.numblocks = blocks;
	song.deftempo = 6;
	song.songlen = old.oldst.st_kappaleen_pit;
	song.flags |= FLAG_STSLIDE;
	memcpy((void *)(song.playseq),(void *)(old.oldst.st_lohkojarj),128);
	DeleteSamplesNotUsed();
	clrxtoy(15,63);
	if(LoadOldBlocks(TRUE)) return(DISKERR);
	return(NOERR);
}

void StripPaths()
{
	UBYTE node[FNSIZE],scnt;
	if(!(gadget7[21].GadgetID & 0x1000)) return;
	for(scnt = 0; scnt < 63; scnt++) {
		stcgfn(node,song.sample[scnt].sname);
		strcpy(song.sample[scnt].sname,node);
	}
}

char *DoSave() /* request the save format and call save function */
{
static UWORD chip pic[] = { /* w = 128, h = 51 */
0x7fff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x3fff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x3fff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x3fff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x3fff,0x3171,0x91e2,0xa3e7,0x6a3c,0x666e,0xd8ff,0xfc00,
0x3ffe,0xf777,0x7bf6,0xafde,0xaafd,0xdaa4,0xadbf,0xfc00,
0x3fff,0x3373,0x7bf6,0x27e6,0x2a7c,0xda6a,0x8dff,0xfc00,
0x3fff,0xd777,0x7bf6,0xaffa,0xb6fd,0xdaae,0xadbf,0xfc00,
0x3ffe,0x3111,0x9bf6,0xa3c6,0xb63d,0xe6ae,0xadff,0xfc00,
0x3fff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x3bff,0xffff,0xffff,0xffef,0xffff,0xffff,0xffff,0xfc00,
0x3bff,0xffff,0xffff,0xffef,0xffff,0xffff,0xffff,0xfc00,
0x3bff,0xfe73,0x6cff,0xffee,0x6d9f,0xcdba,0x6e33,0xfc00,
0x3bff,0xfded,0x2bff,0xffed,0xe57d,0xba92,0xaeef,0xfc00,
0x3bff,0xfe6d,0x4a7f,0xffee,0x6948,0xd8aa,0x6e77,0xfc00,
0x3bff,0xffad,0x6b7f,0xffef,0xad6d,0xeaba,0xeefb,0xfc00,
0x3bff,0xfc73,0x6cff,0xffec,0x6d9f,0x9aba,0xe227,0xfc00,
0x3bff,0xffff,0xffff,0xffef,0xffff,0xffff,0xffff,0xfc00,
0x3800,0x0,0x0,0x20,0x0,0x0,0x0,0xfc00,
0x3bff,0xffff,0xffff,0xffef,0xffff,0xffff,0xffff,0xfc00,
0x3bff,0xffff,0xffff,0xffef,0xffff,0xffff,0xffff,0xfc00,
0x3bff,0xdd99,0xb5c7,0xffef,0xe47e,0xeccd,0xae3f,0xfc00,
0x3bff,0xc96a,0xb5df,0xffef,0xdefe,0x4b55,0xaeff,0xfc00,
0x3bff,0xd56a,0xb5cf,0xffef,0xe6e6,0xab55,0xae7f,0xfc00,
0x3bff,0xdd6a,0xb5df,0xffef,0xfafe,0xeb55,0xaeff,0xfc00,
0x3bff,0xdd99,0xcc47,0xffef,0xc6fe,0xecce,0x623f,0xfc00,
0x3bff,0xffff,0xffff,0xffef,0xffff,0xffff,0xffff,0xfc00,
0x3800,0x0,0x0,0x20,0x0,0x0,0x0,0xfc00,
0x3bff,0xffff,0x7fff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x3bff,0xffff,0x7fff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x3be6,0x7bdf,0x799e,0xe7ff,0xffff,0xffff,0xffff,0xfc00,
0x3bda,0xbb9f,0x76ae,0xfbff,0xffff,0xffff,0xffff,0xfc00,
0x3bda,0x7bdf,0x769e,0xf7ff,0xffff,0xffff,0xffff,0xfc00,
0x3bda,0xabdf,0x76aa,0xefff,0xffff,0xffff,0xffff,0xfc00,
0x3be6,0x778f,0x799d,0xe3ff,0xffff,0xffff,0xffff,0xfc00,
0x3bff,0xffff,0x7fff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x3800,0x1,0x0,0x3f,0xffff,0xffff,0xffff,0xfc00,
0x3fff,0xffff,0xffff,0xffff,0xff7f,0xffff,0xffff,0xfc00,
0x3bff,0xffff,0xffff,0xffff,0xff3f,0xffff,0xffff,0xfc00,
0x3bff,0xffff,0xffff,0xffff,0xff3f,0xffff,0xffff,0xfc00,
0x3bff,0xd99b,0x7fff,0xffff,0xff3f,0x9b6c,0x8bff,0xfc00,
0x3bff,0xd769,0x7fff,0xffff,0xff3f,0x752b,0xbbff,0xfc00,
0x3bff,0xd76a,0x7fff,0xffff,0xff3f,0x714b,0x9bff,0xfc00,
0x3bff,0xd76b,0x7fff,0xffff,0xff3f,0x756b,0xbbff,0xfc00,
0x3bff,0xd99b,0x7fff,0xffff,0xff3f,0x956c,0x88ff,0xfc00,
0x3bff,0xffff,0xffff,0xffff,0xff3f,0xffff,0xffff,0xfc00,
0x3800,0x0,0x7,0xffff,0xff00,0x0,0x1,0xfc00,
0x3fff,0xffff,0xffff,0xffff,0xff00,0x0,0x0,0xfc00,
0x3fff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc00,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400,
/*------ plane # 1: --------*/
0x8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf000,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf000,
0xffff,0x3171,0x91e2,0xa3e7,0x6a3c,0x666e,0xd8ff,0xf000,
0xfffe,0xf777,0x7bf6,0xafde,0xaafd,0xdaa4,0xadbf,0xf000,
0xffff,0x3373,0x7bf6,0x27e6,0x2a7c,0xda6a,0x8dff,0xf000,
0xffff,0xd777,0x7bf6,0xaffa,0xb6fd,0xdaae,0xadbf,0xf000,
0xfffe,0x3111,0x9bf6,0xa3c6,0xb63d,0xe6ae,0xadff,0xf000,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf000,
0xfc00,0x0,0x0,0x10,0x0,0x0,0x0,0x7000,
0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0x7000,
0xffff,0xfe73,0x6cff,0xffde,0x6d9f,0xcdba,0x6e33,0x7000,
0xffff,0xfded,0x2bff,0xffdd,0xe57d,0xba92,0xaeef,0x7000,
0xffff,0xfe6d,0x4a7f,0xffde,0x6948,0xd8aa,0x6e77,0x7000,
0xffff,0xffad,0x6b7f,0xffdf,0xad6d,0xeaba,0xeefb,0x7000,
0xffff,0xfc73,0x6cff,0xffdc,0x6d9f,0x9aba,0xe227,0x7000,
0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0x7000,
0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0x7000,
0xfc00,0x0,0x0,0x10,0x0,0x0,0x0,0x7000,
0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0x7000,
0xffff,0xdd99,0xb5c7,0xffdf,0xe47e,0xeccd,0xae3f,0x7000,
0xffff,0xc96a,0xb5df,0xffdf,0xdefe,0x4b55,0xaeff,0x7000,
0xffff,0xd56a,0xb5cf,0xffdf,0xe6e6,0xab55,0xae7f,0x7000,
0xffff,0xdd6a,0xb5df,0xffdf,0xfafe,0xeb55,0xaeff,0x7000,
0xffff,0xdd99,0xcc47,0xffdf,0xc6fe,0xecce,0x623f,0x7000,
0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0x7000,
0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0x7000,
0xfc00,0x0,0x8000,0x1f,0xffff,0xffff,0xffff,0xf000,
0xffff,0xfffe,0xffff,0xffdf,0xffff,0xffff,0xffff,0xf000,
0xffe6,0x7bfe,0xf99e,0xffdf,0xffff,0xffff,0xffff,0xf000,
0xffda,0xbbfe,0xf6ae,0xffdf,0xffff,0xffff,0xffff,0xf000,
0xffda,0x7bfe,0xf69e,0xffdf,0xffff,0xffff,0xffff,0xf000,
0xffda,0xabfe,0xf6aa,0xffdf,0xffff,0xffff,0xffff,0xf000,
0xffe6,0x77fe,0xf99d,0xffdf,0xffff,0xffff,0xffff,0xf000,
0xffff,0xfffe,0xffff,0xffdf,0xffff,0xffff,0xffff,0xf000,
0xffff,0xfffe,0xffff,0xffdf,0xffff,0xffff,0xffff,0xf000,
0xffff,0xffff,0xffff,0xffff,0xff80,0x0,0x0,0x7000,
0xfc00,0x0,0x3,0xffff,0xffc0,0x0,0x0,0x7000,
0xffff,0xffff,0xfffb,0xffff,0xffff,0xffff,0xfffe,0x7000,
0xffff,0xd99b,0x7ffb,0xffff,0xffff,0x9b6c,0x8bfe,0x7000,
0xffff,0xd769,0x7ffb,0xffff,0xffff,0x752b,0xbbfe,0x7000,
0xffff,0xd76a,0x7ffb,0xffff,0xffff,0x714b,0x9bfe,0x7000,
0xffff,0xd76b,0x7ffb,0xffff,0xffff,0x756b,0xbbfe,0x7000,
0xffff,0xd99b,0x7ffb,0xffff,0xffff,0x956c,0x88fe,0x7000,
0xffff,0xffff,0xfffb,0xffff,0xffff,0xffff,0xfffe,0x7000,
0xffff,0xffff,0xfffb,0xffff,0xffff,0xffff,0xfffe,0x7000,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7000,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf000,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf000,
0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf800 };
static BYTE icon = -1;
static struct Gadget far wgd[] = {
	{ &wgd[1],6,11,52,7,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,NULL,NULL,
	NULL,NULL,NULL,0,NULL },	/* song */
	{ &wgd[2],60,11,52,7,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,NULL,NULL,
	NULL,NULL,NULL,1,NULL },	/* song + samples */
	{ &wgd[3],6,20,52,7,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,NULL,NULL,
	NULL,NULL,NULL,2,NULL },	/* module */
	{ &wgd[4],6,29,25,7,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,NULL,NULL,
	NULL,NULL,NULL,3,NULL },	/* obj1 */
	{ &wgd[5],35,29,25,7,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,NULL,NULL,
	NULL,NULL,NULL,4,NULL },	/* obj2 */
	{ &wgd[6],60,20,52,7,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,NULL,NULL,
	NULL,NULL,NULL,5,NULL },	/* ST/NT-module */
	{ &wgd[7],6,39,39,7,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,NULL,NULL,
	NULL,NULL,NULL,6,NULL },	/* icon */
	{ NULL,74,39,37,7,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,NULL,NULL,
	NULL,NULL,NULL,7,NULL }	/* cancel */
};
static struct NewWindow far wnw = { 101,2,118,51,0,0,GADGETDOWN|RAWKEY,
	SMART_REFRESH|ACTIVATE|BORDERLESS|NOCAREREFRESH|RMBTRAP,&wgd[0],0L,0L,0L,0L,
	0,0,0,0,CUSTOMSCREEN };
	WORD sel = -1;
	static struct Image far img = { 0,0,118,51,2,pic,0x3,0x0,0L };
	struct IntuiMessage *m;
	struct Window *w; /* and now...let the code begin!!! */
	wnw.Screen = screen;
	if(!(w = OpenWindow(&wnw))) return(nomem);
	DrawImage(w->RPort,&img,0,0);
	SetDrMd(w->RPort,COMPLEMENT);
	w->RPort->Mask = 0x3;
	if(icon) RectFill(w->RPort,6,39,44,45);
	for(;;) {
		WaitPort(w->UserPort);
		m = (struct IntuiMessage *)GetMsg(w->UserPort);
		if(m->Class == RAWKEY && m->Code == 0x45) return(NOERR); /* esc */
		else if(m->Class == GADGETDOWN) {
			if(m->IAddress == (APTR)(&wgd[6])) {
				icon = !icon;
				RectFill(w->RPort,6,39,44,45);
			} else sel = ((struct Gadget *)(m->IAddress))->
					GadgetID;
		}
		ReplyMsg((struct Message *)m);
		if(sel != -1) break;
	}
	CloseWindow(w);
	switch(sel) {
		case 0: return(SaveSong(kappaleennimi,FALSE,icon));
		case 1: return(SaveSong(kappaleennimi,TRUE,icon));
		case 2: return(SaveMod(kappaleennimi));
		case 3: return(WriteObj(kappaleennimi,0));
		case 4: return(WriteObj(kappaleennimi,1));
		case 5: return(SaveSTMod(kappaleennimi));
	}
	return(NOERR);
}

char *DelFile()
{
	LONG succ;
	extern BPTR currdir;
	BPTR prevdir;
	char delname[FMSIZE];
	strcpy(delname,kappaleennimi);
	Ilmoita("Really want to delete??");
	if(!Continue()) return("All right!! Not deleted.");
	if(currdir) prevdir = CurrentDir(currdir);
	succ = DeleteFile(delname);
	if(succ) RemFilename(delname); /* delete from requester */
	strcat(delname,".info");	/* delete ".info"-file */
	DeleteFile(delname); /* don't care if it doesn't exist!! */
	if(currdir) CurrentDir(prevdir);
	if(!succ) return(DISKERR);
	Ilmoita("Deleted.");
	return(NOERR);
}

static void Change3to5() /* old MED vibrato, convert filter cmds */
{
	register UBYTE cmdb,*p2;
	UWORD blk;
	UBYTE *ptr,*end;
	for(blk = 0; blk < blocks; blk++) {
		ptr = lohko[blk]->music;
		end = ptr + 3 * (lohko[blk]->lines + 1) * lohko[blk]->numtracks;
		while(ptr < end) {
			p2 = ptr + 1;
			cmdb = *p2 & 0x0f;
			if(cmdb == 0x03) {
				*p2 &= 0xf0; *p2 |= 0x05;
			} else if(cmdb == 0x0E) {
				*p2 &= 0xf0; *p2++ |= 0x0F;
				if(p2) *p2 = 0xF8; else *p2 = 0xF9;
			}
			ptr += 3;
		}
	}
}
