00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00013 #include "stdafx.h"
00014 #include "sndfile.h"
00015
00016
00017
00018 #define FARFILEMAGIC 0xFE524146 // "FAR"
00019
00020 #pragma pack(1)
00021
00022 typedef struct FARHEADER1
00023 {
00024 DWORD id;
00025 CHAR songname[40];
00026 CHAR magic2[3];
00027 WORD headerlen;
00028 BYTE version;
00029 BYTE onoff[16];
00030 BYTE edit1[9];
00031 BYTE speed;
00032 BYTE panning[16];
00033 BYTE edit2[4];
00034 WORD stlen;
00035 } Q_PACKED FARHEADER1;
00036
00037 typedef struct FARHEADER2
00038 {
00039 BYTE orders[256];
00040 BYTE numpat;
00041 BYTE snglen;
00042 BYTE loopto;
00043 WORD patsiz[256];
00044 } Q_PACKED FARHEADER2;
00045
00046 typedef struct FARSAMPLE
00047 {
00048 CHAR samplename[32];
00049 DWORD length;
00050 BYTE finetune;
00051 BYTE volume;
00052 DWORD reppos;
00053 DWORD repend;
00054 BYTE type;
00055 BYTE loop;
00056 } Q_PACKED FARSAMPLE;
00057
00058 #pragma pack()
00059
00060
00061 BOOL CSoundFile::ReadFAR(const BYTE *lpStream, DWORD dwMemLength)
00062
00063 {
00064 FARHEADER1 *pmh1 = (FARHEADER1 *)lpStream;
00065 FARHEADER2 *pmh2;
00066 DWORD dwMemPos = sizeof(FARHEADER1);
00067 UINT headerlen;
00068 BYTE samplemap[8];
00069
00070 if ((!lpStream) || (dwMemLength < 1024) || (pmh1->id != FARFILEMAGIC)
00071 || (pmh1->magic2[0] != 13) || (pmh1->magic2[1] != 10) || (pmh1->magic2[2] != 26)) return FALSE;
00072 headerlen = pmh1->headerlen;
00073 if ((headerlen >= dwMemLength) || (dwMemPos + pmh1->stlen + sizeof(FARHEADER2) >= dwMemLength)) return FALSE;
00074
00075 m_nType = MOD_TYPE_FAR;
00076 m_nChannels = 16;
00077 m_nInstruments = 0;
00078 m_nSamples = 0;
00079 m_nSongPreAmp = 0x20;
00080 m_nDefaultSpeed = pmh1->speed;
00081 m_nDefaultTempo = 80;
00082 m_nDefaultGlobalVolume = 256;
00083
00084 memcpy(m_szNames[0], pmh1->songname, 32);
00085
00086 for (UINT nchpan=0; nchpan<16; nchpan++)
00087 {
00088 ChnSettings[nchpan].dwFlags = 0;
00089 ChnSettings[nchpan].nPan = ((pmh1->panning[nchpan] & 0x0F) << 4) + 8;
00090 ChnSettings[nchpan].nVolume = 64;
00091 }
00092
00093 if (pmh1->stlen)
00094 {
00095 UINT szLen = pmh1->stlen;
00096 if (szLen > dwMemLength - dwMemPos) szLen = dwMemLength - dwMemPos;
00097 if ((m_lpszSongComments = new char[szLen + 1]) != NULL)
00098 {
00099 memcpy(m_lpszSongComments, lpStream+dwMemPos, szLen);
00100 m_lpszSongComments[szLen] = 0;
00101 }
00102 dwMemPos += pmh1->stlen;
00103 }
00104
00105 pmh2 = (FARHEADER2 *)(lpStream + dwMemPos);
00106 dwMemPos += sizeof(FARHEADER2);
00107 if (dwMemPos >= dwMemLength) return TRUE;
00108 for (UINT iorder=0; iorder<MAX_ORDERS; iorder++)
00109 {
00110 Order[iorder] = (iorder <= pmh2->snglen) ? pmh2->orders[iorder] : 0xFF;
00111 }
00112 m_nRestartPos = pmh2->loopto;
00113
00114 dwMemPos += headerlen - (869 + pmh1->stlen);
00115 if (dwMemPos >= dwMemLength) return TRUE;
00116
00117 WORD *patsiz = (WORD *)pmh2->patsiz;
00118 for (UINT ipat=0; ipat<256; ipat++) if (patsiz[ipat])
00119 {
00120 UINT patlen = patsiz[ipat];
00121 if ((ipat >= MAX_PATTERNS) || (patsiz[ipat] < 2))
00122 {
00123 dwMemPos += patlen;
00124 continue;
00125 }
00126 if (dwMemPos + patlen >= dwMemLength) return TRUE;
00127 UINT rows = (patlen - 2) >> 6;
00128 if (!rows)
00129 {
00130 dwMemPos += patlen;
00131 continue;
00132 }
00133 if (rows > 256) rows = 256;
00134 if (rows < 16) rows = 16;
00135 PatternSize[ipat] = rows;
00136 if ((Patterns[ipat] = AllocatePattern(rows, m_nChannels)) == NULL) return TRUE;
00137 MODCOMMAND *m = Patterns[ipat];
00138 UINT patbrk = lpStream[dwMemPos];
00139 const BYTE *p = lpStream + dwMemPos + 2;
00140 UINT max = rows*16*4;
00141 if (max > patlen-2) max = patlen-2;
00142 for (UINT len=0; len<max; len += 4, m++)
00143 {
00144 BYTE note = p[len];
00145 BYTE ins = p[len+1];
00146 BYTE vol = p[len+2];
00147 BYTE eff = p[len+3];
00148 if (note)
00149 {
00150 m->instr = ins + 1;
00151 m->note = note + 36;
00152 }
00153 if (vol & 0x0F)
00154 {
00155 m->volcmd = VOLCMD_VOLUME;
00156 m->vol = (vol & 0x0F) << 2;
00157 if (m->vol <= 4) m->vol = 0;
00158 }
00159 switch(eff & 0xF0)
00160 {
00161
00162 case 0x10:
00163 m->command = CMD_PORTAMENTOUP;
00164 m->param = eff & 0x0F;
00165 break;
00166
00167 case 0x20:
00168 m->command = CMD_PORTAMENTODOWN;
00169 m->param = eff & 0x0F;
00170 break;
00171
00172 case 0x30:
00173 m->command = CMD_TONEPORTAMENTO;
00174 m->param = (eff & 0x0F) << 2;
00175 break;
00176
00177 case 0x40:
00178 m->command = CMD_RETRIG;
00179 m->param = 6 / (1+(eff&0x0F)) + 1;
00180 break;
00181
00182 case 0x50:
00183 m->command = CMD_VIBRATO;
00184 m->param = (eff & 0x0F);
00185 break;
00186
00187 case 0x60:
00188 m->command = CMD_VIBRATO;
00189 m->param = (eff & 0x0F) << 4;
00190 break;
00191
00192 case 0x70:
00193 m->command = CMD_VOLUMESLIDE;
00194 m->param = (eff & 0x0F) << 4;
00195 break;
00196
00197 case 0x80:
00198 m->command = CMD_VOLUMESLIDE;
00199 m->param = (eff & 0x0F);
00200 break;
00201
00202 case 0xA0:
00203 m->volcmd = VOLCMD_VOLUME;
00204 m->vol = ((eff & 0x0F) << 2) + 4;
00205 break;
00206
00207 case 0xB0:
00208 m->command = CMD_PANNING8;
00209 m->param = (eff & 0x0F) << 4;
00210 break;
00211
00212 case 0xF0:
00213 m->command = CMD_SPEED;
00214 m->param = eff & 0x0F;
00215 break;
00216 default:
00217 if ((patbrk) && (patbrk+1 == (len >> 6)) && (patbrk+1 != rows-1))
00218 {
00219 m->command = CMD_PATTERNBREAK;
00220 patbrk = 0;
00221 }
00222 }
00223 }
00224 dwMemPos += patlen;
00225 }
00226
00227 if (dwMemPos + 8 >= dwMemLength) return TRUE;
00228 memcpy(samplemap, lpStream+dwMemPos, 8);
00229 dwMemPos += 8;
00230 MODINSTRUMENT *pins = &Ins[1];
00231 for (UINT ismp=0; ismp<64; ismp++, pins++) if (samplemap[ismp >> 3] & (1 << (ismp & 7)))
00232 {
00233 if (dwMemPos + sizeof(FARSAMPLE) > dwMemLength) return TRUE;
00234 FARSAMPLE *pfs = (FARSAMPLE *)(lpStream + dwMemPos);
00235 dwMemPos += sizeof(FARSAMPLE);
00236 m_nSamples = ismp + 1;
00237 memcpy(m_szNames[ismp+1], pfs->samplename, 32);
00238 pins->nLength = pfs->length;
00239 pins->nLoopStart = pfs->reppos;
00240 pins->nLoopEnd = pfs->repend;
00241 pins->nFineTune = 0;
00242 pins->nC4Speed = 8363*2;
00243 pins->nGlobalVol = 64;
00244 pins->nVolume = pfs->volume << 4;
00245 pins->uFlags = 0;
00246 if ((pins->nLength > 3) && (dwMemPos + 4 < dwMemLength))
00247 {
00248 if (pfs->type & 1)
00249 {
00250 pins->uFlags |= CHN_16BIT;
00251 pins->nLength >>= 1;
00252 pins->nLoopStart >>= 1;
00253 pins->nLoopEnd >>= 1;
00254 }
00255 if ((pfs->loop & 8) && (pins->nLoopEnd > 4)) pins->uFlags |= CHN_LOOP;
00256 ReadSample(pins, (pins->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S,
00257 (LPSTR)(lpStream+dwMemPos), dwMemLength - dwMemPos);
00258 }
00259 dwMemPos += pfs->length;
00260 }
00261 return TRUE;
00262 }
00263