summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/modplug/load_okt.cpp
authorllornkcor <llornkcor>2002-07-20 22:07:31 (UTC)
committer llornkcor <llornkcor>2002-07-20 22:07:31 (UTC)
commit2342d48be31847e7ead9d1cc682452e8f0122351 (patch) (unidiff)
tree8329bb94e9d429c905a0ef6b881cf1c0f775bf14 /core/multimedia/opieplayer/modplug/load_okt.cpp
parent0f24c1fb86d3bb58d8696358b824c0e01752b10d (diff)
downloadopie-2342d48be31847e7ead9d1cc682452e8f0122351.zip
opie-2342d48be31847e7ead9d1cc682452e8f0122351.tar.gz
opie-2342d48be31847e7ead9d1cc682452e8f0122351.tar.bz2
initial commit of modplugin
Diffstat (limited to 'core/multimedia/opieplayer/modplug/load_okt.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/modplug/load_okt.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/modplug/load_okt.cpp b/core/multimedia/opieplayer/modplug/load_okt.cpp
new file mode 100644
index 0000000..4030bbd
--- a/dev/null
+++ b/core/multimedia/opieplayer/modplug/load_okt.cpp
@@ -0,0 +1,200 @@
1/*
2 * This program is free software; you can redistribute it and modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the license or (at your
5 * option) any later version.
6 *
7 * Authors: Olivier Lapicque <olivierl@jps.net>,
8 * Adam Goode <adam@evdebs.org> (endian and char fixes for PPC)
9*/
10
11//////////////////////////////////////////////
12// Oktalyzer (OKT) module loader //
13//////////////////////////////////////////////
14#include "stdafx.h"
15#include "sndfile.h"
16
17//#pragma warning(disable:4244)
18
19typedef struct OKTFILEHEADER
20{
21 DWORD okta; // "OKTA"
22 DWORD song; // "SONG"
23 DWORD cmod; // "CMOD"
24 DWORD fixed8;
25 BYTE chnsetup[8];
26 DWORD samp; // "SAMP"
27 DWORD samplen;
28} Q_PACKED OKTFILEHEADER;
29
30
31typedef struct OKTSAMPLE
32{
33 CHAR name[20];
34 DWORD length;
35 WORD loopstart;
36 WORD looplen;
37 BYTE pad1;
38 BYTE volume;
39 BYTE pad2;
40 BYTE pad3;
41} Q_PACKED OKTSAMPLE;
42
43
44BOOL CSoundFile::ReadOKT(const BYTE *lpStream, DWORD dwMemLength)
45//---------------------------------------------------------------
46{
47 OKTFILEHEADER *pfh = (OKTFILEHEADER *)lpStream;
48 DWORD dwMemPos = sizeof(OKTFILEHEADER);
49 UINT nsamples = 0, npatterns = 0, norders = 0;
50
51 if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
52 if ((pfh->okta != 0x41544B4F) || (pfh->song != 0x474E4F53)
53 || (pfh->cmod != 0x444F4D43) || (pfh->chnsetup[0]) || (pfh->chnsetup[2])
54 || (pfh->chnsetup[4]) || (pfh->chnsetup[6]) || (pfh->fixed8 != 0x08000000)
55 || (pfh->samp != 0x504D4153)) return FALSE;
56 m_nType = MOD_TYPE_OKT;
57 m_nChannels = 4 + pfh->chnsetup[1] + pfh->chnsetup[3] + pfh->chnsetup[5] + pfh->chnsetup[7];
58 if (m_nChannels > MAX_CHANNELS) m_nChannels = MAX_CHANNELS;
59 nsamples = bswapBE32(pfh->samplen) >> 5;
60 m_nSamples = nsamples;
61 if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
62 // Reading samples
63 for (UINT smp=1; smp <= nsamples; smp++)
64 {
65 if (dwMemPos >= dwMemLength) return TRUE;
66 if (smp < MAX_SAMPLES)
67 {
68 OKTSAMPLE *psmp = (OKTSAMPLE *)(lpStream + dwMemPos);
69 MODINSTRUMENT *pins = &Ins[smp];
70
71 memcpy(m_szNames[smp], psmp->name, 20);
72 pins->uFlags = 0;
73 pins->nLength = bswapBE32(psmp->length) & ~1;
74 pins->nLoopStart = bswapBE16(psmp->loopstart);
75 pins->nLoopEnd = pins->nLoopStart + bswapBE16(psmp->looplen);
76 if (pins->nLoopStart + 2 < pins->nLoopEnd) pins->uFlags |= CHN_LOOP;
77 pins->nGlobalVol = 64;
78 pins->nVolume = psmp->volume << 2;
79 pins->nC4Speed = 8363;
80 }
81 dwMemPos += sizeof(OKTSAMPLE);
82 }
83 // SPEE
84 if (dwMemPos >= dwMemLength) return TRUE;
85 if (*((DWORD *)(lpStream + dwMemPos)) == 0x45455053)
86 {
87 m_nDefaultSpeed = lpStream[dwMemPos+9];
88 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
89 }
90 // SLEN
91 if (dwMemPos >= dwMemLength) return TRUE;
92 if (*((DWORD *)(lpStream + dwMemPos)) == 0x4E454C53)
93 {
94 npatterns = lpStream[dwMemPos+9];
95 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
96 }
97 // PLEN
98 if (dwMemPos >= dwMemLength) return TRUE;
99 if (*((DWORD *)(lpStream + dwMemPos)) == 0x4E454C50)
100 {
101 norders = lpStream[dwMemPos+9];
102 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
103 }
104 // PATT
105 if (dwMemPos >= dwMemLength) return TRUE;
106 if (*((DWORD *)(lpStream + dwMemPos)) == 0x54544150)
107 {
108 UINT orderlen = norders;
109 if (orderlen >= MAX_ORDERS) orderlen = MAX_ORDERS-1;
110 for (UINT i=0; i<orderlen; i++) Order[i] = lpStream[dwMemPos+10+i];
111 for (UINT j=orderlen; j>1; j--) { if (Order[j-1]) break; Order[j-1] = 0xFF; }
112 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
113 }
114 // PBOD
115 UINT npat = 0;
116 while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4250))
117 {
118 DWORD dwPos = dwMemPos + 10;
119 UINT rows = lpStream[dwMemPos+9];
120 if (!rows) rows = 64;
121 if (npat < MAX_PATTERNS)
122 {
123 if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) return TRUE;
124 MODCOMMAND *m = Patterns[npat];
125 PatternSize[npat] = rows;
126 UINT imax = m_nChannels*rows;
127 for (UINT i=0; i<imax; i++, m++, dwPos+=4)
128 {
129 if (dwPos+4 > dwMemLength) break;
130 const BYTE *p = lpStream+dwPos;
131 UINT note = p[0];
132 if (note)
133 {
134 m->note = note + 48;
135 m->instr = p[1] + 1;
136 }
137 UINT command = p[2];
138 UINT param = p[3];
139 m->param = param;
140 switch(command)
141 {
142 // 0: no effect
143 case 0:
144 break;
145 // 1: Portamento Up
146 case 1:
147 case 17:
148 case 30:
149 if (param) m->command = CMD_PORTAMENTOUP;
150 break;
151 // 2: Portamento Down
152 case 2:
153 case 13:
154 case 21:
155 if (param) m->command = CMD_PORTAMENTODOWN;
156 break;
157 // 10: Arpeggio
158 case 10:
159 case 11:
160 case 12:
161 m->command = CMD_ARPEGGIO;
162 break;
163 // 15: Filter
164 case 15:
165 m->command = CMD_MODCMDEX;
166 m->param = param & 0x0F;
167 break;
168 // 25: Position Jump
169 case 25:
170 m->command = CMD_POSITIONJUMP;
171 break;
172 // 28: Set Speed
173 case 28:
174 m->command = CMD_SPEED;
175 break;
176 // 31: Volume Control
177 case 31:
178 if (param <= 0x40) m->command = CMD_VOLUME; else
179 if (param <= 0x50) { m->command = CMD_VOLUMESLIDE; m->param &= 0x0F; if (!m->param) m->param = 0x0F; } else
180 if (param <= 0x60) { m->command = CMD_VOLUMESLIDE; m->param = (param & 0x0F) << 4; if (!m->param) m->param = 0xF0; } else
181 if (param <= 0x70) { m->command = CMD_MODCMDEX; m->param = 0xB0 | (param & 0x0F); if (!(param & 0x0F)) m->param = 0xBF; } else
182 if (param <= 0x80) { m->command = CMD_MODCMDEX; m->param = 0xA0 | (param & 0x0F); if (!(param & 0x0F)) m->param = 0xAF; }
183 break;
184 }
185 }
186 }
187 npat++;
188 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
189 }
190 // SBOD
191 UINT nsmp = 1;
192 while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4253))
193 {
194 if (nsmp < MAX_SAMPLES) ReadSample(&Ins[nsmp], RS_PCM8S, (LPSTR)(lpStream+dwMemPos+8), dwMemLength-dwMemPos-8);
195 dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
196 nsmp++;
197 }
198 return TRUE;
199}
200