public override bool Init() { mh1 = new FARHEADER1(); mh2 = new FARHEADER2(); pat = new FARNOTE[256 * 16 * 4]; for (int i = 0; i < pat.Length; i++) { pat[i] = new FARNOTE(); } return(true); }
public override bool Load(int curious) { int t, u, tracks = 0; SAMPLE q; FARSAMPLE s; byte[] smap = new byte[8]; /* try to read module header (first part) */ m_Reader.Read_bytes(mh1.id, 4); mh1.songname = m_Reader.Read_String(40); m_Reader.Read_bytes(mh1.blah, 3); mh1.headerlen = m_Reader.Read_Intel_ushort(); mh1.version = m_Reader.Read_byte(); m_Reader.Read_bytes(mh1.onoff, 16); m_Reader.Read_bytes(mh1.edit1, 9); mh1.speed = m_Reader.Read_byte(); m_Reader.Read_bytes(mh1.panning, 16); m_Reader.Read_bytes(mh1.edit2, 4); mh1.stlen = m_Reader.Read_Intel_ushort(); /* init modfile data */ m_Module.modtype = FAR_Version; m_Module.songname = mh1.songname; m_Module.numchn = 16; m_Module.initspeed = mh1.speed; m_Module.inittempo = 80; m_Module.reppos = 0; m_Module.flags |= SharpMikCommon.UF_PANNING; for (t = 0; t < 16; t++) { m_Module.panning[t] = (ushort)(mh1.panning[t] << 4); } /* read songtext into comment field */ if (mh1.stlen != 0) { if (!ReadLinedComment(mh1.stlen, 66)) { return(false); } } /* try to read module header (second part) */ m_Reader.Read_bytes(mh2.orders, 256); mh2.numpat = m_Reader.Read_byte(); mh2.snglen = m_Reader.Read_byte(); mh2.loopto = m_Reader.Read_byte(); m_Reader.Read_Intel_ushorts(mh2.patsiz, 256); m_Module.numpos = mh2.snglen; m_Module.positions = new ushort[m_Module.numpos]; for (t = 0; t < m_Module.numpos; t++) { if (mh2.orders[t] == 0xff) { break; } m_Module.positions[t] = mh2.orders[t]; } /* count number of patterns stored in file */ m_Module.numpat = 0; for (t = 0; t < 256; t++) { if (mh2.patsiz[t] != 0) { if ((t + 1) > m_Module.numpat) { m_Module.numpat = (ushort)(t + 1); } } } m_Module.numtrk = (ushort)(m_Module.numpat * m_Module.numchn); /* seek across eventual new data */ m_Reader.Seek(mh1.headerlen - (869 + mh1.stlen), SeekOrigin.Current); /* alloc track and pattern structures */ m_Module.AllocTracks(); m_Module.AllocPatterns(); for (t = 0; t < m_Module.numpat; t++) { byte rows = 0, tempo; for (int i = 0; i < pat.Length; i++) { pat[i].Clear(); } if (mh2.patsiz[t] != 0) { rows = m_Reader.Read_byte(); tempo = m_Reader.Read_byte(); /* file often allocates 64 rows even if there are less in pattern */ if (mh2.patsiz[t] < 2 + (rows * 16 * 4)) { m_LoadError = MMERR_LOADING_PATTERN; return(false); } int place = 0; for (u = (mh2.patsiz[t] - 2) / 4; u != 0; u--) { FARNOTE crow = pat[place]; crow.note = m_Reader.Read_byte(); crow.ins = m_Reader.Read_byte(); crow.vol = m_Reader.Read_byte(); crow.eff = m_Reader.Read_byte(); place++; } if (m_Reader.isEOF()) { m_LoadError = MMERR_LOADING_PATTERN; return(false); } m_Module.pattrows[t] = rows; place = 0; for (u = 16; u != 0; u--) { if ((m_Module.tracks[tracks++] = FAR_ConvertTrack(pat, rows, place)) == null) { m_LoadError = MMERR_LOADING_PATTERN; return(false); } place++; } } else { tracks += 16; } } /* read sample map */ m_Reader.Read_bytes(smap, 8); /* count number of samples used */ m_Module.numins = 0; for (t = 0; t < 64; t++) { if ((smap[t >> 3] & (1 << (t & 7))) != 0) { m_Module.numins = (ushort)(t + 1); } } m_Module.numsmp = m_Module.numins; /* alloc sample structs */ m_Module.AllocSamples(); for (t = 0; t < m_Module.numsmp; t++) { s = new FARSAMPLE(); q = m_Module.samples[t]; q.speed = 8363; q.flags = SharpMikCommon.SF_SIGNED; if ((smap[t >> 3] & (1 << (t & 7))) != 0) { s.samplename = m_Reader.Read_String(32); s.length = m_Reader.Read_Intel_uint(); s.finetune = m_Reader.Read_byte(); s.volume = m_Reader.Read_byte(); s.reppos = m_Reader.Read_Intel_uint(); s.repend = m_Reader.Read_Intel_uint(); s.type = m_Reader.Read_byte(); s.loop = m_Reader.Read_byte(); q.samplename = s.samplename; q.length = s.length; q.loopstart = s.reppos; q.loopend = s.repend; q.volume = (byte)(s.volume << 2); if ((s.type & 1) != 0) { q.flags |= SharpMikCommon.SF_16BITS; } if ((s.loop & 8) != 0) { q.flags |= SharpMikCommon.SF_LOOP; } q.seekpos = (uint)m_Reader.Tell(); m_Reader.Seek((int)q.length, SeekOrigin.Current); } else { q.samplename = null; } } return(true); }
byte[] FAR_ConvertTrack(FARNOTE[] notes, int rows, int place) { int t, vibdepth = 1; UniReset(); for (t = 0; t < rows; t++) { FARNOTE n = notes[place]; if (n.note != 0) { UniInstrument(n.ins); UniNote(n.note + 3 * SharpMikCommon.Octave - 1); } if ((n.vol & 0xf) != 0) { UniPTEffect(0xc, (n.vol & 0xf) << 2); } if (n.eff != 0) { switch (n.eff >> 4) { case 0x3: /* porta to note */ UniPTEffect(0x3, (n.eff & 0xf) << 4); break; case 0x4: /* retrigger */ UniPTEffect(0x0e, 0x90 | (n.eff & 0x0f)); break; case 0x5: /* set vibrato depth */ vibdepth = n.eff & 0xf; break; case 0x6: /* vibrato */ UniPTEffect(0x4, ((n.eff & 0xf) << 4) | vibdepth); break; case 0x7: /* volume slide up */ UniPTEffect(0xa, (n.eff & 0xf) << 4); break; case 0x8: /* volume slide down */ UniPTEffect(0xa, n.eff & 0xf); break; case 0xb: /* panning */ UniPTEffect(0xe, 0x80 | (n.eff & 0xf)); break; case 0xf: /* set speed */ UniPTEffect(0xf, n.eff & 0xf); break; /* others not yet implemented */ default: break; } } UniNewline(); place += 16; } return(UniDup()); }