00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00014 #include "stdafx.h"
00015 #include "sndfile.h"
00016
00017
00018
00019 typedef struct OKTFILEHEADER
00020 {
00021 DWORD okta;
00022 DWORD song;
00023 DWORD cmod;
00024 DWORD fixed8;
00025 BYTE chnsetup[8];
00026 DWORD samp;
00027 DWORD samplen;
00028 } Q_PACKED OKTFILEHEADER;
00029
00030
00031 typedef struct OKTSAMPLE
00032 {
00033 CHAR name[20];
00034 DWORD length;
00035 WORD loopstart;
00036 WORD looplen;
00037 BYTE pad1;
00038 BYTE volume;
00039 BYTE pad2;
00040 BYTE pad3;
00041 } Q_PACKED OKTSAMPLE;
00042
00043
00044 BOOL CSoundFile::ReadOKT(const BYTE *lpStream, DWORD dwMemLength)
00045
00046 {
00047 OKTFILEHEADER *pfh = (OKTFILEHEADER *)lpStream;
00048 DWORD dwMemPos = sizeof(OKTFILEHEADER);
00049 UINT nsamples = 0, npatterns = 0, norders = 0;
00050
00051 if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
00052 if ((pfh->okta != 0x41544B4F) || (pfh->song != 0x474E4F53)
00053 || (pfh->cmod != 0x444F4D43) || (pfh->chnsetup[0]) || (pfh->chnsetup[2])
00054 || (pfh->chnsetup[4]) || (pfh->chnsetup[6]) || (pfh->fixed8 != 0x08000000)
00055 || (pfh->samp != 0x504D4153)) return FALSE;
00056 m_nType = MOD_TYPE_OKT;
00057 m_nChannels = 4 + pfh->chnsetup[1] + pfh->chnsetup[3] + pfh->chnsetup[5] + pfh->chnsetup[7];
00058 if (m_nChannels > MAX_CHANNELS) m_nChannels = MAX_CHANNELS;
00059 nsamples = bswapBE32(pfh->samplen) >> 5;
00060 m_nSamples = nsamples;
00061 if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
00062
00063 for (UINT smp=1; smp <= nsamples; smp++)
00064 {
00065 if (dwMemPos >= dwMemLength) return TRUE;
00066 if (smp < MAX_SAMPLES)
00067 {
00068 OKTSAMPLE *psmp = (OKTSAMPLE *)(lpStream + dwMemPos);
00069 MODINSTRUMENT *pins = &Ins[smp];
00070
00071 memcpy(m_szNames[smp], psmp->name, 20);
00072 pins->uFlags = 0;
00073 pins->nLength = bswapBE32(psmp->length) & ~1;
00074 pins->nLoopStart = bswapBE16(psmp->loopstart);
00075 pins->nLoopEnd = pins->nLoopStart + bswapBE16(psmp->looplen);
00076 if (pins->nLoopStart + 2 < pins->nLoopEnd) pins->uFlags |= CHN_LOOP;
00077 pins->nGlobalVol = 64;
00078 pins->nVolume = psmp->volume << 2;
00079 pins->nC4Speed = 8363;
00080 }
00081 dwMemPos += sizeof(OKTSAMPLE);
00082 }
00083
00084 if (dwMemPos >= dwMemLength) return TRUE;
00085 if (*((DWORD *)(lpStream + dwMemPos)) == 0x45455053)
00086 {
00087 m_nDefaultSpeed = lpStream[dwMemPos+9];
00088 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
00089 }
00090
00091 if (dwMemPos >= dwMemLength) return TRUE;
00092 if (*((DWORD *)(lpStream + dwMemPos)) == 0x4E454C53)
00093 {
00094 npatterns = lpStream[dwMemPos+9];
00095 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
00096 }
00097
00098 if (dwMemPos >= dwMemLength) return TRUE;
00099 if (*((DWORD *)(lpStream + dwMemPos)) == 0x4E454C50)
00100 {
00101 norders = lpStream[dwMemPos+9];
00102 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
00103 }
00104
00105 if (dwMemPos >= dwMemLength) return TRUE;
00106 if (*((DWORD *)(lpStream + dwMemPos)) == 0x54544150)
00107 {
00108 UINT orderlen = norders;
00109 if (orderlen >= MAX_ORDERS) orderlen = MAX_ORDERS-1;
00110 for (UINT i=0; i<orderlen; i++) Order[i] = lpStream[dwMemPos+10+i];
00111 for (UINT j=orderlen; j>1; j--) { if (Order[j-1]) break; Order[j-1] = 0xFF; }
00112 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
00113 }
00114
00115 UINT npat = 0;
00116 while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4250))
00117 {
00118 DWORD dwPos = dwMemPos + 10;
00119 UINT rows = lpStream[dwMemPos+9];
00120 if (!rows) rows = 64;
00121 if (npat < MAX_PATTERNS)
00122 {
00123 if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) return TRUE;
00124 MODCOMMAND *m = Patterns[npat];
00125 PatternSize[npat] = rows;
00126 UINT imax = m_nChannels*rows;
00127 for (UINT i=0; i<imax; i++, m++, dwPos+=4)
00128 {
00129 if (dwPos+4 > dwMemLength) break;
00130 const BYTE *p = lpStream+dwPos;
00131 UINT note = p[0];
00132 if (note)
00133 {
00134 m->note = note + 48;
00135 m->instr = p[1] + 1;
00136 }
00137 UINT command = p[2];
00138 UINT param = p[3];
00139 m->param = param;
00140 switch(command)
00141 {
00142
00143 case 0:
00144 break;
00145
00146 case 1:
00147 case 17:
00148 case 30:
00149 if (param) m->command = CMD_PORTAMENTOUP;
00150 break;
00151
00152 case 2:
00153 case 13:
00154 case 21:
00155 if (param) m->command = CMD_PORTAMENTODOWN;
00156 break;
00157
00158 case 10:
00159 case 11:
00160 case 12:
00161 m->command = CMD_ARPEGGIO;
00162 break;
00163
00164 case 15:
00165 m->command = CMD_MODCMDEX;
00166 m->param = param & 0x0F;
00167 break;
00168
00169 case 25:
00170 m->command = CMD_POSITIONJUMP;
00171 break;
00172
00173 case 28:
00174 m->command = CMD_SPEED;
00175 break;
00176
00177 case 31:
00178 if (param <= 0x40) m->command = CMD_VOLUME; else
00179 if (param <= 0x50) { m->command = CMD_VOLUMESLIDE; m->param &= 0x0F; if (!m->param) m->param = 0x0F; } else
00180 if (param <= 0x60) { m->command = CMD_VOLUMESLIDE; m->param = (param & 0x0F) << 4; if (!m->param) m->param = 0xF0; } else
00181 if (param <= 0x70) { m->command = CMD_MODCMDEX; m->param = 0xB0 | (param & 0x0F); if (!(param & 0x0F)) m->param = 0xBF; } else
00182 if (param <= 0x80) { m->command = CMD_MODCMDEX; m->param = 0xA0 | (param & 0x0F); if (!(param & 0x0F)) m->param = 0xAF; }
00183 break;
00184 }
00185 }
00186 }
00187 npat++;
00188 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
00189 }
00190
00191 UINT nsmp = 1;
00192 while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4253))
00193 {
00194 if (nsmp < MAX_SAMPLES) ReadSample(&Ins[nsmp], RS_PCM8S, (LPSTR)(lpStream+dwMemPos+8), dwMemLength-dwMemPos-8);
00195 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
00196 nsmp++;
00197 }
00198 return TRUE;
00199 }
00200